Allow cross-referencing text substitutions.
This commit is contained in:
parent
76bbb71402
commit
aba0fa7bf8
|
@ -32,6 +32,8 @@
|
|||
#include <gr_text.h>
|
||||
#include <confirm.h>
|
||||
#include <sch_text.h>
|
||||
#include <sch_component.h>
|
||||
#include <sch_reference_list.h>
|
||||
#include <widgets/unit_binder.h>
|
||||
#include <dialog_edit_label_base.h>
|
||||
#include <kicad_string.h>
|
||||
|
@ -180,15 +182,126 @@ DIALOG_LABEL_EDITOR::~DIALOG_LABEL_EDITOR()
|
|||
}
|
||||
|
||||
|
||||
wxString convertKIIDsToReferences( const wxString& aSource )
|
||||
{
|
||||
wxString newbuf;
|
||||
size_t sourceLen = aSource.length();
|
||||
|
||||
for( size_t i = 0; i < sourceLen; ++i )
|
||||
{
|
||||
if( aSource[i] == '$' && i + 1 < sourceLen && aSource[i+1] == '{' )
|
||||
{
|
||||
wxString token;
|
||||
bool isCrossRef = false;
|
||||
|
||||
for( i = i + 2; i < sourceLen; ++i )
|
||||
{
|
||||
if( aSource[i] == '}' )
|
||||
break;
|
||||
|
||||
if( aSource[i] == ':' )
|
||||
isCrossRef = true;
|
||||
|
||||
token.append( aSource[i] );
|
||||
}
|
||||
|
||||
if( isCrossRef )
|
||||
{
|
||||
SCH_SHEET_LIST sheetList( g_RootSheet );
|
||||
wxArrayString parts = wxSplit( token, ':' );
|
||||
SCH_SHEET_PATH refSheetPath;
|
||||
SCH_ITEM* refItem = sheetList.GetItem( KIID( parts[0] ), &refSheetPath );
|
||||
|
||||
if( refItem && refItem->Type() == SCH_COMPONENT_T )
|
||||
{
|
||||
SCH_COMPONENT* refComponent = static_cast<SCH_COMPONENT*>( refItem );
|
||||
token = refComponent->GetRef( &refSheetPath, true ) + ":" + parts[1];
|
||||
}
|
||||
}
|
||||
|
||||
newbuf.append( "${" + token + "}" );
|
||||
}
|
||||
else
|
||||
{
|
||||
newbuf.append( aSource[i] );
|
||||
}
|
||||
}
|
||||
|
||||
return newbuf;
|
||||
}
|
||||
|
||||
|
||||
wxString convertReferencesToKIIDs( const wxString& aSource )
|
||||
{
|
||||
wxString newbuf;
|
||||
size_t sourceLen = aSource.length();
|
||||
|
||||
for( size_t i = 0; i < sourceLen; ++i )
|
||||
{
|
||||
if( aSource[i] == '$' && i + 1 < sourceLen && aSource[i+1] == '{' )
|
||||
{
|
||||
wxString token;
|
||||
bool isCrossRef = false;
|
||||
|
||||
for( i = i + 2; i < sourceLen; ++i )
|
||||
{
|
||||
if( aSource[i] == '}' )
|
||||
break;
|
||||
|
||||
if( aSource[i] == ':' )
|
||||
isCrossRef = true;
|
||||
|
||||
token.append( aSource[i] );
|
||||
}
|
||||
|
||||
if( isCrossRef )
|
||||
{
|
||||
SCH_SHEET_LIST sheets( g_RootSheet );
|
||||
wxArrayString parts = wxSplit( token, ':' );
|
||||
SCH_REFERENCE_LIST references;
|
||||
|
||||
sheets.GetComponents( references );
|
||||
|
||||
for( size_t jj = 0; jj < references.GetCount(); jj++ )
|
||||
{
|
||||
SCH_COMPONENT* refComponent = references[ jj ].GetComp();
|
||||
wxString ref = refComponent->GetRef( &references[ jj ].GetSheetPath() );
|
||||
|
||||
if( ref == parts[0] )
|
||||
{
|
||||
token = refComponent->m_Uuid.AsString() + ":" + parts[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
newbuf.append( "${" + token + "}" );
|
||||
}
|
||||
else
|
||||
{
|
||||
newbuf.append( aSource[i] );
|
||||
}
|
||||
}
|
||||
|
||||
return newbuf;
|
||||
}
|
||||
|
||||
|
||||
bool DIALOG_LABEL_EDITOR::TransferDataToWindow()
|
||||
{
|
||||
if( !wxDialog::TransferDataToWindow() )
|
||||
return false;
|
||||
|
||||
if( m_activeTextEntry )
|
||||
m_activeTextEntry->SetValue( UnescapeString( m_CurrentText->GetText() ) );
|
||||
if( m_CurrentText->Type() == SCH_TEXT_T )
|
||||
{
|
||||
// show text variable cross-references in a human-readable format
|
||||
m_valueMultiLine->SetValue( convertKIIDsToReferences( m_CurrentText->GetText() ) );
|
||||
}
|
||||
else
|
||||
m_valueMultiLine->SetValue( UnescapeString( m_CurrentText->GetText() ) );
|
||||
{
|
||||
// show control characters in a human-readable format
|
||||
m_activeTextEntry->SetValue( UnescapeString( m_CurrentText->GetText() ) );
|
||||
}
|
||||
|
||||
if( m_valueCombo->IsShown() )
|
||||
{
|
||||
|
@ -308,11 +421,16 @@ bool DIALOG_LABEL_EDITOR::TransferDataFromWindow()
|
|||
|
||||
m_Parent->GetCanvas()->Refresh();
|
||||
|
||||
// Escape string only if is is a label. For a simple graphic text do not change anything
|
||||
if( m_CurrentText->Type() == SCH_TEXT_T )
|
||||
text = m_valueMultiLine->GetValue();
|
||||
{
|
||||
// convert any text variable cross-references to their UUIDs
|
||||
text = convertReferencesToKIIDs( m_valueMultiLine->GetValue() );
|
||||
}
|
||||
else
|
||||
{
|
||||
// labels need escaping
|
||||
text = EscapeString( m_activeTextEntry->GetValue(), CTX_NETNAME );
|
||||
}
|
||||
|
||||
if( !text.IsEmpty() )
|
||||
m_CurrentText->SetText( text );
|
||||
|
|
|
@ -931,6 +931,53 @@ void SCH_COMPONENT::SwapData( SCH_ITEM* aItem )
|
|||
}
|
||||
|
||||
|
||||
bool SCH_COMPONENT::ResolveTextVar( wxString* token, int aDepth ) const
|
||||
{
|
||||
for( int i = 0; i < MANDATORY_FIELDS; ++i )
|
||||
{
|
||||
if( token->IsSameAs( m_Fields[ i ].GetCanonicalName().Upper() ) )
|
||||
{
|
||||
*token = m_Fields[ i ].GetShownText( aDepth + 1 );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for( size_t i = MANDATORY_FIELDS; i < m_Fields.size(); ++i )
|
||||
{
|
||||
if( token->IsSameAs( m_Fields[ i ].GetName() )
|
||||
|| token->IsSameAs( m_Fields[ i ].GetName().Upper() ) )
|
||||
{
|
||||
*token = m_Fields[ i ].GetShownText( aDepth + 1 );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if( token->IsSameAs( wxT( "FOOTPRINT_LIBRARY" ) ) )
|
||||
{
|
||||
const SCH_FIELD& field = m_Fields[ FOOTPRINT ];
|
||||
wxArrayString parts = wxSplit( field.GetText(), ':' );
|
||||
|
||||
*token = parts[ 0 ];
|
||||
return true;
|
||||
}
|
||||
else if( token->IsSameAs( wxT( "FOOTPRINT_NAME" ) ) )
|
||||
{
|
||||
const SCH_FIELD& field = m_Fields[ FOOTPRINT ];
|
||||
wxArrayString parts = wxSplit( field.GetText(), ':' );
|
||||
|
||||
*token = parts[ std::min( 1, (int) parts.size() - 1 ) ];
|
||||
return true;
|
||||
}
|
||||
else if( token->IsSameAs( wxT( "UNIT" ) ) )
|
||||
{
|
||||
*token = LIB_PART::SubReference( GetUnit() );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void SCH_COMPONENT::ClearAnnotation( SCH_SHEET_PATH* aSheetPath )
|
||||
{
|
||||
// Build a reference with no annotation,
|
||||
|
|
|
@ -305,6 +305,12 @@ public:
|
|||
*/
|
||||
int GetOrientation();
|
||||
|
||||
/**
|
||||
* Resolve any references to system tokens supported by the component.
|
||||
* @param aDepth a counter to limit recursion and circular references.
|
||||
*/
|
||||
bool ResolveTextVar( wxString* token, int aDepth = 0 ) const;
|
||||
|
||||
void GetMsgPanelInfo( EDA_UNITS aUnits, std::vector<MSG_PANEL_ITEM>& aList ) override;
|
||||
|
||||
/**
|
||||
|
|
|
@ -72,103 +72,20 @@ EDA_ITEM* SCH_FIELD::Clone() const
|
|||
}
|
||||
|
||||
|
||||
wxString SCH_FIELD::GetShownText() const
|
||||
wxString SCH_FIELD::GetShownText( int aDepth ) const
|
||||
{
|
||||
std::function<bool( wxString* )> symbolResolver =
|
||||
[this]( wxString* token ) -> bool
|
||||
[&]( wxString* token ) -> bool
|
||||
{
|
||||
SCH_COMPONENT* component = static_cast<SCH_COMPONENT*>( m_Parent );
|
||||
std::vector<SCH_FIELD>& fields = component->GetFields();
|
||||
|
||||
for( int i = 0; i < MANDATORY_FIELDS; ++i )
|
||||
{
|
||||
if( token->IsSameAs( fields[ i ].GetCanonicalName().Upper() ) )
|
||||
{
|
||||
// silently drop recursive references
|
||||
if( &fields[ i ] == this )
|
||||
*token = wxEmptyString;
|
||||
else
|
||||
*token = fields[ i ].GetShownText();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for( size_t i = MANDATORY_FIELDS; i < fields.size(); ++i )
|
||||
{
|
||||
if( token->IsSameAs( fields[ i ].GetName() )
|
||||
|| token->IsSameAs( fields[ i ].GetName().Upper() ) )
|
||||
{
|
||||
// silently drop recursive references
|
||||
if( &fields[ i ] == this )
|
||||
*token = wxEmptyString;
|
||||
else
|
||||
*token = fields[ i ].GetShownText();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if( token->IsSameAs( wxT( "FOOTPRINT_LIBRARY" ) ) )
|
||||
{
|
||||
SCH_FIELD& f = component->GetFields()[ FOOTPRINT ];
|
||||
wxArrayString parts = wxSplit( f.GetText(), ':' );
|
||||
|
||||
*token = parts[ 0 ];
|
||||
return true;
|
||||
}
|
||||
else if( token->IsSameAs( wxT( "FOOTPRINT_NAME" ) ) )
|
||||
{
|
||||
SCH_FIELD& f = component->GetFields()[ FOOTPRINT ];
|
||||
wxArrayString parts = wxSplit( f.GetText(), ':' );
|
||||
|
||||
*token = parts[ std::min( 1, (int) parts.size() - 1 ) ];
|
||||
return true;
|
||||
}
|
||||
else if( token->IsSameAs( wxT( "UNIT" ) ) )
|
||||
{
|
||||
*token = LIB_PART::SubReference( component->GetUnit() );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return component->ResolveTextVar( token, aDepth + 1 );
|
||||
};
|
||||
|
||||
std::function<bool( wxString* )> sheetResolver =
|
||||
[&]( wxString* token ) -> bool
|
||||
{
|
||||
SCH_SHEET* sheet = static_cast<SCH_SHEET*>( m_Parent );
|
||||
std::vector<SCH_FIELD>& fields = sheet->GetFields();
|
||||
|
||||
for( int i = 0; i < SHEET_MANDATORY_FIELDS; ++i )
|
||||
{
|
||||
if( token->IsSameAs( fields[ i ].GetCanonicalName().Upper() ) )
|
||||
{
|
||||
// silently drop recursive references
|
||||
if( &fields[ i ] == this )
|
||||
*token = wxEmptyString;
|
||||
else
|
||||
*token = fields[ i ].GetShownText();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for( size_t i = SHEET_MANDATORY_FIELDS; i < fields.size(); ++i )
|
||||
{
|
||||
if( token->IsSameAs( fields[ i ].GetName() ) )
|
||||
{
|
||||
// silently drop recursive references
|
||||
if( &fields[ i ] == this )
|
||||
*token = wxEmptyString;
|
||||
else
|
||||
*token = fields[ i ].GetShownText();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return sheet->ResolveTextVar( token, aDepth + 1 );
|
||||
};
|
||||
|
||||
PROJECT* project = nullptr;
|
||||
|
@ -177,10 +94,15 @@ wxString SCH_FIELD::GetShownText() const
|
|||
if( g_RootSheet && g_RootSheet->GetScreen() )
|
||||
project = &g_RootSheet->GetScreen()->Kiway().Prj();
|
||||
|
||||
if( aDepth < 10 )
|
||||
{
|
||||
if( m_Parent && m_Parent->Type() == SCH_COMPONENT_T )
|
||||
text = ExpandTextVars( text, &symbolResolver, project );
|
||||
else if( m_Parent && m_Parent->Type() == SCH_SHEET_T )
|
||||
text = ExpandTextVars( text, &sheetResolver, project );
|
||||
else
|
||||
text = ExpandTextVars( text, nullptr, project );
|
||||
}
|
||||
|
||||
// WARNING: the IDs of FIELDS and SHEETS overlap, so one must check *both* the
|
||||
// id and the parent's type.
|
||||
|
@ -197,8 +119,7 @@ wxString SCH_FIELD::GetShownText() const
|
|||
text << LIB_PART::SubReference( component->GetUnit() );
|
||||
}
|
||||
}
|
||||
|
||||
if( m_Parent && m_Parent->Type() == SCH_SHEET_T )
|
||||
else if( m_Parent && m_Parent->Type() == SCH_SHEET_T )
|
||||
{
|
||||
if( m_id == SHEETFILENAME )
|
||||
text = _( "File: " ) + text;
|
||||
|
|
|
@ -115,7 +115,7 @@ public:
|
|||
|
||||
void SetId( int aId ) { m_id = aId; }
|
||||
|
||||
wxString GetShownText() const override;
|
||||
wxString GetShownText( int aDepth = 0 ) const override;
|
||||
|
||||
const EDA_RECT GetBoundingBox() const override;
|
||||
|
||||
|
|
|
@ -190,6 +190,30 @@ SCH_SHEET* SCH_SHEET::GetRootSheet()
|
|||
}
|
||||
|
||||
|
||||
bool SCH_SHEET::ResolveTextVar( wxString* token, int aDepth ) const
|
||||
{
|
||||
for( int i = 0; i < SHEET_MANDATORY_FIELDS; ++i )
|
||||
{
|
||||
if( token->IsSameAs( m_fields[i].GetCanonicalName().Upper() ) )
|
||||
{
|
||||
*token = m_fields[i].GetShownText( aDepth + 1 );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for( size_t i = SHEET_MANDATORY_FIELDS; i < m_fields.size(); ++i )
|
||||
{
|
||||
if( token->IsSameAs( m_fields[i].GetName() ) )
|
||||
{
|
||||
*token = m_fields[i].GetShownText( aDepth + 1 );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool SCH_SHEET::UsesDefaultStroke() const
|
||||
{
|
||||
return m_borderWidth == 0 && m_borderColor == COLOR4D::UNSPECIFIED;
|
||||
|
|
|
@ -336,6 +336,12 @@ public:
|
|||
*/
|
||||
int GetScreenCount() const;
|
||||
|
||||
/**
|
||||
* Resolve any references to system tokens supported by the sheet.
|
||||
* @param aDepth a counter to limit recursion and circular references.
|
||||
*/
|
||||
bool ResolveTextVar( wxString* token, int aDepth = 0 ) const;
|
||||
|
||||
void GetMsgPanelInfo( EDA_UNITS aUnits, std::vector<MSG_PANEL_ITEM>& aList ) override;
|
||||
|
||||
/* there is no member for orientation in sch_sheet, to preserve file
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <macros.h>
|
||||
#include <trigo.h>
|
||||
#include <sch_draw_panel.h>
|
||||
#include <sch_component.h>
|
||||
#include <gr_text.h>
|
||||
#include <sch_edit_frame.h>
|
||||
#include <plotter.h>
|
||||
|
@ -450,10 +451,10 @@ wxString getElectricalTypeLabel( PINSHEETLABEL_SHAPE aType )
|
|||
}
|
||||
|
||||
|
||||
wxString SCH_TEXT::GetShownText() const
|
||||
wxString SCH_TEXT::GetShownText( int aDepth ) const
|
||||
{
|
||||
std::function<bool( wxString* )> textResolver =
|
||||
[this]( wxString* token ) -> bool
|
||||
[&]( wxString* token ) -> bool
|
||||
{
|
||||
if( ( Type() == SCH_GLOBAL_LABEL_T
|
||||
|| Type() == SCH_HIER_LABEL_T
|
||||
|
@ -467,26 +468,42 @@ wxString SCH_TEXT::GetShownText() const
|
|||
if( Type() == SCH_SHEET_PIN_T && m_Parent )
|
||||
{
|
||||
SCH_SHEET* sheet = static_cast<SCH_SHEET*>( m_Parent );
|
||||
std::vector<SCH_FIELD>& fields = sheet->GetFields();
|
||||
|
||||
for( int i = 0; i < SHEET_MANDATORY_FIELDS; ++i )
|
||||
if( sheet->ResolveTextVar( token, aDepth ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
if( Type() == SCH_TEXT_T )
|
||||
{
|
||||
if( token->IsSameAs( fields[i].GetCanonicalName().Upper() ) )
|
||||
if( token->Contains( ':' ) )
|
||||
{
|
||||
*token = fields[i].GetShownText();
|
||||
SCH_SHEET_LIST sheetList( g_RootSheet );
|
||||
wxArrayString parts = wxSplit( *token, ':' );
|
||||
SCH_SHEET_PATH dummy;
|
||||
SCH_ITEM* refItem = sheetList.GetItem( KIID( parts[0] ), &dummy );
|
||||
|
||||
if( refItem && refItem->Type() == SCH_COMPONENT_T )
|
||||
{
|
||||
SCH_COMPONENT* refComponent = static_cast<SCH_COMPONENT*>( refItem );
|
||||
|
||||
if( refComponent->ResolveTextVar( &parts[1], aDepth + 1 ) )
|
||||
{
|
||||
*token = parts[1];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if( refItem && refItem->Type() == SCH_SHEET_T )
|
||||
{
|
||||
SCH_SHEET* refSheet = static_cast<SCH_SHEET*>( refItem );
|
||||
|
||||
for( size_t i = SHEET_MANDATORY_FIELDS; i < fields.size(); ++i )
|
||||
if( refSheet->ResolveTextVar( &parts[1], aDepth + 1 ) )
|
||||
{
|
||||
if( token->IsSameAs( fields[i].GetName() ) )
|
||||
{
|
||||
*token = fields[i].GetShownText();
|
||||
*token = parts[1];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
@ -496,7 +513,12 @@ wxString SCH_TEXT::GetShownText() const
|
|||
if( g_RootSheet && g_RootSheet->GetScreen() )
|
||||
project = &g_RootSheet->GetScreen()->Kiway().Prj();
|
||||
|
||||
return ExpandTextVars( EDA_TEXT::GetShownText(), &textResolver, project );
|
||||
wxString text = EDA_TEXT::GetShownText( aDepth );
|
||||
|
||||
if( aDepth < 10 )
|
||||
text = ExpandTextVars( text, &textResolver, project );
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -207,7 +207,7 @@ public:
|
|||
return wxT( "SCH_TEXT" );
|
||||
}
|
||||
|
||||
wxString GetShownText() const override;
|
||||
wxString GetShownText( int aDepth = 0 ) const override;
|
||||
|
||||
/**
|
||||
* Increment the label text, if it ends with a number.
|
||||
|
|
|
@ -123,10 +123,11 @@ public:
|
|||
virtual const wxString& GetText() const { return m_text; }
|
||||
|
||||
/**
|
||||
* Return the string actually shown after processing of the base
|
||||
* text. Default is no processing
|
||||
* Return the string actually shown after processing of the base text.
|
||||
* @aParam aDepth is used to prevent infinite recusions and loops when expanding
|
||||
* text variables.
|
||||
*/
|
||||
virtual wxString GetShownText() const { return m_shown_text; }
|
||||
virtual wxString GetShownText( int aDepth = 0 ) const { return m_shown_text; }
|
||||
|
||||
/**
|
||||
* Returns a shortened version (max 15 characters) of the shown text
|
||||
|
|
|
@ -260,6 +260,28 @@ MODULE& MODULE::operator=( const MODULE& aOther )
|
|||
}
|
||||
|
||||
|
||||
bool MODULE::ResolveTextVar( wxString* token, int aDepth ) const
|
||||
{
|
||||
if( token->IsSameAs( wxT( "REFERENCE" ) ) )
|
||||
{
|
||||
*token = m_Reference->GetShownText( aDepth + 1 );
|
||||
return true;
|
||||
}
|
||||
else if( token->IsSameAs( wxT( "VALUE" ) ) )
|
||||
{
|
||||
*token = m_Value->GetShownText( aDepth + 1 );
|
||||
return true;
|
||||
}
|
||||
else if( token->IsSameAs( wxT( "LAYER" ) ) )
|
||||
{
|
||||
*token = GetLayerName();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void MODULE::ClearAllNets()
|
||||
{
|
||||
// Force the ORPHANED dummy net info for all pads.
|
||||
|
|
|
@ -411,6 +411,12 @@ public:
|
|||
void TransformGraphicTextWithClearanceToPolygonSet( PCB_LAYER_ID aLayer,
|
||||
SHAPE_POLY_SET& aCornerBuffer, int aInflateValue, int aError = ARC_HIGH_DEF ) const;
|
||||
|
||||
/**
|
||||
* Resolve any references to system tokens supported by the component.
|
||||
* @param aDepth a counter to limit recursion and circular references.
|
||||
*/
|
||||
bool ResolveTextVar( wxString* token, int aDepth = 0 ) const;
|
||||
|
||||
///> @copydoc EDA_ITEM::GetMsgPanelInfo
|
||||
void GetMsgPanelInfo( EDA_UNITS aUnits, std::vector<MSG_PANEL_ITEM>& aList ) override;
|
||||
|
||||
|
|
|
@ -61,13 +61,13 @@ TEXTE_PCB::~TEXTE_PCB()
|
|||
}
|
||||
|
||||
|
||||
wxString TEXTE_PCB::GetShownText() const
|
||||
wxString TEXTE_PCB::GetShownText( int aDepth ) const
|
||||
{
|
||||
const BOARD* board = static_cast<BOARD*>( GetParent() );
|
||||
BOARD* board = static_cast<BOARD*>( GetParent() );
|
||||
wxASSERT( board );
|
||||
|
||||
std::function<bool( wxString* )> moduleResolver =
|
||||
[ this ]( wxString* token ) -> bool
|
||||
std::function<bool( wxString* )> pcbTextResolver =
|
||||
[&]( wxString* token ) -> bool
|
||||
{
|
||||
if( token->IsSameAs( wxT( "LAYER" ) ) )
|
||||
{
|
||||
|
@ -75,10 +75,31 @@ wxString TEXTE_PCB::GetShownText() const
|
|||
return true;
|
||||
}
|
||||
|
||||
if( token->Contains( ':' ) )
|
||||
{
|
||||
wxArrayString parts = wxSplit( *token, ':' );
|
||||
BOARD_ITEM* refItem = board->GetItem( KIID( parts[0] ) );
|
||||
|
||||
if( refItem && refItem->Type() == PCB_MODULE_T )
|
||||
{
|
||||
MODULE* refModule = static_cast<MODULE*>( refItem );
|
||||
|
||||
if( refModule->ResolveTextVar( &parts[1], aDepth + 1 ) )
|
||||
{
|
||||
*token = parts[1];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
return ExpandTextVars( EDA_TEXT::GetShownText(), &moduleResolver, board->GetProject() );
|
||||
wxString text = EDA_TEXT::GetShownText( aDepth );
|
||||
|
||||
if( aDepth < 10 )
|
||||
text = ExpandTextVars( text, &pcbTextResolver, board->GetProject() );
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ public:
|
|||
return aItem && PCB_TEXT_T == aItem->Type();
|
||||
}
|
||||
|
||||
wxString GetShownText() const override;
|
||||
wxString GetShownText( int aDepth = 0 ) const override;
|
||||
|
||||
bool Matches( wxFindReplaceData& aSearchData, void* aAuxData ) override
|
||||
{
|
||||
|
|
|
@ -488,38 +488,25 @@ unsigned int TEXTE_MODULE::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
|
|||
}
|
||||
|
||||
|
||||
wxString TEXTE_MODULE::GetShownText() const
|
||||
wxString TEXTE_MODULE::GetShownText( int aDepth ) const
|
||||
{
|
||||
const MODULE* module = static_cast<MODULE*>( GetParent() );
|
||||
wxASSERT( module );
|
||||
|
||||
const BOARD* board = static_cast<BOARD*>( module->GetParent() );
|
||||
wxASSERT( board );
|
||||
|
||||
std::function<bool( wxString* )> moduleResolver =
|
||||
[ this, module ]( wxString* token ) -> bool
|
||||
[&]( wxString* token ) -> bool
|
||||
{
|
||||
if( module )
|
||||
{
|
||||
if( token->IsSameAs( wxT( "REFERENCE" ) ) )
|
||||
{
|
||||
*token = module->GetReference();
|
||||
return true;
|
||||
}
|
||||
else if( token->IsSameAs( wxT( "VALUE" ) ) )
|
||||
{
|
||||
*token = module->GetValue();
|
||||
return true;
|
||||
}
|
||||
else if( token->IsSameAs( wxT( "LAYER" ) ) )
|
||||
{
|
||||
*token = GetLayerName();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return module && module->ResolveTextVar( token, aDepth );
|
||||
};
|
||||
|
||||
return ExpandTextVars( EDA_TEXT::GetShownText(), &moduleResolver, board->GetProject() );
|
||||
PROJECT* project = nullptr;
|
||||
wxString text = EDA_TEXT::GetShownText( aDepth );
|
||||
|
||||
if( module && module->GetParent() )
|
||||
project = static_cast<BOARD*>( module->GetParent() )->GetProject();
|
||||
|
||||
if( aDepth < 10 )
|
||||
text = ExpandTextVars( text, &moduleResolver, project );
|
||||
|
||||
return text;
|
||||
}
|
||||
|
|
|
@ -216,7 +216,7 @@ public:
|
|||
|
||||
EDA_ITEM* Clone() const override;
|
||||
|
||||
virtual wxString GetShownText() const override;
|
||||
virtual wxString GetShownText( int aDepth = 0 ) const override;
|
||||
|
||||
virtual const BOX2I ViewBBox() const override;
|
||||
|
||||
|
|
|
@ -291,6 +291,99 @@ void DIALOG_TEXT_PROPERTIES::OnDimensionUnitsChange( wxCommandEvent& event )
|
|||
}
|
||||
|
||||
|
||||
wxString DIALOG_TEXT_PROPERTIES::convertKIIDsToReferences( const wxString& aSource )
|
||||
{
|
||||
wxString newbuf;
|
||||
size_t sourceLen = aSource.length();
|
||||
|
||||
for( size_t i = 0; i < sourceLen; ++i )
|
||||
{
|
||||
if( aSource[i] == '$' && i + 1 < sourceLen && aSource[i+1] == '{' )
|
||||
{
|
||||
wxString token;
|
||||
bool isCrossRef = false;
|
||||
|
||||
for( i = i + 2; i < sourceLen; ++i )
|
||||
{
|
||||
if( aSource[i] == '}' )
|
||||
break;
|
||||
|
||||
if( aSource[i] == ':' )
|
||||
isCrossRef = true;
|
||||
|
||||
token.append( aSource[i] );
|
||||
}
|
||||
|
||||
if( isCrossRef )
|
||||
{
|
||||
wxArrayString parts = wxSplit( token, ':' );
|
||||
BOARD_ITEM* refItem = m_Parent->GetBoard()->GetItem( KIID( parts[0] ) );
|
||||
|
||||
if( refItem && refItem->Type() == PCB_MODULE_T )
|
||||
token = static_cast<MODULE*>( refItem )->GetReference() + ":" + parts[1];
|
||||
}
|
||||
|
||||
newbuf.append( "${" + token + "}" );
|
||||
}
|
||||
else
|
||||
{
|
||||
newbuf.append( aSource[i] );
|
||||
}
|
||||
}
|
||||
|
||||
return newbuf;
|
||||
}
|
||||
|
||||
|
||||
wxString DIALOG_TEXT_PROPERTIES::convertReferencesToKIIDs( const wxString& aSource )
|
||||
{
|
||||
wxString newbuf;
|
||||
size_t sourceLen = aSource.length();
|
||||
|
||||
for( size_t i = 0; i < sourceLen; ++i )
|
||||
{
|
||||
if( aSource[i] == '$' && i + 1 < sourceLen && aSource[i+1] == '{' )
|
||||
{
|
||||
wxString token;
|
||||
bool isCrossRef = false;
|
||||
|
||||
for( i = i + 2; i < sourceLen; ++i )
|
||||
{
|
||||
if( aSource[i] == '}' )
|
||||
break;
|
||||
|
||||
if( aSource[i] == ':' )
|
||||
isCrossRef = true;
|
||||
|
||||
token.append( aSource[i] );
|
||||
}
|
||||
|
||||
if( isCrossRef )
|
||||
{
|
||||
wxArrayString parts = wxSplit( token, ':' );
|
||||
|
||||
for( MODULE* mod : m_Parent->GetBoard()->Modules() )
|
||||
{
|
||||
if( mod->GetReference().CmpNoCase( parts[0] ) == 0 )
|
||||
{
|
||||
token = mod->m_Uuid.AsString() + ":" + parts[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
newbuf.append( "${" + token + "}" );
|
||||
}
|
||||
else
|
||||
{
|
||||
newbuf.append( aSource[i] );
|
||||
}
|
||||
}
|
||||
|
||||
return newbuf;
|
||||
}
|
||||
|
||||
|
||||
bool DIALOG_TEXT_PROPERTIES::TransferDataToWindow()
|
||||
{
|
||||
if( m_SingleLineText->IsShown() )
|
||||
|
@ -304,7 +397,7 @@ bool DIALOG_TEXT_PROPERTIES::TransferDataToWindow()
|
|||
}
|
||||
else if( m_MultiLineText->IsShown() )
|
||||
{
|
||||
m_MultiLineText->SetValue( m_edaText->GetText() );
|
||||
m_MultiLineText->SetValue( convertKIIDsToReferences( m_edaText->GetText() ) );
|
||||
m_MultiLineText->SetSelection( -1, -1 );
|
||||
}
|
||||
else if (m_DimensionText->IsShown() )
|
||||
|
@ -403,10 +496,11 @@ bool DIALOG_TEXT_PROPERTIES::TransferDataFromWindow()
|
|||
{
|
||||
if( !m_MultiLineText->GetValue().IsEmpty() )
|
||||
{
|
||||
wxString txt = convertReferencesToKIIDs( m_MultiLineText->GetValue() );
|
||||
|
||||
// On Windows, a new line is coded as \r\n.
|
||||
// We use only \n in kicad files and in drawing routines.
|
||||
// so strip the \r char
|
||||
wxString txt = m_MultiLineText->GetValue();
|
||||
#ifdef __WINDOWS__
|
||||
txt.Replace( "\r", "" );
|
||||
#endif
|
||||
|
|
|
@ -60,6 +60,9 @@ private:
|
|||
wxFloatingPointValidator<double> m_OrientValidator;
|
||||
double m_OrientValue;
|
||||
|
||||
wxString convertReferencesToKIIDs( const wxString& aSource );
|
||||
wxString convertKIIDsToReferences( const wxString& aSource );
|
||||
|
||||
bool TransferDataToWindow() override;
|
||||
bool TransferDataFromWindow() override;
|
||||
|
||||
|
|
Loading…
Reference in New Issue