summaryrefslogtreecommitdiff
path: root/pcbnew
diff options
context:
space:
mode:
Diffstat (limited to 'pcbnew')
-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
672 files changed, 341228 insertions, 0 deletions
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;
+}