Simplify and regularize text variable substitution architecture.

EDA_ITEMs are responsible for giving their parent a crack at it if
they failed to resolve it.  This recurses all the way up to the schematic/
board, and then to the project.

Cross-reference handling is also move to the EDA_ITEMs.  It must be done
before bubbling up so that we don't end up in loops.  (The aDepth parameter
will break the loop, but without having done anything useful.)

Fixes https://gitlab.com/kicad/code/kicad/issues/13541
This commit is contained in:
Jeff Young 2023-01-17 16:54:08 +00:00
parent 9820062c71
commit 26c821962f
23 changed files with 145 additions and 258 deletions

View File

@ -3,7 +3,7 @@
* *
* Copyright (C) 2014-2020 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2014-2020 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com> * Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -56,14 +56,18 @@ enum Bracket
wxString ExpandTextVars( const wxString& aSource, const PROJECT* aProject ) wxString ExpandTextVars( const wxString& aSource, const PROJECT* aProject )
{ {
return ExpandTextVars( aSource, nullptr, nullptr, aProject ); std::function<bool( wxString* )> projectResolver =
[&]( wxString* token ) -> bool
{
return aProject->TextVarResolver( token );
};
return ExpandTextVars( aSource, &projectResolver );
} }
wxString ExpandTextVars( const wxString& aSource, wxString ExpandTextVars( const wxString& aSource,
const std::function<bool( wxString* )>* aLocalResolver, const std::function<bool( wxString* )>* aResolver )
const std::function<bool( wxString* )>* aFallbackResolver,
const PROJECT* aProject )
{ {
wxString newbuf; wxString newbuf;
size_t sourceLen = aSource.length(); size_t sourceLen = aSource.length();
@ -87,15 +91,7 @@ wxString ExpandTextVars( const wxString& aSource,
if( token.IsEmpty() ) if( token.IsEmpty() )
continue; continue;
if( aLocalResolver && (*aLocalResolver)( &token ) ) if( aResolver && (*aResolver)( &token ) )
{
newbuf.append( token );
}
else if( aProject && aProject->TextVarResolver( &token ) )
{
newbuf.append( token );
}
else if( aFallbackResolver && (*aFallbackResolver)( &token ) )
{ {
newbuf.append( token ); newbuf.append( token );
} }

View File

@ -1,7 +1,7 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
* *
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@ -182,10 +182,13 @@ wxString DS_DRAW_ITEM_LIST::BuildFullText( const wxString& aTextbase )
return true; return true;
} }
if( m_project && m_project->TextVarResolver( token ) )
return true;
return false; return false;
}; };
return ExpandTextVars( aTextbase, &wsResolver, nullptr, m_project ); return ExpandTextVars( aTextbase, &wsResolver );
} }

View File

@ -4,7 +4,7 @@
* Copyright (C) 1992-2018 Jean-Pierre Charras jp.charras at wanadoo.fr * Copyright (C) 1992-2018 Jean-Pierre Charras jp.charras at wanadoo.fr
* Copyright (C) 1992-2010 Lorenzo Marcantonio * Copyright (C) 1992-2010 Lorenzo Marcantonio
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@gmail.com> * Copyright (C) 2011 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -418,7 +418,7 @@ wxString DIALOG_PLOT_SCHEMATIC::getOutputPath()
}; };
wxString path = m_outputDirectoryName->GetValue(); wxString path = m_outputDirectoryName->GetValue();
path = ExpandTextVars( path, &textResolver, nullptr, &Prj() ); path = ExpandTextVars( path, &textResolver );
path = ExpandEnvVarSubstitutions( path, &Prj() ); path = ExpandEnvVarSubstitutions( path, &Prj() );
fn.SetPath( path ); fn.SetPath( path );

View File

@ -177,43 +177,21 @@ wxString SCH_FIELD::GetShownText( int aDepth, bool aAllowExtraText ) const
std::function<bool( wxString* )> symbolResolver = std::function<bool( wxString* )> symbolResolver =
[&]( wxString* token ) -> bool [&]( wxString* token ) -> bool
{ {
if( token->Contains( ':' ) ) return static_cast<SCH_SYMBOL*>( m_parent )->ResolveTextVar( token, aDepth + 1 );
{
if( Schematic()->ResolveCrossReference( token, aDepth ) )
return true;
}
else
{
SCH_SYMBOL* parentSymbol = static_cast<SCH_SYMBOL*>( m_parent );
if( parentSymbol->ResolveTextVar( token, aDepth + 1 ) )
return true;
SCHEMATIC* schematic = parentSymbol->Schematic();
SCH_SHEET* sheet = schematic ? schematic->CurrentSheet().Last() : nullptr;
if( sheet && sheet->ResolveTextVar( token, aDepth + 1 ) )
return true;
}
return false;
}; };
std::function<bool( wxString* )> sheetResolver = std::function<bool( wxString* )> sheetResolver =
[&]( wxString* token ) -> bool [&]( wxString* token ) -> bool
{ {
SCH_SHEET* sheet = static_cast<SCH_SHEET*>( m_parent ); return static_cast<SCH_SHEET*>( m_parent )->ResolveTextVar( token, aDepth + 1 );
return sheet->ResolveTextVar( token, aDepth + 1 );
}; };
std::function<bool( wxString* )> labelResolver = std::function<bool( wxString* )> labelResolver =
[&]( wxString* token ) -> bool [&]( wxString* token ) -> bool
{ {
SCH_LABEL_BASE* label = static_cast<SCH_LABEL_BASE*>( m_parent ); return static_cast<SCH_LABEL_BASE*>( m_parent )->ResolveTextVar( token, aDepth + 1 );
return label->ResolveTextVar( token, aDepth + 1 );
}; };
PROJECT* project = nullptr;
wxString text = EDA_TEXT::GetShownText(); wxString text = EDA_TEXT::GetShownText();
if( IsNameShown() ) if( IsNameShown() )
@ -225,19 +203,16 @@ wxString SCH_FIELD::GetShownText( int aDepth, bool aAllowExtraText ) const
} }
else if( HasTextVars() ) else if( HasTextVars() )
{ {
if( Schematic() )
project = &Schematic()->Prj();
if( aDepth < 10 ) if( aDepth < 10 )
{ {
if( m_parent && m_parent->Type() == SCH_SYMBOL_T ) if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
text = ExpandTextVars( text, &symbolResolver, nullptr, project ); text = ExpandTextVars( text, &symbolResolver );
else if( m_parent && m_parent->Type() == SCH_SHEET_T ) else if( m_parent && m_parent->Type() == SCH_SHEET_T )
text = ExpandTextVars( text, &sheetResolver, nullptr, project ); text = ExpandTextVars( text, &sheetResolver );
else if( m_parent && m_parent->IsType( { SCH_LABEL_LOCATE_ANY_T } ) ) else if( m_parent && m_parent->IsType( { SCH_LABEL_LOCATE_ANY_T } ) )
text = ExpandTextVars( text, &labelResolver, nullptr, project ); text = ExpandTextVars( text, &labelResolver );
else else if( Schematic() )
text = ExpandTextVars( text, project ); text = ExpandTextVars( text, &Schematic()->Prj() );
} }
} }

View File

@ -3,7 +3,7 @@
* *
* Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2015 Wayne Stambaugh <stambaughw@gmail.com> * Copyright (C) 2015 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -480,13 +480,13 @@ void SCH_LABEL_BASE::GetIntersheetRefs( std::vector<std::pair<wxString, wxString
bool SCH_LABEL_BASE::ResolveTextVar( wxString* token, int aDepth ) const bool SCH_LABEL_BASE::ResolveTextVar( wxString* token, int aDepth ) const
{
if( token->Contains( ':' ) )
{ {
if( !Schematic() ) if( !Schematic() )
return false; return false;
if( Schematic()->ResolveCrossReference( token, aDepth ) ) if( token->Contains( ':' ) )
{
if( Schematic()->ResolveCrossReference( token, aDepth + 1 ) )
return true; return true;
} }
@ -537,21 +537,20 @@ bool SCH_LABEL_BASE::ResolveTextVar( wxString* token, int aDepth ) const
} }
} }
// See if parent can resolve it (these will recurse to ancestors)
if( Type() == SCH_SHEET_PIN_T && m_parent ) if( Type() == SCH_SHEET_PIN_T && m_parent )
{ {
SCH_SHEET* sheet = static_cast<SCH_SHEET*>( m_parent ); SCH_SHEET* sheet = static_cast<SCH_SHEET*>( m_parent );
if( sheet->ResolveTextVar( token, aDepth ) ) if( sheet->ResolveTextVar( token, aDepth + 1 ) )
return true; return true;
} }
else if( Schematic() ) else if( SCH_SHEET* sheet = Schematic()->CurrentSheet().Last() )
{ {
if( SCH_SHEET* sheet = Schematic()->CurrentSheet().Last() ) if( sheet->ResolveTextVar( token, aDepth + 1 ) )
{
if( sheet->ResolveTextVar( token, aDepth ) )
return true; return true;
} }
}
return false; return false;
} }
@ -565,12 +564,6 @@ wxString SCH_LABEL_BASE::GetShownText( int aDepth, bool aAllowExtraText ) const
return ResolveTextVar( token, aDepth ); return ResolveTextVar( token, aDepth );
}; };
std::function<bool( wxString* )> schematicTextResolver =
[&]( wxString* token ) -> bool
{
return Schematic()->ResolveTextVar( token, aDepth + 1 );
};
wxString text = EDA_TEXT::GetShownText(); wxString text = EDA_TEXT::GetShownText();
if( text == wxS( "~" ) ) // Legacy placeholder for empty string if( text == wxS( "~" ) ) // Legacy placeholder for empty string
@ -579,13 +572,8 @@ wxString SCH_LABEL_BASE::GetShownText( int aDepth, bool aAllowExtraText ) const
} }
else if( HasTextVars() ) else if( HasTextVars() )
{ {
PROJECT* project = nullptr;
if( Schematic() )
project = &Schematic()->Prj();
if( aDepth < 10 ) if( aDepth < 10 )
text = ExpandTextVars( text, &textResolver, &schematicTextResolver, project ); text = ExpandTextVars( text, &textResolver );
} }
return text; return text;

View File

@ -2186,40 +2186,15 @@ static void orientSymbol( LIB_SYMBOL* symbol, int orientation )
} }
wxString resolveTextVars( const wxString& aSourceText, const SCH_SYMBOL* aSymbolContext ) wxString expandLibItemTextVars( const wxString& aSourceText, const SCH_SYMBOL* aSymbolContext )
{ {
std::function<bool( wxString* )> symbolResolver = std::function<bool( wxString* )> symbolResolver =
[&]( wxString* token ) -> bool [&]( wxString* token ) -> bool
{ {
if( token->Contains( ':' ) ) return aSymbolContext->ResolveTextVar( token, 0 );
{
if( aSymbolContext->Schematic()->ResolveCrossReference( token, 0 ) )
return true;
}
else
{
if( aSymbolContext->ResolveTextVar( token, 0 ) )
return true;
SCHEMATIC* schematic = aSymbolContext->Schematic();
SCH_SHEET* sheet = schematic ? schematic->CurrentSheet().Last() : nullptr;
if( sheet && sheet->ResolveTextVar( token, 0 ) )
return true;
}
return false;
}; };
PROJECT* project = nullptr; return ExpandTextVars( aSourceText, &symbolResolver );
wxString text = aSourceText;
if( aSymbolContext->Schematic() )
project = &aSymbolContext->Schematic()->Prj();
text = ExpandTextVars( text, &symbolResolver, nullptr, project );
return text;
} }
@ -2270,14 +2245,14 @@ void SCH_PAINTER::draw( const SCH_SYMBOL* aSymbol, int aLayer )
LIB_TEXT* textItem = static_cast<LIB_TEXT*>( &tempItem ); LIB_TEXT* textItem = static_cast<LIB_TEXT*>( &tempItem );
if( textItem->HasTextVars() ) if( textItem->HasTextVars() )
textItem->SetText( resolveTextVars( textItem->GetText(), aSymbol ) ); textItem->SetText( expandLibItemTextVars( textItem->GetText(), aSymbol ) );
} }
else if( tempItem.Type() == LIB_TEXTBOX_T ) else if( tempItem.Type() == LIB_TEXTBOX_T )
{ {
LIB_TEXTBOX* textboxItem = static_cast<LIB_TEXTBOX*>( &tempItem ); LIB_TEXTBOX* textboxItem = static_cast<LIB_TEXTBOX*>( &tempItem );
if( textboxItem->HasTextVars() ) if( textboxItem->HasTextVars() )
textboxItem->SetText( resolveTextVars( textboxItem->GetText(), aSymbol ) ); textboxItem->SetText( expandLibItemTextVars( textboxItem->GetText(), aSymbol ) );
} }
} }

View File

@ -232,6 +232,15 @@ void SCH_SHEET::GetContextualTextVars( wxArrayString* aVars ) const
bool SCH_SHEET::ResolveTextVar( wxString* token, int aDepth ) const bool SCH_SHEET::ResolveTextVar( wxString* token, int aDepth ) const
{ {
if( !Schematic() )
return false;
if( token->Contains( ':' ) )
{
if( Schematic()->ResolveCrossReference( token, aDepth + 1 ) )
return true;
}
for( int i = 0; i < SHEET_MANDATORY_FIELDS; ++i ) for( int i = 0; i < SHEET_MANDATORY_FIELDS; ++i )
{ {
if( token->IsSameAs( m_fields[i].GetCanonicalName().Upper() ) ) if( token->IsSameAs( m_fields[i].GetCanonicalName().Upper() ) )
@ -275,9 +284,8 @@ bool SCH_SHEET::ResolveTextVar( wxString* token, int aDepth ) const
*token = findSelf().PathHumanReadable(); *token = findSelf().PathHumanReadable();
return true; return true;
} }
else
{ // See if parent can resolve it (these will recurse to ancestors)
// See if any of the sheets up the hierarchy can resolve it:
SCH_SHEET_PATH sheetPath = findSelf(); SCH_SHEET_PATH sheetPath = findSelf();
@ -285,9 +293,13 @@ bool SCH_SHEET::ResolveTextVar( wxString* token, int aDepth ) const
{ {
sheetPath.pop_back(); sheetPath.pop_back();
if( sheetPath.Last()->ResolveTextVar( token, aDepth ) ) if( sheetPath.Last()->ResolveTextVar( token, aDepth + 1 ) )
return true; return true;
} }
else
{
if( Schematic()->ResolveTextVar( token, aDepth + 1 ) )
return true;
} }
return false; return false;

View File

@ -1138,6 +1138,12 @@ bool SCH_SYMBOL::ResolveTextVar( wxString* token, int aDepth ) const
if( !schematic ) if( !schematic )
return false; return false;
if( token->Contains( ':' ) )
{
if( schematic->ResolveCrossReference( token, aDepth + 1 ) )
return true;
}
for( int i = 0; i < MANDATORY_FIELDS; ++i ) for( int i = 0; i < MANDATORY_FIELDS; ++i )
{ {
if( token->IsSameAs( m_fields[ i ].GetCanonicalName().Upper() ) ) if( token->IsSameAs( m_fields[ i ].GetCanonicalName().Upper() ) )
@ -1245,6 +1251,14 @@ bool SCH_SYMBOL::ResolveTextVar( wxString* token, int aDepth ) const
return true; return true;
} }
// See if parent can resolve it (this will recurse to ancestors)
if( SCH_SHEET* sheet = schematic->CurrentSheet().Last() )
{
if( sheet->ResolveTextVar( token, aDepth + 1 ) )
return true;
}
return false; return false;
} }

View File

@ -3,7 +3,7 @@
* *
* Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2015 Wayne Stambaugh <stambaughw@gmail.com> * Copyright (C) 2015 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -344,29 +344,15 @@ wxString SCH_TEXT::GetShownText( int aDepth, bool aAllowExtraText ) const
std::function<bool( wxString* )> textResolver = std::function<bool( wxString* )> textResolver =
[&]( wxString* token ) -> bool [&]( wxString* token ) -> bool
{ {
if( token->Contains( ':' ) ) if( SCH_SHEET* sheet = Schematic()->CurrentSheet().Last() )
{ {
if( Schematic()->ResolveCrossReference( token, aDepth ) ) if( sheet->ResolveTextVar( token, aDepth + 1 ) )
return true;
}
else
{
SCHEMATIC* schematic = Schematic();
SCH_SHEET* sheet = schematic ? schematic->CurrentSheet().Last() : nullptr;
if( sheet && sheet->ResolveTextVar( token, aDepth + 1 ) )
return true; return true;
} }
return false; return false;
}; };
std::function<bool( wxString* )> schematicTextResolver =
[&]( wxString* token ) -> bool
{
return Schematic()->ResolveTextVar( token, aDepth + 1 );
};
wxString text = EDA_TEXT::GetShownText(); wxString text = EDA_TEXT::GetShownText();
if( text == wxS( "~" ) ) // Legacy placeholder for empty string if( text == wxS( "~" ) ) // Legacy placeholder for empty string
@ -375,13 +361,8 @@ wxString SCH_TEXT::GetShownText( int aDepth, bool aAllowExtraText ) const
} }
else if( HasTextVars() ) else if( HasTextVars() )
{ {
PROJECT* project = nullptr;
if( Schematic() )
project = &Schematic()->Prj();
if( aDepth < 10 ) if( aDepth < 10 )
text = ExpandTextVars( text, &textResolver, &schematicTextResolver, project ); text = ExpandTextVars( text, &textResolver );
} }
return text; return text;

View File

@ -283,40 +283,21 @@ wxString SCH_TEXTBOX::GetShownText( int aDepth, bool aAllowExtraText ) const
std::function<bool( wxString* )> textResolver = std::function<bool( wxString* )> textResolver =
[&]( wxString* token ) -> bool [&]( wxString* token ) -> bool
{ {
if( token->Contains( ':' ) ) if( SCH_SHEET* sheet = Schematic()->CurrentSheet().Last() )
{ {
if( Schematic()->ResolveCrossReference( token, aDepth ) ) if( sheet->ResolveTextVar( token, aDepth + 1 ) )
return true;
}
else
{
SCHEMATIC* schematic = Schematic();
SCH_SHEET* sheet = schematic ? schematic->CurrentSheet().Last() : nullptr;
if( sheet && sheet->ResolveTextVar( token, aDepth + 1 ) )
return true; return true;
} }
return false; return false;
}; };
std::function<bool( wxString* )> schematicTextResolver =
[&]( wxString* token ) -> bool
{
return Schematic()->ResolveTextVar( token, aDepth + 1 );
};
wxString text = EDA_TEXT::GetShownText(); wxString text = EDA_TEXT::GetShownText();
if( HasTextVars() ) if( HasTextVars() )
{ {
PROJECT* project = nullptr;
if( Schematic() )
project = &Schematic()->Prj();
if( aDepth < 10 ) if( aDepth < 10 )
text = ExpandTextVars( text, &textResolver, &schematicTextResolver, project ); text = ExpandTextVars( text, &textResolver );
} }
KIFONT::FONT* font = GetFont(); KIFONT::FONT* font = GetFont();

View File

@ -161,6 +161,9 @@ bool SCHEMATIC::ResolveTextVar( wxString* token, int aDepth ) const
return CurrentSheet().LastScreen()->GetTitleBlock().TextVarResolver( token, m_project ); return CurrentSheet().LastScreen()->GetTitleBlock().TextVarResolver( token, m_project );
} }
if( Prj().TextVarResolver( token ) )
return true;
return false; return false;
} }

View File

@ -4,7 +4,7 @@
* Copyright (C) 2014-2020 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2014-2020 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2007-2015 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com> * Copyright (C) 2007-2015 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com> * Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -79,13 +79,10 @@ bool EnsureFileDirectoryExists( wxFileName* aTargetFullFileName,
const wxString ExpandEnvVarSubstitutions( const wxString& aString, const PROJECT* aProject ); const wxString ExpandEnvVarSubstitutions( const wxString& aString, const PROJECT* aProject );
/** /**
* Expand '${var-name}' templates in text. The LocalResolver is given first crack at it, * Expand '${var-name}' templates in text.
* after which the PROJECT's resolver is called.
*/ */
wxString ExpandTextVars( const wxString& aSource, wxString ExpandTextVars( const wxString& aSource,
const std::function<bool( wxString* )>* aLocalResolver, const std::function<bool( wxString* )>* aResolver );
const std::function<bool( wxString* )>* aFallbackResolver,
const PROJECT* aProject );
wxString ExpandTextVars( const wxString& aSource, const PROJECT* aProject ); wxString ExpandTextVars( const wxString& aSource, const PROJECT* aProject );

View File

@ -5,7 +5,7 @@
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com> * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@gmail.com> * Copyright (C) 2011 Wayne Stambaugh <stambaughw@gmail.com>
* *
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -324,6 +324,24 @@ std::vector<PCB_MARKER*> BOARD::ResolveDRCExclusions()
bool BOARD::ResolveTextVar( wxString* token, int aDepth ) const bool BOARD::ResolveTextVar( wxString* token, int aDepth ) const
{ {
if( token->Contains( ':' ) )
{
wxString remainder;
wxString ref = token->BeforeFirst( ':', &remainder );
BOARD_ITEM* refItem = GetItem( KIID( ref ) );
if( refItem && refItem->Type() == PCB_FOOTPRINT_T )
{
FOOTPRINT* refFP = static_cast<FOOTPRINT*>( refItem );
if( refFP->ResolveTextVar( &remainder, aDepth + 1 ) )
{
*token = remainder;
return true;
}
}
}
wxString var = *token; wxString var = *token;
if( GetTitleBlock().TextVarResolver( token, m_project ) ) if( GetTitleBlock().TextVarResolver( token, m_project ) )
@ -336,6 +354,9 @@ bool BOARD::ResolveTextVar( wxString* token, int aDepth ) const
return true; return true;
} }
if( GetProject() && GetProject()->TextVarResolver( token ) )
return true;
return false; return false;
} }

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * 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 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2022-2023 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -259,7 +259,7 @@ void DIALOG_EXPORT_SVG::ExportSVGFile( bool aOnlyOneFile )
}; };
wxString path = m_outputDirectory; wxString path = m_outputDirectory;
path = ExpandTextVars( path, &textResolver, nullptr, nullptr ); path = ExpandTextVars( path, &textResolver );
path = ExpandEnvVarSubstitutions( path, nullptr ); path = ExpandEnvVarSubstitutions( path, nullptr );
wxFileName outputDir = wxFileName::DirName( path ); wxFileName outputDir = wxFileName::DirName( path );

View File

@ -1,7 +1,7 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2022 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2015-2023 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -267,7 +267,7 @@ bool DIALOG_GEN_FOOTPRINT_POSITION::CreateGerberFiles()
}; };
wxString path = m_parent->GetPcbNewSettings()->m_PlaceFile.output_directory; wxString path = m_parent->GetPcbNewSettings()->m_PlaceFile.output_directory;
path = ExpandTextVars( path, &textResolver, nullptr, nullptr ); path = ExpandTextVars( path, &textResolver );
path = ExpandEnvVarSubstitutions( path, nullptr ); path = ExpandEnvVarSubstitutions( path, nullptr );
wxFileName outputDir = wxFileName::DirName( path ); wxFileName outputDir = wxFileName::DirName( path );
@ -375,7 +375,7 @@ bool DIALOG_GEN_FOOTPRINT_POSITION::CreateAsciiFiles()
}; };
wxString path = m_parent->GetPcbNewSettings()->m_PlaceFile.output_directory; wxString path = m_parent->GetPcbNewSettings()->m_PlaceFile.output_directory;
path = ExpandTextVars( path, &textResolver, nullptr, nullptr ); path = ExpandTextVars( path, &textResolver );
path = ExpandEnvVarSubstitutions( path, nullptr ); path = ExpandEnvVarSubstitutions( path, nullptr );
wxFileName outputDir = wxFileName::DirName( path ); wxFileName outputDir = wxFileName::DirName( path );

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 1992-2019 Jean_Pierre Charras <jp.charras at wanadoo.fr> * Copyright (C) 1992-2019 Jean_Pierre Charras <jp.charras at wanadoo.fr>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -395,7 +395,7 @@ void DIALOG_GENDRILL::GenDrillAndMapFiles( bool aGenDrill, bool aGenMap )
}; };
wxString path = m_plotOpts.GetOutputDirectory(); wxString path = m_plotOpts.GetOutputDirectory();
path = ExpandTextVars( path, &textResolver, nullptr, nullptr ); path = ExpandTextVars( path, &textResolver );
path = ExpandEnvVarSubstitutions( path, nullptr ); path = ExpandEnvVarSubstitutions( path, nullptr );
wxFileName outputDir = wxFileName::DirName( path ); wxFileName outputDir = wxFileName::DirName( path );

View File

@ -1,7 +1,7 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -508,7 +508,7 @@ void DIALOG_PLOT::OnOutputDirectoryBrowseClicked( wxCommandEvent& event )
}; };
wxString path = m_outputDirectoryName->GetValue(); wxString path = m_outputDirectoryName->GetValue();
path = ExpandTextVars( path, &textResolver, nullptr, &Prj() ); path = ExpandTextVars( path, &textResolver );
path = ExpandEnvVarSubstitutions( path, &Prj() ); path = ExpandEnvVarSubstitutions( path, &Prj() );
path = Prj().AbsolutePath( path ); path = Prj().AbsolutePath( path );
@ -978,7 +978,7 @@ void DIALOG_PLOT::Plot( wxCommandEvent& event )
}; };
wxString path = m_plotOpts.GetOutputDirectory(); wxString path = m_plotOpts.GetOutputDirectory();
path = ExpandTextVars( path, &textResolver, nullptr, board->GetProject() ); path = ExpandTextVars( path, &textResolver );
path = ExpandEnvVarSubstitutions( path, board->GetProject() ); path = ExpandEnvVarSubstitutions( path, board->GetProject() );
wxFileName outputDir = wxFileName::DirName( path ); wxFileName outputDir = wxFileName::DirName( path );

View File

@ -4,7 +4,7 @@
* Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2015 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com> * Copyright (C) 2015 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2015 Wayne Stambaugh <stambaughw@gmail.com> * Copyright (C) 2015 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -548,6 +548,9 @@ bool FOOTPRINT::ResolveTextVar( wxString* token, int aDepth ) const
return true; return true;
} }
if( GetBoard() && GetBoard()->ResolveTextVar( token, aDepth + 1 ) )
return true;
return false; return false;
} }

View File

@ -3,7 +3,7 @@
* *
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com> * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -415,8 +415,6 @@ double FP_TEXT::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
wxString FP_TEXT::GetShownText( int aDepth, bool aAllowExtraText ) const wxString FP_TEXT::GetShownText( int aDepth, bool aAllowExtraText ) const
{ {
const FOOTPRINT* parentFootprint = static_cast<FOOTPRINT*>( GetParent() ); const FOOTPRINT* parentFootprint = static_cast<FOOTPRINT*>( GetParent() );
wxASSERT( parentFootprint );
const BOARD* board = parentFootprint->GetBoard();
std::function<bool( wxString* )> footprintResolver = std::function<bool( wxString* )> footprintResolver =
[&]( wxString* token ) -> bool [&]( wxString* token ) -> bool
@ -424,23 +422,12 @@ wxString FP_TEXT::GetShownText( int aDepth, bool aAllowExtraText ) const
return parentFootprint && parentFootprint->ResolveTextVar( token, aDepth ); return parentFootprint && parentFootprint->ResolveTextVar( token, aDepth );
}; };
std::function<bool( wxString* )> boardTextResolver =
[&]( wxString* token ) -> bool
{
return board->ResolveTextVar( token, aDepth + 1 );
};
wxString text = EDA_TEXT::GetShownText(); wxString text = EDA_TEXT::GetShownText();
if( HasTextVars() ) if( HasTextVars() )
{ {
PROJECT* project = nullptr;
if( parentFootprint && parentFootprint->GetParent() )
project = static_cast<BOARD*>( parentFootprint->GetParent() )->GetProject();
if( aDepth < 10 ) if( aDepth < 10 )
text = ExpandTextVars( text, &footprintResolver, &boardTextResolver, project ); text = ExpandTextVars( text, &footprintResolver );
} }
return text; return text;

View File

@ -1,7 +1,7 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2022-2023 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -393,8 +393,6 @@ double FP_TEXTBOX::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
wxString FP_TEXTBOX::GetShownText( int aDepth, bool aAllowExtraText ) const wxString FP_TEXTBOX::GetShownText( int aDepth, bool aAllowExtraText ) const
{ {
const FOOTPRINT* parentFootprint = static_cast<FOOTPRINT*>( GetParent() ); const FOOTPRINT* parentFootprint = static_cast<FOOTPRINT*>( GetParent() );
wxASSERT( parentFootprint );
const BOARD* board = parentFootprint->GetBoard();
std::function<bool( wxString* )> footprintResolver = std::function<bool( wxString* )> footprintResolver =
[&]( wxString* token ) -> bool [&]( wxString* token ) -> bool
@ -402,23 +400,12 @@ wxString FP_TEXTBOX::GetShownText( int aDepth, bool aAllowExtraText ) const
return parentFootprint && parentFootprint->ResolveTextVar( token, aDepth ); return parentFootprint && parentFootprint->ResolveTextVar( token, aDepth );
}; };
std::function<bool( wxString* )> boardTextResolver =
[&]( wxString* token ) -> bool
{
return board->ResolveTextVar( token, aDepth + 1 );
};
wxString text = EDA_TEXT::GetShownText(); wxString text = EDA_TEXT::GetShownText();
if( HasTextVars() ) if( HasTextVars() )
{ {
PROJECT* project = nullptr;
if( parentFootprint && parentFootprint->GetParent() )
project = static_cast<BOARD*>( parentFootprint->GetParent() )->GetProject();
if( aDepth < 10 ) if( aDepth < 10 )
text = ExpandTextVars( text, &footprintResolver, &boardTextResolver, project ); text = ExpandTextVars( text, &footprintResolver );
} }
KIFONT::FONT* font = getDrawFont(); KIFONT::FONT* font = getDrawFont();

View File

@ -3,7 +3,7 @@
* *
* Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr * 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 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -65,36 +65,18 @@ wxString PCB_TEXT::GetShownText( int aDepth, bool aAllowExtraText ) const
return true; return true;
} }
if( token->Contains( ':' ) ) if( board->ResolveTextVar( token, aDepth + 1 ) )
{ {
wxString remainder;
wxString ref = token->BeforeFirst( ':', &remainder );
BOARD_ITEM* refItem = board->GetItem( KIID( ref ) );
if( refItem && refItem->Type() == PCB_FOOTPRINT_T )
{
FOOTPRINT* refFP = static_cast<FOOTPRINT*>( refItem );
if( refFP->ResolveTextVar( &remainder, aDepth + 1 ) )
{
*token = remainder;
return true; return true;
} }
}
}
return false;
};
std::function<bool( wxString* )> boardTextResolver = return false;
[&]( wxString* token ) -> bool
{
return board->ResolveTextVar( token, aDepth + 1 );
}; };
wxString text = EDA_TEXT::GetShownText(); wxString text = EDA_TEXT::GetShownText();
if( board && HasTextVars() && aDepth < 10 ) if( board && HasTextVars() && aDepth < 10 )
text = ExpandTextVars( text, &pcbTextResolver, &boardTextResolver, board->GetProject() ); text = ExpandTextVars( text, &pcbTextResolver );
return text; return text;
} }

View File

@ -1,7 +1,7 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2022-2023 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -252,36 +252,18 @@ wxString PCB_TEXTBOX::GetShownText( int aDepth, bool aAllowExtraText ) const
return true; return true;
} }
if( token->Contains( ':' ) ) if( board->ResolveTextVar( token, aDepth + 1 ) )
{ {
wxString remainder;
wxString ref = token->BeforeFirst( ':', &remainder );
BOARD_ITEM* refItem = board->GetItem( KIID( ref ) );
if( refItem && refItem->Type() == PCB_FOOTPRINT_T )
{
FOOTPRINT* refFP = static_cast<FOOTPRINT*>( refItem );
if( refFP->ResolveTextVar( &remainder, aDepth + 1 ) )
{
*token = remainder;
return true; return true;
} }
}
}
return false;
};
std::function<bool( wxString* )> boardTextResolver = return false;
[&]( wxString* token ) -> bool
{
return board->ResolveTextVar( token, aDepth + 1 );
}; };
wxString text = EDA_TEXT::GetShownText(); wxString text = EDA_TEXT::GetShownText();
if( board && HasTextVars() && aDepth < 10 ) if( board && HasTextVars() && aDepth < 10 )
text = ExpandTextVars( text, &pcbTextResolver, &boardTextResolver, board->GetProject() ); text = ExpandTextVars( text, &pcbTextResolver );
KIFONT::FONT* font = getDrawFont(); KIFONT::FONT* font = getDrawFont();
std::vector<VECTOR2I> corners = GetAnchorAndOppositeCorner(); std::vector<VECTOR2I> corners = GetAnchorAndOppositeCorner();

View File

@ -3,7 +3,7 @@
* *
* Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com> * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -447,7 +447,7 @@ bool PLOT_CONTROLLER::OpenPlotfile( const wxString& aSuffix, PLOT_FORMAT aFormat
}; };
wxString outputDirName = GetPlotOptions().GetOutputDirectory(); wxString outputDirName = GetPlotOptions().GetOutputDirectory();
outputDirName = ExpandTextVars( outputDirName, &textResolver, nullptr, nullptr ); outputDirName = ExpandTextVars( outputDirName, &textResolver );
outputDirName = ExpandEnvVarSubstitutions( outputDirName, nullptr ); outputDirName = ExpandEnvVarSubstitutions( outputDirName, nullptr );
wxFileName outputDir = wxFileName::DirName( outputDirName ); wxFileName outputDir = wxFileName::DirName( outputDirName );