Rewrite intersheet refs resolution to be sheet-path aware.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/17533
This commit is contained in:
Jeff Young 2024-03-23 16:50:00 +00:00
parent fc572bfbc6
commit a6e2746a08
6 changed files with 40 additions and 45 deletions

View File

@ -351,13 +351,14 @@ SCH_FIELD::GetRenderCache( const wxString& forResolvedText, const VECTOR2I& forP
void SCH_FIELD::Print( const RENDER_SETTINGS* aSettings, const VECTOR2I& aOffset ) void SCH_FIELD::Print( const RENDER_SETTINGS* aSettings, const VECTOR2I& aOffset )
{ {
wxDC* DC = aSettings->GetPrintDC(); SCH_SHEET_PATH* sheet = &Schematic()->CurrentSheet();
COLOR4D color = aSettings->GetLayerColor( IsForceVisible() ? LAYER_HIDDEN : m_layer ); wxDC* DC = aSettings->GetPrintDC();
bool blackAndWhiteMode = GetGRForceBlackPenState(); COLOR4D color = aSettings->GetLayerColor( IsForceVisible() ? LAYER_HIDDEN : m_layer );
VECTOR2I textpos; bool blackAndWhiteMode = GetGRForceBlackPenState();
int penWidth = GetEffectiveTextPenWidth( aSettings->GetDefaultPenWidth() ); VECTOR2I textpos;
int penWidth = GetEffectiveTextPenWidth( aSettings->GetDefaultPenWidth() );
if( ( !IsVisible() && !IsForceVisible() ) || GetShownText( true ).IsEmpty() ) if( ( !IsVisible() && !IsForceVisible() ) || GetShownText( sheet, true ).IsEmpty() )
return; return;
COLOR4D bg = aSettings->GetBackgroundColor(); COLOR4D bg = aSettings->GetBackgroundColor();
@ -416,7 +417,7 @@ void SCH_FIELD::Print( const RENDER_SETTINGS* aSettings, const VECTOR2I& aOffset
textpos += label->GetSchematicTextOffset( aSettings ); textpos += label->GetSchematicTextOffset( aSettings );
} }
GRPrintText( DC, textpos, color, GetShownText( true ), orient, GetTextSize(), GRPrintText( DC, textpos, color, GetShownText( sheet, true ), orient, GetTextSize(),
GR_TEXT_H_ALIGN_CENTER, GR_TEXT_V_ALIGN_CENTER, penWidth, IsItalic(), IsBold(), GR_TEXT_H_ALIGN_CENTER, GR_TEXT_V_ALIGN_CENTER, penWidth, IsItalic(), IsBold(),
font, GetFontMetrics() ); font, GetFontMetrics() );
} }
@ -950,12 +951,14 @@ void SCH_FIELD::DoHypertextAction( EDA_DRAW_FRAME* aFrame ) const
if( IsHypertext() ) if( IsHypertext() )
{ {
SCH_LABEL_BASE* label = static_cast<SCH_LABEL_BASE*>( m_parent ); SCH_LABEL_BASE* label = static_cast<SCH_LABEL_BASE*>( m_parent );
std::vector<std::pair<wxString, wxString>> pages; SCH_SHEET_PATH* sheet = &label->Schematic()->CurrentSheet();
wxMenu menu; wxMenu menu;
wxString href; wxString href;
label->GetIntersheetRefs( &pages ); std::vector<std::pair<wxString, wxString>> pages;
label->GetIntersheetRefs( sheet, &pages );
for( int i = 0; i < (int) pages.size(); ++i ) for( int i = 0; i < (int) pages.size(); ++i )
{ {
@ -1148,7 +1151,9 @@ bool SCH_FIELD::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) co
void SCH_FIELD::Plot( PLOTTER* aPlotter, bool aBackground, void SCH_FIELD::Plot( PLOTTER* aPlotter, bool aBackground,
const SCH_PLOT_SETTINGS& aPlotSettings ) const const SCH_PLOT_SETTINGS& aPlotSettings ) const
{ {
if( GetShownText( true ).IsEmpty() || aBackground ) SCH_SHEET_PATH* sheet = &Schematic()->CurrentSheet();
if( GetShownText( sheet, true ).IsEmpty() || aBackground )
return; return;
RENDER_SETTINGS* settings = aPlotter->RenderSettings(); RENDER_SETTINGS* settings = aPlotter->RenderSettings();
@ -1228,7 +1233,7 @@ void SCH_FIELD::Plot( PLOTTER* aPlotter, bool aBackground,
attrs.m_Angle = orient; attrs.m_Angle = orient;
attrs.m_Multiline = false; attrs.m_Multiline = false;
aPlotter->PlotText( textpos, color, GetShownText( true ), attrs, font, GetFontMetrics() ); aPlotter->PlotText( textpos, color, GetShownText( sheet, true ), attrs, font, GetFontMetrics() );
if( IsHypertext() ) if( IsHypertext() )
{ {
@ -1239,7 +1244,7 @@ void SCH_FIELD::Plot( PLOTTER* aPlotter, bool aBackground,
wxCHECK( label, /* void */ ); wxCHECK( label, /* void */ );
label->GetIntersheetRefs( &pages ); label->GetIntersheetRefs( sheet, &pages );
for( const std::pair<wxString, wxString>& page : pages ) for( const std::pair<wxString, wxString>& page : pages )
pageHrefs.push_back( wxT( "#" ) + page.first ); pageHrefs.push_back( wxT( "#" ) + page.first );

View File

@ -706,13 +706,15 @@ void SCH_LABEL_BASE::AutoplaceFields( SCH_SCREEN* aScreen, bool aManual )
} }
void SCH_LABEL_BASE::GetIntersheetRefs( std::vector<std::pair<wxString, wxString>>* pages ) void SCH_LABEL_BASE::GetIntersheetRefs( const SCH_SHEET_PATH* aPath,
std::vector<std::pair<wxString, wxString>>* pages )
{ {
wxCHECK( pages, /* void */ ); wxCHECK( pages, /* void */ );
if( Schematic() ) if( Schematic() )
{ {
auto it = Schematic()->GetPageRefsMap().find( GetText() ); wxString resolvedLabel = GetShownText( &Schematic()->CurrentSheet(), false );
auto it = Schematic()->GetPageRefsMap().find( resolvedLabel );
if( it != Schematic()->GetPageRefsMap().end() ) if( it != Schematic()->GetPageRefsMap().end() )
{ {
@ -1308,6 +1310,7 @@ void SCH_LABEL_BASE::Plot( PLOTTER* aPlotter, bool aBackground,
{ {
static std::vector<VECTOR2I> s_poly; static std::vector<VECTOR2I> s_poly;
SCH_SHEET_PATH* sheet = &Schematic()->CurrentSheet();
RENDER_SETTINGS* settings = aPlotter->RenderSettings(); RENDER_SETTINGS* settings = aPlotter->RenderSettings();
SCH_CONNECTION* connection = Connection(); SCH_CONNECTION* connection = Connection();
int layer = ( connection && connection->IsBus() ) ? LAYER_BUS : m_layer; int layer = ( connection && connection->IsBus() ) ? LAYER_BUS : m_layer;
@ -1338,7 +1341,8 @@ void SCH_LABEL_BASE::Plot( PLOTTER* aPlotter, bool aBackground,
} }
else else
{ {
aPlotter->PlotText( textpos, color, GetShownText( true ), attrs, font, GetFontMetrics() ); aPlotter->PlotText( textpos, color, GetShownText( sheet, true ), attrs, font,
GetFontMetrics() );
if( GetShape() == LABEL_FLAG_SHAPE::F_DOT ) if( GetShape() == LABEL_FLAG_SHAPE::F_DOT )
{ {
@ -1840,7 +1844,7 @@ bool SCH_GLOBALLABEL::ResolveTextVar( const SCH_SHEET_PATH* aPath, wxString* tok
{ {
SCHEMATIC_SETTINGS& settings = schematic->Settings(); SCHEMATIC_SETTINGS& settings = schematic->Settings();
wxString ref; wxString ref;
auto it = schematic->GetPageRefsMap().find( GetText() ); auto it = schematic->GetPageRefsMap().find( GetShownText( aPath ) );
if( it == schematic->GetPageRefsMap().end() ) if( it == schematic->GetPageRefsMap().end() )
{ {

View File

@ -238,7 +238,8 @@ public:
* Builds an array of { pageNumber, pageName } pairs. * Builds an array of { pageNumber, pageName } pairs.
* @param pages [out] Array of { pageNumber, pageName } pairs. * @param pages [out] Array of { pageNumber, pageName } pairs.
*/ */
void GetIntersheetRefs( std::vector<std::pair<wxString, wxString>>* pages ); void GetIntersheetRefs( const SCH_SHEET_PATH* aPath,
std::vector<std::pair<wxString, wxString>>* pages );
/** /**
* Return the list of system text vars & fields for this label. * Return the list of system text vars & fields for this label.

View File

@ -342,6 +342,7 @@ void SCH_TEXT::Plot( PLOTTER* aPlotter, bool aBackground,
if( aBackground ) if( aBackground )
return; return;
SCH_SHEET_PATH* sheet = &Schematic()->CurrentSheet();
RENDER_SETTINGS* settings = aPlotter->RenderSettings(); RENDER_SETTINGS* settings = aPlotter->RenderSettings();
SCH_CONNECTION* connection = Connection(); SCH_CONNECTION* connection = Connection();
int layer = ( connection && connection->IsBus() ) ? LAYER_BUS : m_layer; int layer = ( connection && connection->IsBus() ) ? LAYER_BUS : m_layer;
@ -375,7 +376,7 @@ void SCH_TEXT::Plot( PLOTTER* aPlotter, bool aBackground,
std::vector<VECTOR2I> positions; std::vector<VECTOR2I> positions;
wxArrayString strings_list; wxArrayString strings_list;
wxStringSplit( GetShownText( true ), strings_list, '\n' ); wxStringSplit( GetShownText( sheet, true ), strings_list, '\n' );
positions.reserve( strings_list.Count() ); positions.reserve( strings_list.Count() );
GetLinePositions( positions, (int) strings_list.Count() ); GetLinePositions( positions, (int) strings_list.Count() );

View File

@ -419,6 +419,7 @@ void SCH_TEXTBOX::Plot( PLOTTER* aPlotter, bool aBackground,
return; return;
} }
SCH_SHEET_PATH* sheet = &Schematic()->CurrentSheet();
RENDER_SETTINGS* settings = aPlotter->RenderSettings(); RENDER_SETTINGS* settings = aPlotter->RenderSettings();
int penWidth = GetPenWidth(); int penWidth = GetPenWidth();
COLOR4D color = GetStroke().GetColor(); COLOR4D color = GetStroke().GetColor();
@ -456,7 +457,7 @@ void SCH_TEXTBOX::Plot( PLOTTER* aPlotter, bool aBackground,
std::vector<VECTOR2I> positions; std::vector<VECTOR2I> positions;
wxArrayString strings_list; wxArrayString strings_list;
wxStringSplit( GetShownText( true ), strings_list, '\n' ); wxStringSplit( GetShownText( sheet, true ), strings_list, '\n' );
positions.reserve( strings_list.Count() ); positions.reserve( strings_list.Count() );
GetLinePositions( positions, (int) strings_list.Count() ); GetLinePositions( positions, (int) strings_list.Count() );

View File

@ -659,37 +659,20 @@ void SCHEMATIC::RecomputeIntersheetRefs( const std::function<void( SCH_GLOBALLAB
pageRefsMap.clear(); pageRefsMap.clear();
SCH_SCREENS screens( Root() ); for( const SCH_SHEET_PATH& sheet : GetSheets() )
std::vector<int> virtualPageNumbers;
/* Iterate over screens */
for( SCH_SCREEN* screen = screens.GetFirst(); screen != nullptr; screen = screens.GetNext() )
{ {
virtualPageNumbers.clear(); for( SCH_ITEM* item : sheet.LastScreen()->Items().OfType( SCH_GLOBAL_LABEL_T ) )
/* Find in which sheets this screen is used */
for( const SCH_SHEET_PATH& sheet : GetSheets() )
{ {
if( sheet.LastScreen() == screen ) SCH_GLOBALLABEL* global = static_cast<SCH_GLOBALLABEL*>( item );
virtualPageNumbers.push_back( sheet.GetVirtualPageNumber() ); wxString resolvedLabel = global->GetShownText( &sheet, false );
}
for( SCH_ITEM* item : screen->Items() ) pageRefsMap[ resolvedLabel ].insert( sheet.GetVirtualPageNumber() );
{
if( item->Type() == SCH_GLOBAL_LABEL_T )
{
SCH_GLOBALLABEL* globalLabel = static_cast<SCH_GLOBALLABEL*>( item );
std::set<int>& virtualpageList = pageRefsMap[globalLabel->GetText()];
for( const int& pageNo : virtualPageNumbers )
virtualpageList.insert( pageNo );
}
} }
} }
bool show = Settings().m_IntersheetRefsShow; bool show = Settings().m_IntersheetRefsShow;
// Refresh all global labels. Note that we have to collect them first as the // Refresh all visible global labels. Note that we have to collect them first as the
// SCH_SCREEN::Update() call is going to invalidate the RTree iterator. // SCH_SCREEN::Update() call is going to invalidate the RTree iterator.
std::vector<SCH_GLOBALLABEL*> currentSheetGlobalLabels; std::vector<SCH_GLOBALLABEL*> currentSheetGlobalLabels;