Use GetType() for pin alternate electrical type queries
When a pin has an alternate function selected, GetType() correctly
returns the alternate's type. However, GetCanonicalElectricalTypeName(),
GetElectricalTypeName(), and PlotPinType() were accessing m_type directly,
bypassing the alternate type lookup. This caused netlist exports to show
the wrong pin type (e.g., "no_connect" instead of "power_in") and the
NC symbol to be drawn incorrectly when alternates changed the pin type.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/22286
(cherry picked from commit 25430cfbb8)
This commit is contained in:
+5
-15
@@ -308,25 +308,15 @@ void SCH_PIN::SetType( ELECTRICAL_PINTYPE aType )
|
||||
|
||||
wxString SCH_PIN::GetCanonicalElectricalTypeName() const
|
||||
{
|
||||
if( m_type != ELECTRICAL_PINTYPE::PT_INHERIT )
|
||||
return ::GetCanonicalElectricalTypeName( m_type );
|
||||
|
||||
if( !m_libPin )
|
||||
return ::GetCanonicalElectricalTypeName( ELECTRICAL_PINTYPE::PT_UNSPECIFIED );
|
||||
|
||||
return m_libPin->GetCanonicalElectricalTypeName();
|
||||
// Use GetType() which correctly handles alternates
|
||||
return ::GetCanonicalElectricalTypeName( GetType() );
|
||||
}
|
||||
|
||||
|
||||
wxString SCH_PIN::GetElectricalTypeName() const
|
||||
{
|
||||
if( m_type != ELECTRICAL_PINTYPE::PT_INHERIT )
|
||||
return ElectricalPinTypeGetText( m_type );
|
||||
|
||||
if( !m_libPin )
|
||||
return ElectricalPinTypeGetText( ELECTRICAL_PINTYPE::PT_UNSPECIFIED );
|
||||
|
||||
return m_libPin->GetElectricalTypeName();
|
||||
// Use GetType() which correctly handles alternates
|
||||
return ElectricalPinTypeGetText( GetType() );
|
||||
}
|
||||
|
||||
|
||||
@@ -1186,7 +1176,7 @@ void SCH_PIN::PlotPinType( PLOTTER *aPlotter, const VECTOR2I &aPosition,
|
||||
y1 + ( MapY1 + MapX1 ) * deco_size ) );
|
||||
}
|
||||
|
||||
if( m_type == ELECTRICAL_PINTYPE::PT_NC ) // Draw a N.C. symbol
|
||||
if( GetType() == ELECTRICAL_PINTYPE::PT_NC ) // Draw a N.C. symbol
|
||||
{
|
||||
const int deco_size = TARGET_PIN_RADIUS;
|
||||
const int ex1 = aPosition.x;
|
||||
|
||||
@@ -0,0 +1,660 @@
|
||||
{
|
||||
"board": {
|
||||
"3dviewports": [],
|
||||
"design_settings": {
|
||||
"defaults": {
|
||||
"apply_defaults_to_fp_barcodes": false,
|
||||
"apply_defaults_to_fp_dimensions": false,
|
||||
"apply_defaults_to_fp_fields": false,
|
||||
"apply_defaults_to_fp_shapes": false,
|
||||
"apply_defaults_to_fp_text": false,
|
||||
"board_outline_line_width": 0.05,
|
||||
"copper_line_width": 0.2,
|
||||
"copper_text_italic": false,
|
||||
"copper_text_size_h": 1.5,
|
||||
"copper_text_size_v": 1.5,
|
||||
"copper_text_thickness": 0.3,
|
||||
"copper_text_upright": false,
|
||||
"courtyard_line_width": 0.05,
|
||||
"dimension_precision": 4,
|
||||
"dimension_units": 3,
|
||||
"dimensions": {
|
||||
"arrow_length": 1270000,
|
||||
"extension_offset": 500000,
|
||||
"keep_text_aligned": true,
|
||||
"suppress_zeroes": true,
|
||||
"text_position": 0,
|
||||
"units_format": 0
|
||||
},
|
||||
"fab_line_width": 0.1,
|
||||
"fab_text_italic": false,
|
||||
"fab_text_size_h": 1.0,
|
||||
"fab_text_size_v": 1.0,
|
||||
"fab_text_thickness": 0.15,
|
||||
"fab_text_upright": false,
|
||||
"other_line_width": 0.1,
|
||||
"other_text_italic": false,
|
||||
"other_text_size_h": 1.0,
|
||||
"other_text_size_v": 1.0,
|
||||
"other_text_thickness": 0.15,
|
||||
"other_text_upright": false,
|
||||
"pads": {
|
||||
"drill": 0.8,
|
||||
"height": 1.27,
|
||||
"width": 2.54
|
||||
},
|
||||
"silk_line_width": 0.1,
|
||||
"silk_text_italic": false,
|
||||
"silk_text_size_h": 1.0,
|
||||
"silk_text_size_v": 1.0,
|
||||
"silk_text_thickness": 0.1,
|
||||
"silk_text_upright": false,
|
||||
"zones": {
|
||||
"min_clearance": 0.5
|
||||
}
|
||||
},
|
||||
"diff_pair_dimensions": [],
|
||||
"drc_exclusions": [],
|
||||
"meta": {
|
||||
"version": 2
|
||||
},
|
||||
"rule_severities": {
|
||||
"annular_width": "error",
|
||||
"clearance": "error",
|
||||
"connection_width": "warning",
|
||||
"copper_edge_clearance": "error",
|
||||
"copper_sliver": "warning",
|
||||
"courtyards_overlap": "error",
|
||||
"creepage": "error",
|
||||
"diff_pair_gap_out_of_range": "error",
|
||||
"diff_pair_uncoupled_length_too_long": "error",
|
||||
"drill_out_of_range": "error",
|
||||
"duplicate_footprints": "warning",
|
||||
"extra_footprint": "warning",
|
||||
"footprint": "error",
|
||||
"footprint_filters_mismatch": "ignore",
|
||||
"footprint_symbol_field_mismatch": "warning",
|
||||
"footprint_symbol_mismatch": "warning",
|
||||
"footprint_type_mismatch": "ignore",
|
||||
"hole_clearance": "error",
|
||||
"hole_to_hole": "warning",
|
||||
"holes_co_located": "warning",
|
||||
"invalid_outline": "error",
|
||||
"isolated_copper": "warning",
|
||||
"item_on_disabled_layer": "error",
|
||||
"items_not_allowed": "error",
|
||||
"length_out_of_range": "error",
|
||||
"lib_footprint_issues": "warning",
|
||||
"lib_footprint_mismatch": "warning",
|
||||
"malformed_courtyard": "error",
|
||||
"microvia_drill_out_of_range": "error",
|
||||
"mirrored_text_on_front_layer": "warning",
|
||||
"missing_courtyard": "ignore",
|
||||
"missing_footprint": "warning",
|
||||
"missing_tuning_profile": "warning",
|
||||
"net_conflict": "warning",
|
||||
"nonmirrored_text_on_back_layer": "warning",
|
||||
"npth_inside_courtyard": "ignore",
|
||||
"padstack": "warning",
|
||||
"pth_inside_courtyard": "ignore",
|
||||
"shorting_items": "error",
|
||||
"silk_edge_clearance": "warning",
|
||||
"silk_over_copper": "warning",
|
||||
"silk_overlap": "warning",
|
||||
"skew_out_of_range": "error",
|
||||
"solder_mask_bridge": "error",
|
||||
"starved_thermal": "error",
|
||||
"text_height": "warning",
|
||||
"text_on_edge_cuts": "error",
|
||||
"text_thickness": "warning",
|
||||
"through_hole_pad_without_hole": "error",
|
||||
"too_many_vias": "error",
|
||||
"track_angle": "error",
|
||||
"track_dangling": "warning",
|
||||
"track_on_post_machined_layer": "error",
|
||||
"track_segment_length": "error",
|
||||
"track_width": "error",
|
||||
"tracks_crossing": "error",
|
||||
"tuning_profile_track_geometries": "ignore",
|
||||
"unconnected_items": "error",
|
||||
"unresolved_variable": "error",
|
||||
"via_dangling": "warning",
|
||||
"zones_intersect": "error"
|
||||
},
|
||||
"rules": {
|
||||
"max_error": 0.005,
|
||||
"min_clearance": 0.0,
|
||||
"min_connection": 0.0,
|
||||
"min_copper_edge_clearance": 0.5,
|
||||
"min_groove_width": 0.0,
|
||||
"min_hole_clearance": 0.25,
|
||||
"min_hole_to_hole": 0.25,
|
||||
"min_microvia_diameter": 0.2,
|
||||
"min_microvia_drill": 0.1,
|
||||
"min_resolved_spokes": 2,
|
||||
"min_silk_clearance": 0.0,
|
||||
"min_text_height": 0.8,
|
||||
"min_text_thickness": 0.08,
|
||||
"min_through_hole_diameter": 0.3,
|
||||
"min_track_width": 0.0,
|
||||
"min_via_annular_width": 0.1,
|
||||
"min_via_diameter": 0.5,
|
||||
"solder_mask_to_copper_clearance": 0.0,
|
||||
"use_height_for_length_calcs": true
|
||||
},
|
||||
"teardrop_options": [
|
||||
{
|
||||
"td_onpthpad": true,
|
||||
"td_onroundshapesonly": false,
|
||||
"td_onsmdpad": true,
|
||||
"td_ontrackend": false,
|
||||
"td_onvia": true
|
||||
}
|
||||
],
|
||||
"teardrop_parameters": [
|
||||
{
|
||||
"td_allow_use_two_tracks": true,
|
||||
"td_curve_segcount": 0,
|
||||
"td_height_ratio": 1.0,
|
||||
"td_length_ratio": 0.5,
|
||||
"td_maxheight": 2.0,
|
||||
"td_maxlen": 1.0,
|
||||
"td_on_pad_in_zone": false,
|
||||
"td_target_name": "td_round_shape",
|
||||
"td_width_to_size_filter_ratio": 0.9
|
||||
},
|
||||
{
|
||||
"td_allow_use_two_tracks": true,
|
||||
"td_curve_segcount": 0,
|
||||
"td_height_ratio": 1.0,
|
||||
"td_length_ratio": 0.5,
|
||||
"td_maxheight": 2.0,
|
||||
"td_maxlen": 1.0,
|
||||
"td_on_pad_in_zone": false,
|
||||
"td_target_name": "td_rect_shape",
|
||||
"td_width_to_size_filter_ratio": 0.9
|
||||
},
|
||||
{
|
||||
"td_allow_use_two_tracks": true,
|
||||
"td_curve_segcount": 0,
|
||||
"td_height_ratio": 1.0,
|
||||
"td_length_ratio": 0.5,
|
||||
"td_maxheight": 2.0,
|
||||
"td_maxlen": 1.0,
|
||||
"td_on_pad_in_zone": false,
|
||||
"td_target_name": "td_track_end",
|
||||
"td_width_to_size_filter_ratio": 0.9
|
||||
}
|
||||
],
|
||||
"track_widths": [],
|
||||
"tuning_pattern_settings": {
|
||||
"diff_pair_defaults": {
|
||||
"corner_radius_percentage": 80,
|
||||
"corner_style": 1,
|
||||
"max_amplitude": 1.0,
|
||||
"min_amplitude": 0.2,
|
||||
"single_sided": false,
|
||||
"spacing": 1.0
|
||||
},
|
||||
"diff_pair_skew_defaults": {
|
||||
"corner_radius_percentage": 80,
|
||||
"corner_style": 1,
|
||||
"max_amplitude": 1.0,
|
||||
"min_amplitude": 0.2,
|
||||
"single_sided": false,
|
||||
"spacing": 0.6
|
||||
},
|
||||
"single_track_defaults": {
|
||||
"corner_radius_percentage": 80,
|
||||
"corner_style": 1,
|
||||
"max_amplitude": 1.0,
|
||||
"min_amplitude": 0.2,
|
||||
"single_sided": false,
|
||||
"spacing": 0.6
|
||||
}
|
||||
},
|
||||
"via_dimensions": [],
|
||||
"zones_allow_external_fillets": false
|
||||
},
|
||||
"ipc2581": {
|
||||
"dist": "",
|
||||
"distpn": "",
|
||||
"internal_id": "",
|
||||
"mfg": "",
|
||||
"mpn": ""
|
||||
},
|
||||
"layer_pairs": [],
|
||||
"layer_presets": [],
|
||||
"viewports": []
|
||||
},
|
||||
"boards": [],
|
||||
"component_class_settings": {
|
||||
"assignments": [],
|
||||
"meta": {
|
||||
"version": 0
|
||||
},
|
||||
"sheet_component_classes": {
|
||||
"enabled": false
|
||||
}
|
||||
},
|
||||
"cvpcb": {
|
||||
"equivalence_files": []
|
||||
},
|
||||
"erc": {
|
||||
"erc_exclusions": [],
|
||||
"meta": {
|
||||
"version": 0
|
||||
},
|
||||
"pin_map": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
2,
|
||||
1,
|
||||
1,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
1,
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2
|
||||
]
|
||||
],
|
||||
"rule_severities": {
|
||||
"bus_definition_conflict": "error",
|
||||
"bus_entry_needed": "error",
|
||||
"bus_to_bus_conflict": "error",
|
||||
"bus_to_net_conflict": "error",
|
||||
"different_unit_footprint": "error",
|
||||
"different_unit_net": "error",
|
||||
"duplicate_reference": "error",
|
||||
"duplicate_sheet_names": "error",
|
||||
"endpoint_off_grid": "warning",
|
||||
"extra_units": "error",
|
||||
"footprint_filter": "ignore",
|
||||
"footprint_link_issues": "warning",
|
||||
"four_way_junction": "ignore",
|
||||
"global_label_dangling": "warning",
|
||||
"ground_pin_not_ground": "warning",
|
||||
"hier_label_mismatch": "error",
|
||||
"isolated_pin_label": "warning",
|
||||
"label_dangling": "error",
|
||||
"label_multiple_wires": "warning",
|
||||
"lib_symbol_issues": "warning",
|
||||
"lib_symbol_mismatch": "warning",
|
||||
"missing_bidi_pin": "warning",
|
||||
"missing_input_pin": "warning",
|
||||
"missing_power_pin": "error",
|
||||
"missing_unit": "warning",
|
||||
"multiple_net_names": "warning",
|
||||
"net_not_bus_member": "warning",
|
||||
"no_connect_connected": "warning",
|
||||
"no_connect_dangling": "warning",
|
||||
"pin_not_connected": "error",
|
||||
"pin_not_driven": "error",
|
||||
"pin_to_pin": "warning",
|
||||
"power_pin_not_driven": "error",
|
||||
"same_local_global_label": "warning",
|
||||
"similar_label_and_power": "warning",
|
||||
"similar_labels": "warning",
|
||||
"similar_power": "warning",
|
||||
"simulation_model_issue": "ignore",
|
||||
"single_global_label": "ignore",
|
||||
"stacked_pin_name": "warning",
|
||||
"unannotated": "error",
|
||||
"unconnected_wire_endpoint": "warning",
|
||||
"undefined_netclass": "error",
|
||||
"unit_value_mismatch": "error",
|
||||
"unresolved_variable": "error",
|
||||
"wire_dangling": "error"
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"pinned_footprint_libs": [],
|
||||
"pinned_symbol_libs": []
|
||||
},
|
||||
"meta": {
|
||||
"filename": "bugtest.kicad_pro",
|
||||
"version": 3
|
||||
},
|
||||
"net_settings": {
|
||||
"classes": [
|
||||
{
|
||||
"bus_width": 12,
|
||||
"clearance": 0.2,
|
||||
"diff_pair_gap": 0.25,
|
||||
"diff_pair_via_gap": 0.25,
|
||||
"diff_pair_width": 0.2,
|
||||
"line_style": 0,
|
||||
"microvia_diameter": 0.3,
|
||||
"microvia_drill": 0.1,
|
||||
"name": "Default",
|
||||
"pcb_color": "rgba(0, 0, 0, 0.000)",
|
||||
"priority": 2147483647,
|
||||
"schematic_color": "rgba(0, 0, 0, 0.000)",
|
||||
"track_width": 0.2,
|
||||
"tuning_profile": "",
|
||||
"via_diameter": 0.6,
|
||||
"via_drill": 0.3,
|
||||
"wire_width": 6
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"version": 5
|
||||
},
|
||||
"net_colors": null,
|
||||
"netclass_assignments": null,
|
||||
"netclass_patterns": []
|
||||
},
|
||||
"pcbnew": {
|
||||
"last_paths": {
|
||||
"gencad": "",
|
||||
"idf": "",
|
||||
"netlist": "",
|
||||
"plot": "",
|
||||
"pos_files": "",
|
||||
"specctra_dsn": "",
|
||||
"step": "",
|
||||
"svg": "",
|
||||
"vrml": ""
|
||||
},
|
||||
"page_layout_descr_file": ""
|
||||
},
|
||||
"schematic": {
|
||||
"annotate_start_num": 0,
|
||||
"annotation": {
|
||||
"method": 0,
|
||||
"sort_order": 0
|
||||
},
|
||||
"bom_export_filename": "${PROJECTNAME}.csv",
|
||||
"bom_fmt_presets": [],
|
||||
"bom_fmt_settings": {
|
||||
"field_delimiter": ",",
|
||||
"keep_line_breaks": false,
|
||||
"keep_tabs": false,
|
||||
"name": "CSV",
|
||||
"ref_delimiter": ",",
|
||||
"ref_range_delimiter": "",
|
||||
"string_delimiter": "\""
|
||||
},
|
||||
"bom_presets": [],
|
||||
"bom_settings": {
|
||||
"exclude_dnp": false,
|
||||
"fields_ordered": [
|
||||
{
|
||||
"group_by": false,
|
||||
"label": "Reference",
|
||||
"name": "Reference",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": false,
|
||||
"label": "Qty",
|
||||
"name": "${QUANTITY}",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": true,
|
||||
"label": "Value",
|
||||
"name": "Value",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": true,
|
||||
"label": "DNP",
|
||||
"name": "${DNP}",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": true,
|
||||
"label": "Exclude from BOM",
|
||||
"name": "${EXCLUDE_FROM_BOM}",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": true,
|
||||
"label": "Exclude from Board",
|
||||
"name": "${EXCLUDE_FROM_BOARD}",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": true,
|
||||
"label": "Footprint",
|
||||
"name": "Footprint",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": false,
|
||||
"label": "Datasheet",
|
||||
"name": "Datasheet",
|
||||
"show": true
|
||||
}
|
||||
],
|
||||
"filter_string": "",
|
||||
"group_symbols": true,
|
||||
"include_excluded_from_bom": true,
|
||||
"name": "Default Editing",
|
||||
"sort_asc": true,
|
||||
"sort_field": "Reference"
|
||||
},
|
||||
"bus_aliases": {},
|
||||
"connection_grid_size": 50.0,
|
||||
"drawing": {
|
||||
"dashed_lines_dash_length_ratio": 12.0,
|
||||
"dashed_lines_gap_length_ratio": 3.0,
|
||||
"default_line_thickness": 6.0,
|
||||
"default_text_size": 50.0,
|
||||
"field_names": [],
|
||||
"hop_over_size_choice": 0,
|
||||
"intersheets_ref_own_page": false,
|
||||
"intersheets_ref_prefix": "",
|
||||
"intersheets_ref_short": false,
|
||||
"intersheets_ref_show": false,
|
||||
"intersheets_ref_suffix": "",
|
||||
"junction_size_choice": 3,
|
||||
"label_size_ratio": 0.25,
|
||||
"operating_point_overlay_i_precision": 3,
|
||||
"operating_point_overlay_i_range": "~A",
|
||||
"operating_point_overlay_v_precision": 3,
|
||||
"operating_point_overlay_v_range": "~V",
|
||||
"overbar_offset_ratio": 1.23,
|
||||
"pin_symbol_size": 0.0,
|
||||
"text_offset_ratio": 0.08
|
||||
},
|
||||
"legacy_lib_dir": "",
|
||||
"legacy_lib_list": [],
|
||||
"meta": {
|
||||
"version": 1
|
||||
},
|
||||
"net_format_name": "",
|
||||
"page_layout_descr_file": "",
|
||||
"plot_directory": "",
|
||||
"reuse_designators": true,
|
||||
"space_save_all_events": true,
|
||||
"spice_current_sheet_as_root": false,
|
||||
"spice_external_command": "spice \"%I\"",
|
||||
"spice_model_current_sheet_as_root": true,
|
||||
"spice_save_all_currents": false,
|
||||
"spice_save_all_dissipations": false,
|
||||
"spice_save_all_voltages": false,
|
||||
"subpart_first_id": 65,
|
||||
"subpart_id_separator": 0,
|
||||
"top_level_sheets": [
|
||||
{
|
||||
"filename": "bugtest.kicad_sch",
|
||||
"name": "bugtest",
|
||||
"uuid": "084ee3b1-71f6-47a6-9dc8-ecb4f5c55a9a"
|
||||
}
|
||||
],
|
||||
"used_designators": "",
|
||||
"variants": []
|
||||
},
|
||||
"sheets": [
|
||||
[
|
||||
"084ee3b1-71f6-47a6-9dc8-ecb4f5c55a9a",
|
||||
"bugtest"
|
||||
]
|
||||
],
|
||||
"text_variables": {},
|
||||
"tuning_profiles": {
|
||||
"meta": {
|
||||
"version": 0
|
||||
},
|
||||
"tuning_profiles_impedance_geometric": []
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,392 @@
|
||||
(kicad_symbol_lib
|
||||
(version 20241209)
|
||||
(generator "kicad_symbol_editor")
|
||||
(generator_version "9.0")
|
||||
(symbol "MOLEX_PICOBLADE_8PHOR"
|
||||
(exclude_from_sim no)
|
||||
(in_bom yes)
|
||||
(on_board yes)
|
||||
(property "Reference" "J1"
|
||||
(at 6.35 0.0001 0)
|
||||
(effects
|
||||
(font
|
||||
(size 1.27 1.0795)
|
||||
)
|
||||
(justify left)
|
||||
)
|
||||
)
|
||||
(property "Value" "MOLEX"
|
||||
(at 6.35 -2.5399 0)
|
||||
(effects
|
||||
(font
|
||||
(size 1.27 1.0795)
|
||||
)
|
||||
(justify left)
|
||||
)
|
||||
)
|
||||
(property "Footprint" ""
|
||||
(at 0 0 0)
|
||||
(effects
|
||||
(font
|
||||
(size 1.27 1.27)
|
||||
)
|
||||
(hide yes)
|
||||
)
|
||||
)
|
||||
(property "Datasheet" ""
|
||||
(at 0 0 0)
|
||||
(effects
|
||||
(font
|
||||
(size 1.27 1.27)
|
||||
)
|
||||
(hide yes)
|
||||
)
|
||||
)
|
||||
(property "Description" "1.25mm (.049\") Pitch PicoBlade Header, SMT, Vertical, Lead-free, 8 Circuits"
|
||||
(at 0 0 0)
|
||||
(effects
|
||||
(font
|
||||
(size 1.27 1.27)
|
||||
)
|
||||
(hide yes)
|
||||
)
|
||||
)
|
||||
(property "LOCATION" "Front"
|
||||
(at 0 0 0)
|
||||
(effects
|
||||
(font
|
||||
(size 1.27 1.27)
|
||||
)
|
||||
(hide yes)
|
||||
)
|
||||
)
|
||||
(property "FUNCTION" "Panel"
|
||||
(at 0 0 0)
|
||||
(effects
|
||||
(font
|
||||
(size 1.27 1.27)
|
||||
)
|
||||
(hide yes)
|
||||
)
|
||||
)
|
||||
(symbol "MOLEX_PICOBLADE_8PHOR_1_0"
|
||||
(polyline
|
||||
(pts
|
||||
(xy -2.54 12.7) (xy 5.08 12.7)
|
||||
)
|
||||
(stroke
|
||||
(width 0.254)
|
||||
(type solid)
|
||||
)
|
||||
(fill
|
||||
(type none)
|
||||
)
|
||||
)
|
||||
(polyline
|
||||
(pts
|
||||
(xy -2.54 -15.24) (xy -2.54 12.7)
|
||||
)
|
||||
(stroke
|
||||
(width 0.254)
|
||||
(type solid)
|
||||
)
|
||||
(fill
|
||||
(type none)
|
||||
)
|
||||
)
|
||||
(polyline
|
||||
(pts
|
||||
(xy 5.08 12.7) (xy 5.08 -15.24)
|
||||
)
|
||||
(stroke
|
||||
(width 0.254)
|
||||
(type solid)
|
||||
)
|
||||
(fill
|
||||
(type none)
|
||||
)
|
||||
)
|
||||
(polyline
|
||||
(pts
|
||||
(xy 5.08 -15.24) (xy -2.54 -15.24)
|
||||
)
|
||||
(stroke
|
||||
(width 0.254)
|
||||
(type solid)
|
||||
)
|
||||
(fill
|
||||
(type none)
|
||||
)
|
||||
)
|
||||
(text "${LOCATION}"
|
||||
(at 2.286 -2.54 900)
|
||||
(effects
|
||||
(font
|
||||
(size 1.27 1.0795)
|
||||
)
|
||||
(justify bottom)
|
||||
)
|
||||
)
|
||||
(text "${FUNCTION}"
|
||||
(at 3.81 -2.54 900)
|
||||
(effects
|
||||
(font
|
||||
(size 1.27 1.0795)
|
||||
)
|
||||
(justify bottom)
|
||||
)
|
||||
)
|
||||
(pin no_connect line
|
||||
(at -5.08 7.62 0)
|
||||
(length 2.54)
|
||||
(name "1"
|
||||
(effects
|
||||
(font
|
||||
(size 0 0)
|
||||
)
|
||||
)
|
||||
)
|
||||
(number "1"
|
||||
(effects
|
||||
(font
|
||||
(size 1.27 1.27)
|
||||
)
|
||||
)
|
||||
)
|
||||
(alternate "1.bidir" bidirectional line)
|
||||
(alternate "1.free" free line)
|
||||
(alternate "1.in" input line)
|
||||
(alternate "1.oc" open_collector line)
|
||||
(alternate "1.oe" open_emitter line)
|
||||
(alternate "1.out" output line)
|
||||
(alternate "1.pas" passive line)
|
||||
(alternate "1.pow" power_in line)
|
||||
(alternate "1.sup" power_out line)
|
||||
(alternate "1.tristate" tri_state line)
|
||||
(alternate "1.unspec" unspecified line)
|
||||
)
|
||||
(pin no_connect line
|
||||
(at -5.08 5.08 0)
|
||||
(length 2.54)
|
||||
(name "2"
|
||||
(effects
|
||||
(font
|
||||
(size 0 0)
|
||||
)
|
||||
)
|
||||
)
|
||||
(number "2"
|
||||
(effects
|
||||
(font
|
||||
(size 1.27 1.27)
|
||||
)
|
||||
)
|
||||
)
|
||||
(alternate "2.bidir" bidirectional line)
|
||||
(alternate "2.free" free line)
|
||||
(alternate "2.in" input line)
|
||||
(alternate "2.oc" open_collector line)
|
||||
(alternate "2.oe" open_emitter line)
|
||||
(alternate "2.out" output line)
|
||||
(alternate "2.pas" passive line)
|
||||
(alternate "2.pow" power_in line)
|
||||
(alternate "2.sup" power_out line)
|
||||
(alternate "2.tristate" tri_state line)
|
||||
(alternate "2.unspec" unspecified line)
|
||||
)
|
||||
(pin no_connect line
|
||||
(at -5.08 2.54 0)
|
||||
(length 2.54)
|
||||
(name "3"
|
||||
(effects
|
||||
(font
|
||||
(size 0 0)
|
||||
)
|
||||
)
|
||||
)
|
||||
(number "3"
|
||||
(effects
|
||||
(font
|
||||
(size 1.27 1.27)
|
||||
)
|
||||
)
|
||||
)
|
||||
(alternate "3.bidir" bidirectional line)
|
||||
(alternate "3.free" free line)
|
||||
(alternate "3.in" input line)
|
||||
(alternate "3.oc" open_collector line)
|
||||
(alternate "3.oe" open_emitter line)
|
||||
(alternate "3.out" output line)
|
||||
(alternate "3.pas" passive line)
|
||||
(alternate "3.pow" power_in line)
|
||||
(alternate "3.sup" power_out line)
|
||||
(alternate "3.tristate" tri_state line)
|
||||
(alternate "3.unspec" unspecified line)
|
||||
)
|
||||
(pin no_connect line
|
||||
(at -5.08 0 0)
|
||||
(length 2.54)
|
||||
(name "4"
|
||||
(effects
|
||||
(font
|
||||
(size 0 0)
|
||||
)
|
||||
)
|
||||
)
|
||||
(number "4"
|
||||
(effects
|
||||
(font
|
||||
(size 1.27 1.27)
|
||||
)
|
||||
)
|
||||
)
|
||||
(alternate "4.bidir" bidirectional line)
|
||||
(alternate "4.free" free line)
|
||||
(alternate "4.in" input line)
|
||||
(alternate "4.oc" open_collector line)
|
||||
(alternate "4.oe" open_emitter line)
|
||||
(alternate "4.out" output line)
|
||||
(alternate "4.pas" passive line)
|
||||
(alternate "4.pow" power_in line)
|
||||
(alternate "4.sup" power_out line)
|
||||
(alternate "4.tristate" tri_state line)
|
||||
(alternate "4.unspec" unspecified line)
|
||||
)
|
||||
(pin no_connect line
|
||||
(at -5.08 -2.54 0)
|
||||
(length 2.54)
|
||||
(name "5"
|
||||
(effects
|
||||
(font
|
||||
(size 0 0)
|
||||
)
|
||||
)
|
||||
)
|
||||
(number "5"
|
||||
(effects
|
||||
(font
|
||||
(size 1.27 1.27)
|
||||
)
|
||||
)
|
||||
)
|
||||
(alternate "5.bidir" bidirectional line)
|
||||
(alternate "5.free" free line)
|
||||
(alternate "5.in" input line)
|
||||
(alternate "5.oc" open_collector line)
|
||||
(alternate "5.oe" open_emitter line)
|
||||
(alternate "5.out" output line)
|
||||
(alternate "5.pas" passive line)
|
||||
(alternate "5.pow" power_in line)
|
||||
(alternate "5.sup" power_out line)
|
||||
(alternate "5.tristate" tri_state line)
|
||||
(alternate "5.unspec" unspecified line)
|
||||
)
|
||||
(pin no_connect line
|
||||
(at -5.08 -5.08 0)
|
||||
(length 2.54)
|
||||
(name "6"
|
||||
(effects
|
||||
(font
|
||||
(size 0 0)
|
||||
)
|
||||
)
|
||||
)
|
||||
(number "6"
|
||||
(effects
|
||||
(font
|
||||
(size 1.27 1.27)
|
||||
)
|
||||
)
|
||||
)
|
||||
(alternate "6.bidir" bidirectional line)
|
||||
(alternate "6.free" free line)
|
||||
(alternate "6.in" input line)
|
||||
(alternate "6.oc" open_collector line)
|
||||
(alternate "6.oe" open_emitter line)
|
||||
(alternate "6.out" output line)
|
||||
(alternate "6.pas" passive line)
|
||||
(alternate "6.pow" power_in line)
|
||||
(alternate "6.sup" power_out line)
|
||||
(alternate "6.tristate" tri_state line)
|
||||
(alternate "6.unspec" unspecified line)
|
||||
)
|
||||
(pin no_connect line
|
||||
(at -5.08 -7.62 0)
|
||||
(length 2.54)
|
||||
(name "7"
|
||||
(effects
|
||||
(font
|
||||
(size 0 0)
|
||||
)
|
||||
)
|
||||
)
|
||||
(number "7"
|
||||
(effects
|
||||
(font
|
||||
(size 1.27 1.27)
|
||||
)
|
||||
)
|
||||
)
|
||||
(alternate "7.bidir" bidirectional line)
|
||||
(alternate "7.free" free line)
|
||||
(alternate "7.in" input line)
|
||||
(alternate "7.oc" open_collector line)
|
||||
(alternate "7.oe" open_emitter line)
|
||||
(alternate "7.out" output line)
|
||||
(alternate "7.pas" passive line)
|
||||
(alternate "7.pow" power_in line)
|
||||
(alternate "7.sup" power_out line)
|
||||
(alternate "7.tristate" tri_state line)
|
||||
(alternate "7.unspec" unspecified line)
|
||||
)
|
||||
(pin no_connect line
|
||||
(at -5.08 -10.16 0)
|
||||
(length 2.54)
|
||||
(name "8"
|
||||
(effects
|
||||
(font
|
||||
(size 0 0)
|
||||
)
|
||||
)
|
||||
)
|
||||
(number "8"
|
||||
(effects
|
||||
(font
|
||||
(size 1.27 1.27)
|
||||
)
|
||||
)
|
||||
)
|
||||
(alternate "8.bidir" bidirectional line)
|
||||
(alternate "8.free" free line)
|
||||
(alternate "8.in" input line)
|
||||
(alternate "8.oc" open_collector line)
|
||||
(alternate "8.oe" open_emitter line)
|
||||
(alternate "8.out" output line)
|
||||
(alternate "8.pas" passive line)
|
||||
(alternate "8.pow" power_in line)
|
||||
(alternate "8.sup" power_out line)
|
||||
(alternate "8.tristate" tri_state line)
|
||||
(alternate "8.unspec" unspecified line)
|
||||
)
|
||||
(pin passive line
|
||||
(at -5.08 -15.24 0)
|
||||
(length 2.54)
|
||||
(name "G"
|
||||
(effects
|
||||
(font
|
||||
(size 0 0)
|
||||
)
|
||||
)
|
||||
)
|
||||
(number "G"
|
||||
(effects
|
||||
(font
|
||||
(size 0 0)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(embedded_fonts no)
|
||||
)
|
||||
)
|
||||
@@ -68,6 +68,7 @@ set( QA_EESCHEMA_SRCS
|
||||
test_issue18119_bus_hierarchy.cpp
|
||||
test_issue18299_bus_member_rename.cpp
|
||||
test_issue20173_paste_subsheet.cpp
|
||||
test_issue22286_pin_alternate.cpp
|
||||
test_issue16915_bus_netclass.cpp
|
||||
test_nc_pin_connectivity.cpp
|
||||
test_crossing_label.cpp
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Test for issue #22286 - Pin alternate type not being applied after schematic load.
|
||||
*
|
||||
* When a pin has an alternate function selected (like "8.pow" with type power_in),
|
||||
* the pin TYPE should switch from the default (no_connect) to the alternate's type.
|
||||
* This test verifies the fix by loading the actual reproduction schematic.
|
||||
*/
|
||||
|
||||
#include <qa_utils/wx_utils/unit_test_utils.h>
|
||||
#include "eeschema_test_utils.h"
|
||||
|
||||
#include <lib_symbol.h>
|
||||
#include <pin_type.h>
|
||||
#include <sch_pin.h>
|
||||
#include <sch_symbol.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
|
||||
|
||||
class TEST_ISSUE22286_FIXTURE : public KI_TEST::SCHEMATIC_TEST_FIXTURE
|
||||
{
|
||||
protected:
|
||||
wxFileName GetSchematicPath( const wxString& aBaseName ) override
|
||||
{
|
||||
wxFileName fn( aBaseName );
|
||||
return fn;
|
||||
}
|
||||
|
||||
public:
|
||||
SCH_SYMBOL* FindSymbolByRef( const wxString& aRef )
|
||||
{
|
||||
if( !m_schematic )
|
||||
return nullptr;
|
||||
|
||||
SCH_SCREEN* screen = m_schematic->RootScreen();
|
||||
|
||||
if( !screen )
|
||||
return nullptr;
|
||||
|
||||
for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
|
||||
{
|
||||
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
|
||||
|
||||
if( symbol && symbol->GetRef( &m_schematic->Hierarchy()[0], false ) == aRef )
|
||||
return symbol;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SCH_PIN* FindPinByNumber( SCH_SYMBOL* aSymbol, const wxString& aNumber )
|
||||
{
|
||||
if( !aSymbol )
|
||||
return nullptr;
|
||||
|
||||
for( SCH_PIN* pin : aSymbol->GetPins( &m_schematic->Hierarchy()[0] ) )
|
||||
{
|
||||
if( pin->GetNumber() == aNumber )
|
||||
return pin;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE( Issue22286, TEST_ISSUE22286_FIXTURE )
|
||||
|
||||
|
||||
/**
|
||||
* Test that pin alternates are correctly applied after loading a schematic from disk.
|
||||
*
|
||||
* This test loads the actual reproduction schematic for issue #22286 and verifies that:
|
||||
* 1. Pin 8 on symbol J1 has the alternate "8.pow" set
|
||||
* 2. Pin 8's GetType() returns PT_POWER_IN (not PT_NC)
|
||||
* 3. The library pin has the alternates map populated
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE( PinAlternateTypeAfterSchematicLoad )
|
||||
{
|
||||
wxFileName fn;
|
||||
fn.SetPath( KI_TEST::GetEeschemaTestDataDir() );
|
||||
fn.AppendDir( wxS( "issue22286" ) );
|
||||
fn.SetName( wxS( "bugtest" ) );
|
||||
fn.SetExt( FILEEXT::KiCadSchematicFileExtension );
|
||||
|
||||
LoadSchematic( fn.GetFullPath() );
|
||||
|
||||
// Find symbol J1 (the MOLEX connector)
|
||||
SCH_SYMBOL* j1 = FindSymbolByRef( wxS( "J1" ) );
|
||||
BOOST_REQUIRE_MESSAGE( j1 != nullptr, "Symbol J1 not found in schematic" );
|
||||
|
||||
// Find pin 8
|
||||
SCH_PIN* pin8 = FindPinByNumber( j1, wxS( "8" ) );
|
||||
BOOST_REQUIRE_MESSAGE( pin8 != nullptr, "Pin 8 not found on symbol J1" );
|
||||
|
||||
// Check that the alternate is set
|
||||
BOOST_CHECK_MESSAGE( pin8->GetAlt() == wxS( "8.pow" ),
|
||||
"Pin 8 should have alternate '8.pow' set, but has '"
|
||||
+ pin8->GetAlt() + "'" );
|
||||
|
||||
// Check that m_libPin is set
|
||||
BOOST_CHECK_MESSAGE( pin8->GetLibPin() != nullptr,
|
||||
"Pin 8 should have m_libPin set after schematic load" );
|
||||
|
||||
if( pin8->GetLibPin() )
|
||||
{
|
||||
// Check that the library pin has alternates
|
||||
const auto& alternates = pin8->GetLibPin()->GetAlternates();
|
||||
BOOST_CHECK_MESSAGE( !alternates.empty(),
|
||||
"Library pin should have alternates populated" );
|
||||
BOOST_CHECK_MESSAGE( alternates.count( wxS( "8.pow" ) ) > 0,
|
||||
"Library pin should have '8.pow' in alternates map" );
|
||||
|
||||
// Check the alternate's type in the library pin
|
||||
if( alternates.count( wxS( "8.pow" ) ) > 0 )
|
||||
{
|
||||
const SCH_PIN::ALT& alt = alternates.at( wxS( "8.pow" ) );
|
||||
BOOST_CHECK_MESSAGE( alt.m_Type == ELECTRICAL_PINTYPE::PT_POWER_IN,
|
||||
"Library pin alternate '8.pow' should have type PT_POWER_IN" );
|
||||
}
|
||||
}
|
||||
|
||||
// The critical test: GetType() should return the alternate's type, not the default
|
||||
ELECTRICAL_PINTYPE pinType = pin8->GetType();
|
||||
BOOST_CHECK_MESSAGE( pinType == ELECTRICAL_PINTYPE::PT_POWER_IN,
|
||||
"Pin 8 GetType() should return PT_POWER_IN (7) for alternate '8.pow', "
|
||||
"but returned " + std::to_string( static_cast<int>( pinType ) )
|
||||
+ " (" + ElectricalPinTypeGetText( pinType ) + ")" );
|
||||
|
||||
// Verify the shown name is the alternate name
|
||||
BOOST_CHECK_MESSAGE( pin8->GetShownName() == wxS( "8.pow" ),
|
||||
"Pin 8 GetShownName() should return '8.pow', but returned '"
|
||||
+ pin8->GetShownName() + "'" );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verify the connection graph does NOT treat the pin as no-connect.
|
||||
*
|
||||
* When pin 8 has type PT_POWER_IN (from alternate), it should NOT be marked
|
||||
* as a no-connect in the connection graph. It will still get a "Net-(...)" name
|
||||
* because it's on a regular connector (not a power symbol), but importantly it
|
||||
* should NOT be prefixed with "unconnected-".
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE( ConnectionGraphHandlesPinAlternateType )
|
||||
{
|
||||
wxFileName fn;
|
||||
fn.SetPath( KI_TEST::GetEeschemaTestDataDir() );
|
||||
fn.AppendDir( wxS( "issue22286" ) );
|
||||
fn.SetName( wxS( "bugtest" ) );
|
||||
fn.SetExt( FILEEXT::KiCadSchematicFileExtension );
|
||||
|
||||
LoadSchematic( fn.GetFullPath() );
|
||||
|
||||
SCH_SYMBOL* j1 = FindSymbolByRef( wxS( "J1" ) );
|
||||
BOOST_REQUIRE( j1 != nullptr );
|
||||
|
||||
SCH_PIN* pin8 = FindPinByNumber( j1, wxS( "8" ) );
|
||||
BOOST_REQUIRE( pin8 != nullptr );
|
||||
|
||||
// Get the net name for pin 8
|
||||
SCH_SHEET_PATH path = m_schematic->Hierarchy()[0];
|
||||
wxString netName = pin8->GetDefaultNetName( path );
|
||||
|
||||
// With the fix, pin 8 should NOT get an "unconnected-(...)" name because
|
||||
// it's a power pin (PT_POWER_IN), not a no-connect pin (PT_NC).
|
||||
// It will still get a "Net-(...)" name because it's on a regular connector.
|
||||
BOOST_CHECK_MESSAGE( !netName.StartsWith( wxS( "unconnected-(" ) ),
|
||||
"Pin 8 (power_in) should not get an 'unconnected-(...)' name. "
|
||||
"Got: '" + netName + "'" );
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
@@ -214,6 +214,334 @@ BOOST_AUTO_TEST_CASE( AlternatePinRenameUpdates )
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test for issue #22286 - GetType() should return the alternate's type when alternate is selected
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE( AlternatePinTypeReturnsCorrectType )
|
||||
{
|
||||
// Set the library pin's default type to no_connect
|
||||
m_lib_pin->SetType( ELECTRICAL_PINTYPE::PT_NC );
|
||||
|
||||
// Add an alternate with a different type (power_in)
|
||||
SCH_PIN::ALT powerAlt;
|
||||
powerAlt.m_Name = wxS( "8.pow" );
|
||||
powerAlt.m_Shape = GRAPHIC_PINSHAPE::LINE;
|
||||
powerAlt.m_Type = ELECTRICAL_PINTYPE::PT_POWER_IN;
|
||||
m_lib_pin->GetAlternates()[ wxS( "8.pow" ) ] = powerAlt;
|
||||
|
||||
// Flatten and update the symbol to get a fresh schematic pin
|
||||
m_parent_symbol->SetLibSymbol( m_parent_part->Flatten().release() );
|
||||
m_sch_pin = m_parent_symbol->GetPins()[0];
|
||||
|
||||
// Before selecting alternate, type should be the default (NC)
|
||||
BOOST_CHECK( m_sch_pin->GetType() == ELECTRICAL_PINTYPE::PT_NC );
|
||||
|
||||
// Select the alternate
|
||||
m_sch_pin->SetAlt( wxS( "8.pow" ) );
|
||||
|
||||
// After selecting alternate, type should be the alternate's type (POWER_IN)
|
||||
BOOST_CHECK_EQUAL( m_sch_pin->GetAlt(), "8.pow" );
|
||||
BOOST_CHECK( m_sch_pin->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN );
|
||||
|
||||
// Also verify shape changed
|
||||
BOOST_CHECK( m_sch_pin->GetShape() == GRAPHIC_PINSHAPE::LINE );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test for issue #22286 - simulate schematic loading scenario
|
||||
* When a schematic is loaded, the pin's alternate is set BEFORE SetLibSymbol is called.
|
||||
* The alternate must persist through UpdatePins().
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE( AlternatePinTypePersistsThroughSymbolUpdate )
|
||||
{
|
||||
// Set the library pin's default type to no_connect
|
||||
m_lib_pin->SetType( ELECTRICAL_PINTYPE::PT_NC );
|
||||
|
||||
// Add an alternate with a different type (power_in)
|
||||
SCH_PIN::ALT powerAlt;
|
||||
powerAlt.m_Name = wxS( "8.pow" );
|
||||
powerAlt.m_Shape = GRAPHIC_PINSHAPE::LINE;
|
||||
powerAlt.m_Type = ELECTRICAL_PINTYPE::PT_POWER_IN;
|
||||
m_lib_pin->GetAlternates()[ wxS( "8.pow" ) ] = powerAlt;
|
||||
|
||||
// First flatten to set up the symbol
|
||||
m_parent_symbol->SetLibSymbol( m_parent_part->Flatten().release() );
|
||||
m_sch_pin = m_parent_symbol->GetPins()[0];
|
||||
|
||||
// Set the alternate on the schematic pin (like the parser would)
|
||||
m_sch_pin->SetAlt( wxS( "8.pow" ) );
|
||||
BOOST_CHECK_EQUAL( m_sch_pin->GetAlt(), "8.pow" );
|
||||
BOOST_CHECK( m_sch_pin->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN );
|
||||
|
||||
// Now simulate what happens when the library symbol is re-resolved
|
||||
// This is similar to what happens after loading a schematic from file
|
||||
m_parent_symbol->SetLibSymbol( m_parent_part->Flatten().release() );
|
||||
m_sch_pin = m_parent_symbol->GetPins()[0];
|
||||
|
||||
// After the symbol update, the alternate should still be set
|
||||
BOOST_CHECK_EQUAL( m_sch_pin->GetAlt(), "8.pow" );
|
||||
|
||||
// And GetType() should return the alternate's type
|
||||
BOOST_CHECK( m_sch_pin->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test for issue #22286 - simulate parser-created pins with alternates
|
||||
* The parser creates pins with m_alt set but m_libPin=nullptr.
|
||||
* Verify that after UpdatePins() the alternate type is correctly returned.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE( ParserCreatedPinWithAlternate )
|
||||
{
|
||||
// Create a library symbol with a pin that has alternates
|
||||
LIB_SYMBOL* libSymbol = new LIB_SYMBOL( "test_symbol", nullptr );
|
||||
|
||||
SCH_PIN* libPin = new SCH_PIN( libSymbol );
|
||||
libPin->SetNumber( "8" );
|
||||
libPin->SetName( "PIN8" );
|
||||
libPin->SetType( ELECTRICAL_PINTYPE::PT_NC ); // Default type is NC
|
||||
libPin->SetPosition( VECTOR2I( 0, 0 ) );
|
||||
|
||||
// Add an alternate with power_in type
|
||||
SCH_PIN::ALT powerAlt;
|
||||
powerAlt.m_Name = wxS( "8.pow" );
|
||||
powerAlt.m_Shape = GRAPHIC_PINSHAPE::LINE;
|
||||
powerAlt.m_Type = ELECTRICAL_PINTYPE::PT_POWER_IN;
|
||||
libPin->GetAlternates()[ wxS( "8.pow" ) ] = powerAlt;
|
||||
|
||||
libSymbol->AddDrawItem( libPin );
|
||||
|
||||
// Create a schematic symbol
|
||||
SCH_SHEET_PATH path;
|
||||
SCH_SYMBOL* symbol = new SCH_SYMBOL( *libSymbol, libSymbol->GetLibId(), &path, 0, 0,
|
||||
VECTOR2I( 0, 0 ) );
|
||||
symbol->SetRef( &path, "J1" );
|
||||
|
||||
// Simulate what the parser does: create a raw pin with alternate set
|
||||
// This bypasses SetAlt() validation by using the constructor directly
|
||||
symbol->GetRawPins().clear(); // Remove auto-created pins
|
||||
symbol->GetRawPins().emplace_back(
|
||||
std::make_unique<SCH_PIN>( symbol, wxS( "8" ), wxS( "8.pow" ), KIID() ) );
|
||||
|
||||
SCH_PIN* parserPin = symbol->GetRawPins()[0].get();
|
||||
|
||||
// At this point, m_alt is set but m_libPin is nullptr
|
||||
BOOST_CHECK_EQUAL( parserPin->GetAlt(), "8.pow" );
|
||||
BOOST_CHECK( parserPin->GetLibPin() == nullptr );
|
||||
|
||||
// GetType() should return PT_UNSPECIFIED when m_libPin is null
|
||||
BOOST_CHECK( parserPin->GetType() == ELECTRICAL_PINTYPE::PT_UNSPECIFIED );
|
||||
|
||||
// Now simulate SetLibSymbol() which calls UpdatePins()
|
||||
symbol->SetLibSymbol( libSymbol->Flatten().release() );
|
||||
|
||||
// Verify the flattened library symbol has pins with alternates
|
||||
BOOST_CHECK( symbol->GetLibSymbolRef() != nullptr );
|
||||
std::vector<SCH_PIN*> libPins = symbol->GetLibSymbolRef()->GetPins();
|
||||
BOOST_CHECK_EQUAL( libPins.size(), 1 );
|
||||
|
||||
if( !libPins.empty() )
|
||||
{
|
||||
SCH_PIN* flattenedLibPin = libPins[0];
|
||||
BOOST_CHECK( !flattenedLibPin->GetAlternates().empty() );
|
||||
BOOST_CHECK( flattenedLibPin->GetAlternates().count( wxS( "8.pow" ) ) > 0 );
|
||||
}
|
||||
|
||||
// Get the pin after the update
|
||||
SCH_PIN* updatedPin = symbol->GetPins( &path )[0];
|
||||
|
||||
// The alternate should still be set
|
||||
BOOST_CHECK_EQUAL( updatedPin->GetAlt(), "8.pow" );
|
||||
|
||||
// m_libPin should now be set
|
||||
BOOST_CHECK( updatedPin->GetLibPin() != nullptr );
|
||||
|
||||
// GetType() should return the alternate's type (PT_POWER_IN)
|
||||
BOOST_CHECK( updatedPin->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN );
|
||||
|
||||
delete symbol;
|
||||
delete libSymbol;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test for issue #22286 - detailed trace of SetLibSymbol flow
|
||||
* Verifies that library pin alternates are preserved through the copy
|
||||
* and that SetAlt succeeds in UpdatePins().
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE( LibraryPinAlternatesPreservedThroughCopy )
|
||||
{
|
||||
// Create original library symbol with pin that has alternates
|
||||
LIB_SYMBOL* origLibSymbol = new LIB_SYMBOL( "test_symbol", nullptr );
|
||||
|
||||
SCH_PIN* origLibPin = new SCH_PIN( origLibSymbol );
|
||||
origLibPin->SetNumber( "8" );
|
||||
origLibPin->SetName( "8" ); // Default name matches number
|
||||
origLibPin->SetType( ELECTRICAL_PINTYPE::PT_NC ); // Default type is NC
|
||||
origLibPin->SetPosition( VECTOR2I( 0, 0 ) );
|
||||
|
||||
// Add alternate with power_in type
|
||||
SCH_PIN::ALT powerAlt;
|
||||
powerAlt.m_Name = wxS( "8.pow" );
|
||||
powerAlt.m_Shape = GRAPHIC_PINSHAPE::LINE;
|
||||
powerAlt.m_Type = ELECTRICAL_PINTYPE::PT_POWER_IN;
|
||||
origLibPin->GetAlternates()[ wxS( "8.pow" ) ] = powerAlt;
|
||||
|
||||
origLibSymbol->AddDrawItem( origLibPin );
|
||||
|
||||
// Verify original has alternates
|
||||
BOOST_CHECK( !origLibPin->GetAlternates().empty() );
|
||||
BOOST_CHECK( origLibPin->GetAlternates().count( wxS( "8.pow" ) ) > 0 );
|
||||
|
||||
// Simulate what happens during loading:
|
||||
// 1. Library symbol is stored in m_libSymbols (just keep the original)
|
||||
// 2. Create a COPY of the library symbol (like UpdateLocalLibSymbolLinks does)
|
||||
LIB_SYMBOL* copiedLibSymbol = new LIB_SYMBOL( *origLibSymbol );
|
||||
|
||||
// Verify the copied library symbol has pins with alternates
|
||||
std::vector<SCH_PIN*> copiedLibPins = copiedLibSymbol->GetPins();
|
||||
BOOST_CHECK_EQUAL( copiedLibPins.size(), 1 );
|
||||
|
||||
if( !copiedLibPins.empty() )
|
||||
{
|
||||
SCH_PIN* copiedLibPin = copiedLibPins[0];
|
||||
|
||||
// This is the critical check - does the copied lib pin have alternates?
|
||||
BOOST_CHECK_MESSAGE( !copiedLibPin->GetAlternates().empty(),
|
||||
"Copied library pin should have alternates" );
|
||||
BOOST_CHECK_MESSAGE( copiedLibPin->GetAlternates().count( wxS( "8.pow" ) ) > 0,
|
||||
"Copied library pin should have '8.pow' alternate" );
|
||||
|
||||
// Check if the alternate has the correct type
|
||||
if( copiedLibPin->GetAlternates().count( wxS( "8.pow" ) ) > 0 )
|
||||
{
|
||||
BOOST_CHECK( copiedLibPin->GetAlternates().at( wxS( "8.pow" ) ).m_Type
|
||||
== ELECTRICAL_PINTYPE::PT_POWER_IN );
|
||||
}
|
||||
}
|
||||
|
||||
// Now create a schematic symbol with parser-created raw pins
|
||||
SCH_SHEET_PATH path;
|
||||
SCH_SYMBOL* symbol = new SCH_SYMBOL( *origLibSymbol, origLibSymbol->GetLibId(), &path, 0, 0,
|
||||
VECTOR2I( 0, 0 ) );
|
||||
symbol->SetRef( &path, "J1" );
|
||||
|
||||
// Clear auto-created pins and add parser-style raw pin
|
||||
symbol->GetRawPins().clear();
|
||||
symbol->GetRawPins().emplace_back(
|
||||
std::make_unique<SCH_PIN>( symbol, wxS( "8" ), wxS( "8.pow" ), KIID() ) );
|
||||
|
||||
// Verify raw pin state before SetLibSymbol
|
||||
SCH_PIN* rawPin = symbol->GetRawPins()[0].get();
|
||||
BOOST_CHECK_EQUAL( rawPin->GetAlt(), "8.pow" );
|
||||
BOOST_CHECK( rawPin->GetLibPin() == nullptr );
|
||||
|
||||
// Call SetLibSymbol with the COPIED library symbol (like UpdateLocalLibSymbolLinks does)
|
||||
symbol->SetLibSymbol( copiedLibSymbol ); // Takes ownership
|
||||
|
||||
// Get the pin after UpdatePins() was called
|
||||
std::vector<SCH_PIN*> schPins = symbol->GetPins( &path );
|
||||
BOOST_CHECK_EQUAL( schPins.size(), 1 );
|
||||
|
||||
if( !schPins.empty() )
|
||||
{
|
||||
SCH_PIN* schPin = schPins[0];
|
||||
|
||||
// Check that m_libPin is set
|
||||
BOOST_CHECK_MESSAGE( schPin->GetLibPin() != nullptr,
|
||||
"Schematic pin should have m_libPin set after UpdatePins" );
|
||||
|
||||
// Check that the alternate is still set
|
||||
BOOST_CHECK_MESSAGE( schPin->GetAlt() == "8.pow",
|
||||
"Alternate should be preserved as '8.pow'" );
|
||||
|
||||
// Check that GetType() returns the alternate's type
|
||||
BOOST_CHECK_MESSAGE( schPin->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN,
|
||||
"GetType() should return alternate's type (PT_POWER_IN)" );
|
||||
|
||||
// Additional diagnostic: check the library pin's alternates
|
||||
if( schPin->GetLibPin() )
|
||||
{
|
||||
BOOST_CHECK_MESSAGE( !schPin->GetLibPin()->GetAlternates().empty(),
|
||||
"Library pin pointed to by schematic pin should have alternates" );
|
||||
BOOST_CHECK_MESSAGE( schPin->GetLibPin()->GetAlternates().count( wxS( "8.pow" ) ) > 0,
|
||||
"Library pin should have '8.pow' in its alternates map" );
|
||||
}
|
||||
}
|
||||
|
||||
delete symbol;
|
||||
delete origLibSymbol;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test for issue #22286 - verify behavior when GetType() is called before
|
||||
* m_libPin is set. This simulates what happens if GetType() is called
|
||||
* during loading before UpdateLocalLibSymbolLinks() runs.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE( GetTypeBeforeLibPinSet )
|
||||
{
|
||||
// Create a schematic symbol with parser-created raw pin
|
||||
SCH_SHEET_PATH path;
|
||||
LIB_SYMBOL* libSymbol = new LIB_SYMBOL( "test_symbol", nullptr );
|
||||
|
||||
SCH_PIN* libPin = new SCH_PIN( libSymbol );
|
||||
libPin->SetNumber( "8" );
|
||||
libPin->SetName( "8" );
|
||||
libPin->SetType( ELECTRICAL_PINTYPE::PT_NC );
|
||||
libPin->SetPosition( VECTOR2I( 0, 0 ) );
|
||||
|
||||
SCH_PIN::ALT powerAlt;
|
||||
powerAlt.m_Name = wxS( "8.pow" );
|
||||
powerAlt.m_Shape = GRAPHIC_PINSHAPE::LINE;
|
||||
powerAlt.m_Type = ELECTRICAL_PINTYPE::PT_POWER_IN;
|
||||
libPin->GetAlternates()[ wxS( "8.pow" ) ] = powerAlt;
|
||||
libSymbol->AddDrawItem( libPin );
|
||||
|
||||
// Create symbol using default constructor (like parser does)
|
||||
SCH_SYMBOL* symbol = new SCH_SYMBOL();
|
||||
symbol->SetLibId( libSymbol->GetLibId() );
|
||||
|
||||
// Add parser-style raw pin with alternate set but no m_libPin
|
||||
symbol->GetRawPins().emplace_back(
|
||||
std::make_unique<SCH_PIN>( symbol, wxS( "8" ), wxS( "8.pow" ), KIID() ) );
|
||||
|
||||
SCH_PIN* rawPin = symbol->GetRawPins()[0].get();
|
||||
|
||||
// At this point: m_alt is set, m_libPin is nullptr, m_type is PT_INHERIT
|
||||
BOOST_CHECK_EQUAL( rawPin->GetAlt(), "8.pow" );
|
||||
BOOST_CHECK( rawPin->GetLibPin() == nullptr );
|
||||
|
||||
// GetType() with m_alt set but m_libPin=nullptr should return PT_UNSPECIFIED
|
||||
// per the code in GetType()
|
||||
BOOST_CHECK_MESSAGE( rawPin->GetType() == ELECTRICAL_PINTYPE::PT_UNSPECIFIED,
|
||||
"GetType() with m_alt set but m_libPin=nullptr should return PT_UNSPECIFIED" );
|
||||
|
||||
// GetShownName() should still return the alternate name
|
||||
BOOST_CHECK_EQUAL( rawPin->GetShownName(), "8.pow" );
|
||||
|
||||
// Now set the library symbol which triggers UpdatePins()
|
||||
symbol->SetLibSymbol( new LIB_SYMBOL( *libSymbol ) );
|
||||
|
||||
// After UpdatePins(), pin should have correct type
|
||||
std::vector<SCH_PIN*> schPins = symbol->GetPins( &path );
|
||||
BOOST_CHECK_EQUAL( schPins.size(), 1 );
|
||||
|
||||
if( !schPins.empty() )
|
||||
{
|
||||
SCH_PIN* schPin = schPins[0];
|
||||
BOOST_CHECK_EQUAL( schPin->GetAlt(), "8.pow" );
|
||||
BOOST_CHECK( schPin->GetLibPin() != nullptr );
|
||||
BOOST_CHECK_MESSAGE( schPin->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN,
|
||||
"After SetLibSymbol, GetType() should return PT_POWER_IN" );
|
||||
}
|
||||
|
||||
delete symbol;
|
||||
delete libSymbol;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test for issue #22566 - changing to a symbol with fewer pins should not crash
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user