Allow recursion up the sheet hierarchy for text variable resolution.

Fixes https://gitlab.com/kicad/code/kicad/issues/11953
This commit is contained in:
Jeff Young 2022-09-09 22:48:13 +01:00
parent 4f5998ee6b
commit 59f546ced0
3 changed files with 71 additions and 43 deletions

View File

@ -25,6 +25,7 @@
#include <richio.h>
#include <common.h>
#include <title_block.h>
#include <core/kicad_algo.h>
void TITLE_BLOCK::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControlBits ) const
{
@ -72,19 +73,22 @@ void TITLE_BLOCK::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aCont
void TITLE_BLOCK::GetContextualTextVars( wxArrayString* aVars )
{
aVars->push_back( wxT( "ISSUE_DATE" ) );
aVars->push_back( wxT( "REVISION" ) );
aVars->push_back( wxT( "TITLE" ) );
aVars->push_back( wxT( "COMPANY" ) );
aVars->push_back( wxT( "COMMENT1" ) );
aVars->push_back( wxT( "COMMENT2" ) );
aVars->push_back( wxT( "COMMENT3" ) );
aVars->push_back( wxT( "COMMENT4" ) );
aVars->push_back( wxT( "COMMENT5" ) );
aVars->push_back( wxT( "COMMENT6" ) );
aVars->push_back( wxT( "COMMENT7" ) );
aVars->push_back( wxT( "COMMENT8" ) );
aVars->push_back( wxT( "COMMENT9" ) );
if( !alg::contains( *aVars, wxT( "ISSUE_DATE" ) ) )
{
aVars->push_back( wxT( "ISSUE_DATE" ) );
aVars->push_back( wxT( "REVISION" ) );
aVars->push_back( wxT( "TITLE" ) );
aVars->push_back( wxT( "COMPANY" ) );
aVars->push_back( wxT( "COMMENT1" ) );
aVars->push_back( wxT( "COMMENT2" ) );
aVars->push_back( wxT( "COMMENT3" ) );
aVars->push_back( wxT( "COMMENT4" ) );
aVars->push_back( wxT( "COMMENT5" ) );
aVars->push_back( wxT( "COMMENT6" ) );
aVars->push_back( wxT( "COMMENT7" ) );
aVars->push_back( wxT( "COMMENT8" ) );
aVars->push_back( wxT( "COMMENT9" ) );
}
}

View File

@ -27,6 +27,7 @@
#include <bitmaps.h>
#include <core/mirror.h>
#include <core/kicad_algo.h>
#include <sch_draw_panel.h>
#include <trigo.h>
#include <sch_edit_frame.h>
@ -199,15 +200,31 @@ bool SCH_SHEET::IsRootSheet() const
void SCH_SHEET::GetContextualTextVars( wxArrayString* aVars ) const
{
auto add =
[&]( const wxString& aVar )
{
if( !alg::contains( *aVars, aVar ) )
aVars->push_back( aVar );
};
for( int i = 0; i < SHEET_MANDATORY_FIELDS; ++i )
aVars->push_back( m_fields[i].GetCanonicalName().Upper() );
add( m_fields[i].GetCanonicalName().Upper() );
for( size_t i = SHEET_MANDATORY_FIELDS; i < m_fields.size(); ++i )
aVars->push_back( m_fields[i].GetName() );
add( m_fields[i].GetName() );
SCH_SHEET_PATH sheetPath = findSelf();
if( sheetPath.size() >= 2 )
{
sheetPath.pop_back();
sheetPath.Last()->GetContextualTextVars( aVars );
}
add( wxT( "#" ) );
add( wxT( "##" ) );
add( wxT( "SHEETPATH" ) );
aVars->push_back( wxT( "#" ) );
aVars->push_back( wxT( "##" ) );
aVars->push_back( wxT( "SHEETPATH" ) );
m_screen->GetTitleBlock().GetContextualTextVars( aVars );
}
@ -243,14 +260,8 @@ bool SCH_SHEET::ResolveTextVar( wxString* token, int aDepth ) const
if( token->IsSameAs( wxT( "#" ) ) )
{
for( const SCH_SHEET_PATH& sheet : Schematic()->GetSheets() )
{
if( sheet.Last() == this ) // Current sheet path found
{
*token = wxString::Format( "%s", sheet.GetPageNumber() );
return true;
}
}
*token = wxString::Format( "%s", findSelf().GetPageNumber() );
return true;
}
else if( token->IsSameAs( wxT( "##" ) ) )
{
@ -260,9 +271,23 @@ bool SCH_SHEET::ResolveTextVar( wxString* token, int aDepth ) const
}
else if( token->IsSameAs( wxT( "SHEETPATH" ) ) )
{
*token = Schematic()->CurrentSheet().PathHumanReadable();
*token = findSelf().PathHumanReadable();
return true;
}
else
{
// See if any of the sheets up the hierarchy can resolve it:
SCH_SHEET_PATH sheetPath = findSelf();
if( sheetPath.size() >= 2 )
{
sheetPath.pop_back();
if( sheetPath.Last()->ResolveTextVar( token, aDepth ) )
return true;
}
}
return false;
}
@ -908,20 +933,21 @@ void SCH_SHEET::renumberPins()
}
SCH_SHEET_PATH SCH_SHEET::getSheetPath() const
SCH_SHEET_PATH SCH_SHEET::findSelf() const
{
SCH_SCREEN* parentScreen = static_cast<SCH_SCREEN*>( m_parent );
size_t vPageNumParent = parentScreen->GetVirtualPageNumber();
SCH_SHEET_LIST sheets = parentScreen->Schematic()->GetSheets();
wxCHECK_MSG( Schematic(), SCH_SHEET_PATH(), "Can't call findSelf without a schematic" );
// We can use the virtual page number as an index to find the instance
size_t parentIdx = std::max<size_t>( 0, std::min( sheets.size(), vPageNumParent ) - 1 );
SCH_SHEET_PATH sheetPath = sheets.at( parentIdx );
SCH_SHEET_PATH sheetPath = Schematic()->CurrentSheet();
// Make sure our asumption about the virtual page number being the index-1 is correct
wxASSERT( sheetPath.LastScreen()->GetFileName() == parentScreen->GetFileName() );
while( !sheetPath.empty() && sheetPath.Last() != this )
sheetPath.pop_back();
sheetPath.push_back( const_cast<SCH_SHEET*>( this ) );
if( sheetPath.empty() )
{
// If we weren't in the hierarchy, then we must be a child of the current sheet.
sheetPath = Schematic()->CurrentSheet();
sheetPath.push_back( const_cast<SCH_SHEET*>( this ) );
}
return sheetPath;
}
@ -1077,7 +1103,7 @@ void SCH_SHEET::Plot( PLOTTER* aPlotter, bool aBackground ) const
// Make the sheet object a clickable hyperlink (e.g. for PDF plotter)
std::vector<wxString> properties;
properties.emplace_back( EDA_TEXT::GotoPageHref( GetPageNumber( getSheetPath() ) ) );
properties.emplace_back( EDA_TEXT::GotoPageHref( GetPageNumber( findSelf() ) ) );
for( const SCH_FIELD& field : GetFields() )
{

View File

@ -451,12 +451,10 @@ protected:
void renumberPins();
/**
* Guess the sheet path of this sheet based on the virtual page number currently set
* on the parent screen. (Useful helper function for plotting)
*
* @return the instance corresponding to this sheet
* Get the sheetpath of this sheet. NB: REQUIRES that the current sheet hierarchy contains
* the given sheet.
*/
SCH_SHEET_PATH getSheetPath() const;
SCH_SHEET_PATH findSelf() const;
private:
bool doIsConnected( const VECTOR2I& aPosition ) const override;