Allow back-annotation of differing values and footprints.
Also fixes a couple of bugs where resolving a textVar reference to the refDes or unit wouldn't get the correct value in a hierarchical schematic. (Unlogged.) Fixes https://gitlab.com/kicad/code/kicad/issues/5397
This commit is contained in:
parent
306a8f57f7
commit
be15053745
|
@ -646,11 +646,11 @@ int SCH_REFERENCE_LIST::CheckAnnotation( REPORTER& aReporter )
|
|||
flatList[ii].GetRef(),
|
||||
flatList[ii].m_NumRef,
|
||||
LIB_PART::SubReference( flatList[ii].m_Unit ),
|
||||
flatList[ii].m_Value->GetText(),
|
||||
flatList[ii].m_Value,
|
||||
flatList[next].GetRef(),
|
||||
flatList[next].m_NumRef,
|
||||
LIB_PART::SubReference( flatList[next].m_Unit ),
|
||||
flatList[next].m_Value->GetText() );
|
||||
flatList[next].m_Value );
|
||||
|
||||
aReporter.Report( msg, RPT_SEVERITY_ERROR );
|
||||
error++;
|
||||
|
@ -670,6 +670,7 @@ SCH_REFERENCE::SCH_REFERENCE( SCH_COMPONENT* aComponent, LIB_PART* aLibPart,
|
|||
m_Entry = aLibPart; // Warning: can be nullptr for orphan components
|
||||
// (i.e. with a symbol library not found)
|
||||
m_Unit = aComponent->GetUnitSelection( &aSheetPath );
|
||||
m_Footprint = aComponent->GetFootprint( &aSheetPath );
|
||||
m_SheetPath = aSheetPath;
|
||||
m_IsNew = false;
|
||||
m_Flag = 0;
|
||||
|
@ -688,7 +689,7 @@ SCH_REFERENCE::SCH_REFERENCE( SCH_COMPONENT* aComponent, LIB_PART* aLibPart,
|
|||
if( aComponent->GetField( VALUE )->GetText().IsEmpty() )
|
||||
aComponent->GetField( VALUE )->SetText( wxT( "~" ) );
|
||||
|
||||
m_Value = aComponent->GetField( VALUE );
|
||||
m_Value = aComponent->GetValue( &aSheetPath );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -301,9 +301,9 @@ int ERC_TESTER::TestMultiunitFootprints()
|
|||
SCH_MULTI_UNIT_REFERENCE_MAP refMap;
|
||||
sheets.GetMultiUnitComponents( refMap, true );
|
||||
|
||||
for( auto& component : refMap )
|
||||
for( std::pair<const wxString, SCH_REFERENCE_LIST>& component : refMap )
|
||||
{
|
||||
auto& refList = component.second;
|
||||
SCH_REFERENCE_LIST& refList = component.second;
|
||||
|
||||
if( refList.GetCount() == 0 )
|
||||
{
|
||||
|
@ -316,10 +316,10 @@ int ERC_TESTER::TestMultiunitFootprints()
|
|||
wxString unitName;
|
||||
wxString unitFP;
|
||||
|
||||
for( unsigned i = 0; i < component.second.GetCount(); ++i )
|
||||
for( unsigned i = 0; i < refList.GetCount(); ++i )
|
||||
{
|
||||
SCH_SHEET_PATH sheetPath = refList.GetItem( i ).GetSheetPath();
|
||||
unitFP = refList.GetItem( i ).GetComp()->GetField( FOOTPRINT )->GetText();
|
||||
unitFP = refList.GetItem( i ).GetFootprint();
|
||||
|
||||
if( !unitFP.IsEmpty() )
|
||||
{
|
||||
|
@ -329,12 +329,12 @@ int ERC_TESTER::TestMultiunitFootprints()
|
|||
}
|
||||
}
|
||||
|
||||
for( unsigned i = 0; i < component.second.GetCount(); ++i )
|
||||
for( unsigned i = 0; i < refList.GetCount(); ++i )
|
||||
{
|
||||
SCH_REFERENCE& secondRef = refList.GetItem( i );
|
||||
SCH_COMPONENT* secondUnit = secondRef.GetComp();
|
||||
wxString secondName = secondUnit->GetRef( &secondRef.GetSheetPath(), true );
|
||||
const wxString secondFp = secondUnit->GetField( FOOTPRINT )->GetText();
|
||||
const wxString secondFp = secondRef.GetFootprint();
|
||||
wxString msg;
|
||||
|
||||
if( !secondFp.IsEmpty() && unitFP != secondFp )
|
||||
|
|
|
@ -926,7 +926,7 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType )
|
|||
SCH_COMPONENT* cmp = static_cast<SCH_COMPONENT*>( item );
|
||||
|
||||
// Update footprint LIB_ID to point to the imported Eagle library
|
||||
auto fpField = cmp->GetField( FOOTPRINT );
|
||||
SCH_FIELD* fpField = cmp->GetField( FOOTPRINT );
|
||||
|
||||
if( !fpField->GetText().IsEmpty() )
|
||||
{
|
||||
|
|
|
@ -369,17 +369,21 @@ void SCH_COMPONENT::Print( RENDER_SETTINGS* aSettings, const wxPoint& aOffset )
|
|||
|
||||
|
||||
void SCH_COMPONENT::AddHierarchicalReference( const KIID_PATH& aPath, const wxString& aRef,
|
||||
int aUnit )
|
||||
int aUnit, const wxString& aValue,
|
||||
const wxString& aFootprint )
|
||||
{
|
||||
// Search for an existing path and remove it if found (should not occur)
|
||||
for( unsigned ii = 0; ii < m_instanceReferences.size(); ii++ )
|
||||
{
|
||||
if( m_instanceReferences[ii].m_Path == aPath )
|
||||
{
|
||||
wxLogTrace( traceSchSheetPaths,
|
||||
"Removing symbol instance:\n sheet path %s\n reference %s, unit %d\n from symbol %s.",
|
||||
aPath.AsString(), m_instanceReferences[ii].m_Reference,
|
||||
m_instanceReferences[ii].m_Unit, m_Uuid.AsString() );
|
||||
wxLogTrace( traceSchSheetPaths, "Removing symbol instance:\n"
|
||||
" sheet path %s\n"
|
||||
" reference %s, unit %d from symbol %s.",
|
||||
aPath.AsString(),
|
||||
m_instanceReferences[ii].m_Reference,
|
||||
m_instanceReferences[ii].m_Unit,
|
||||
m_Uuid.AsString() );
|
||||
|
||||
m_instanceReferences.erase( m_instanceReferences.begin() + ii );
|
||||
ii--;
|
||||
|
@ -390,16 +394,22 @@ void SCH_COMPONENT::AddHierarchicalReference( const KIID_PATH& aPath, const wxSt
|
|||
instance.m_Path = aPath;
|
||||
instance.m_Reference = aRef;
|
||||
instance.m_Unit = aUnit;
|
||||
instance.m_Value = aValue;
|
||||
instance.m_Footprint = aFootprint;
|
||||
|
||||
wxLogTrace( traceSchSheetPaths,
|
||||
"Adding symbol instance:\n sheet path %s\n reference %s, unit %d\n to symbol %s.",
|
||||
aPath.AsString(), aRef, aUnit, m_Uuid.AsString() );
|
||||
wxLogTrace( traceSchSheetPaths, "Adding symbol instance:\n"
|
||||
" sheet path %s\n"
|
||||
" reference %s, unit %d to symbol %s.",
|
||||
aPath.AsString(),
|
||||
aRef,
|
||||
aUnit,
|
||||
m_Uuid.AsString() );
|
||||
|
||||
m_instanceReferences.push_back( instance );
|
||||
}
|
||||
|
||||
|
||||
const wxString SCH_COMPONENT::GetRef( const SCH_SHEET_PATH* sheet, bool aIncludeUnit )
|
||||
const wxString SCH_COMPONENT::GetRef( const SCH_SHEET_PATH* sheet, bool aIncludeUnit ) const
|
||||
{
|
||||
KIID_PATH path = sheet->Path();
|
||||
wxString ref;
|
||||
|
@ -408,10 +418,6 @@ const wxString SCH_COMPONENT::GetRef( const SCH_SHEET_PATH* sheet, bool aInclude
|
|||
{
|
||||
if( instance.m_Path == path )
|
||||
{
|
||||
wxLogTrace( traceSchSheetPaths,
|
||||
"Setting symbol instance:\n sheet path %s\n reference %s, unit %d\n found in symbol %s.",
|
||||
path.AsString(), instance.m_Reference, instance.m_Unit, m_Uuid.AsString() );
|
||||
|
||||
ref = instance.m_Reference;
|
||||
break;
|
||||
}
|
||||
|
@ -423,7 +429,7 @@ const wxString SCH_COMPONENT::GetRef( const SCH_SHEET_PATH* sheet, bool aInclude
|
|||
// the same component references, but perhaps this is best.
|
||||
if( ref.IsEmpty() && !GetField( REFERENCE )->GetText().IsEmpty() )
|
||||
{
|
||||
SetRef( sheet, GetField( REFERENCE )->GetText() );
|
||||
const_cast<SCH_COMPONENT*>( this )->SetRef( sheet, GetField( REFERENCE )->GetText() );
|
||||
ref = GetField( REFERENCE )->GetText();
|
||||
}
|
||||
|
||||
|
@ -541,7 +547,6 @@ int SCH_COMPONENT::GetUnitSelection( const SCH_SHEET_PATH* aSheet ) const
|
|||
void SCH_COMPONENT::SetUnitSelection( const SCH_SHEET_PATH* aSheet, int aUnitSelection )
|
||||
{
|
||||
KIID_PATH path = aSheet->Path();
|
||||
bool notInArray = true;
|
||||
|
||||
// check to see if it is already there before inserting it
|
||||
for( COMPONENT_INSTANCE_REFERENCE& instance : m_instanceReferences )
|
||||
|
@ -549,12 +554,86 @@ void SCH_COMPONENT::SetUnitSelection( const SCH_SHEET_PATH* aSheet, int aUnitSel
|
|||
if( instance.m_Path == path )
|
||||
{
|
||||
instance.m_Unit = aUnitSelection;
|
||||
notInArray = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if( notInArray )
|
||||
AddHierarchicalReference( path, m_prefix, aUnitSelection );
|
||||
// didn't find it; better add it
|
||||
AddHierarchicalReference( path, m_prefix, aUnitSelection );
|
||||
}
|
||||
|
||||
|
||||
const wxString SCH_COMPONENT::GetValue( const SCH_SHEET_PATH* sheet ) const
|
||||
{
|
||||
KIID_PATH path = sheet->Path();
|
||||
|
||||
for( const COMPONENT_INSTANCE_REFERENCE& instance : m_instanceReferences )
|
||||
{
|
||||
if( instance.m_Path == path && !instance.m_Footprint.IsEmpty() )
|
||||
{
|
||||
SCH_FIELD dummy( wxDefaultPosition, VALUE, const_cast<SCH_COMPONENT*>( this ) );
|
||||
dummy.SetText( instance.m_Value );
|
||||
return dummy.GetShownText();
|
||||
}
|
||||
}
|
||||
|
||||
return GetField( VALUE )->GetShownText();
|
||||
}
|
||||
|
||||
|
||||
void SCH_COMPONENT::SetValue( const SCH_SHEET_PATH* sheet, const wxString& aValue )
|
||||
{
|
||||
KIID_PATH path = sheet->Path();
|
||||
|
||||
// check to see if it is already there before inserting it
|
||||
for( COMPONENT_INSTANCE_REFERENCE& instance : m_instanceReferences )
|
||||
{
|
||||
if( instance.m_Path == path )
|
||||
{
|
||||
instance.m_Value = aValue;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// didn't find it; better add it
|
||||
AddHierarchicalReference( path, m_prefix, m_unit, aValue, wxEmptyString );
|
||||
}
|
||||
|
||||
|
||||
const wxString SCH_COMPONENT::GetFootprint( const SCH_SHEET_PATH* sheet ) const
|
||||
{
|
||||
KIID_PATH path = sheet->Path();
|
||||
|
||||
for( const COMPONENT_INSTANCE_REFERENCE& instance : m_instanceReferences )
|
||||
{
|
||||
if( instance.m_Path == path && !instance.m_Footprint.IsEmpty() )
|
||||
{
|
||||
SCH_FIELD dummy( wxDefaultPosition, FOOTPRINT, const_cast<SCH_COMPONENT*>( this ) );
|
||||
dummy.SetText( instance.m_Footprint );
|
||||
return dummy.GetShownText();
|
||||
}
|
||||
}
|
||||
|
||||
return GetField( FOOTPRINT )->GetShownText();
|
||||
}
|
||||
|
||||
|
||||
void SCH_COMPONENT::SetFootprint( const SCH_SHEET_PATH* sheet, const wxString& aFootprint )
|
||||
{
|
||||
KIID_PATH path = sheet->Path();
|
||||
|
||||
// check to see if it is already there before inserting it
|
||||
for( COMPONENT_INSTANCE_REFERENCE& instance : m_instanceReferences )
|
||||
{
|
||||
if( instance.m_Path == path )
|
||||
{
|
||||
instance.m_Footprint = aFootprint;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// didn't find it; better add it
|
||||
AddHierarchicalReference( path, m_prefix, m_unit, wxEmptyString, aFootprint );
|
||||
}
|
||||
|
||||
|
||||
|
@ -793,11 +872,21 @@ void SCH_COMPONENT::GetContextualTextVars( wxArrayString* aVars ) const
|
|||
|
||||
bool SCH_COMPONENT::ResolveTextVar( wxString* token, int aDepth ) const
|
||||
{
|
||||
SCHEMATIC* schematic = Schematic();
|
||||
|
||||
for( int i = 0; i < MANDATORY_FIELDS; ++i )
|
||||
{
|
||||
if( token->IsSameAs( m_Fields[ i ].GetCanonicalName().Upper() ) )
|
||||
{
|
||||
*token = m_Fields[ i ].GetShownText( aDepth + 1 );
|
||||
if( i == REFERENCE && schematic )
|
||||
*token = GetRef( &schematic->CurrentSheet(), true );
|
||||
else if( i == VALUE && schematic )
|
||||
*token = GetValue( &schematic->CurrentSheet() );
|
||||
else if( i == FOOTPRINT && schematic )
|
||||
*token = GetFootprint( &schematic->CurrentSheet() );
|
||||
else
|
||||
*token = m_Fields[ i ].GetShownText( aDepth + 1 );
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -814,23 +903,42 @@ bool SCH_COMPONENT::ResolveTextVar( wxString* token, int aDepth ) const
|
|||
|
||||
if( token->IsSameAs( wxT( "FOOTPRINT_LIBRARY" ) ) )
|
||||
{
|
||||
const SCH_FIELD& field = m_Fields[ FOOTPRINT ];
|
||||
wxArrayString parts = wxSplit( field.GetText(), ':' );
|
||||
wxString footprint;
|
||||
|
||||
if( schematic )
|
||||
footprint = GetFootprint( &schematic->CurrentSheet() );
|
||||
else
|
||||
footprint = m_Fields[ FOOTPRINT ].GetShownText();
|
||||
|
||||
wxArrayString parts = wxSplit( footprint, ':' );
|
||||
|
||||
*token = parts[ 0 ];
|
||||
return true;
|
||||
}
|
||||
else if( token->IsSameAs( wxT( "FOOTPRINT_NAME" ) ) )
|
||||
{
|
||||
const SCH_FIELD& field = m_Fields[ FOOTPRINT ];
|
||||
wxArrayString parts = wxSplit( field.GetText(), ':' );
|
||||
wxString footprint;
|
||||
|
||||
if( schematic )
|
||||
footprint = GetFootprint( &schematic->CurrentSheet() );
|
||||
else
|
||||
footprint = m_Fields[ FOOTPRINT ].GetShownText();
|
||||
|
||||
wxArrayString parts = wxSplit( footprint, ':' );
|
||||
|
||||
*token = parts[ std::min( 1, (int) parts.size() - 1 ) ];
|
||||
return true;
|
||||
}
|
||||
else if( token->IsSameAs( wxT( "UNIT" ) ) )
|
||||
{
|
||||
*token = LIB_PART::SubReference( GetUnit() );
|
||||
int unit;
|
||||
|
||||
if( schematic )
|
||||
unit = GetUnitSelection( &schematic->CurrentSheet() );
|
||||
else
|
||||
unit = GetUnit();
|
||||
|
||||
*token = LIB_PART::SubReference( unit );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1238,9 +1346,9 @@ void SCH_COMPONENT::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, MSG_PANEL_ITEMS& aL
|
|||
}
|
||||
|
||||
// Display the current associated footprint, if exists.
|
||||
if( !GetField( FOOTPRINT )->IsVoid() )
|
||||
msg = GetField( FOOTPRINT )->GetShownText();
|
||||
else
|
||||
msg = GetFootprint( &schframe->GetCurrentSheet() );
|
||||
|
||||
if( msg.IsEmpty() )
|
||||
msg = _( "<Unknown>" );
|
||||
|
||||
aList.push_back( MSG_PANEL_ITEM( _( "Footprint" ), msg, DARKRED ) );
|
||||
|
|
|
@ -514,7 +514,7 @@ public:
|
|||
*
|
||||
* @return the reference for the sheet.
|
||||
*/
|
||||
const wxString GetRef( const SCH_SHEET_PATH* aSheet, bool aIncludeUnit = false );
|
||||
const wxString GetRef( const SCH_SHEET_PATH* aSheet, bool aIncludeUnit = false ) const;
|
||||
|
||||
/**
|
||||
* Set the reference for the given sheet path for this symbol.
|
||||
|
@ -538,17 +538,28 @@ public:
|
|||
* timestamp> like /05678E50/A23EF560)
|
||||
* @param aRef is the local reference like C45, R56
|
||||
* @param aUnit is the unit selection used for symbols with multiple units per package.
|
||||
* @param aValue is the value used for this instance
|
||||
* @param aFootprint is the footprint used for this instance (which might have different
|
||||
* hole spacing or other board-specific changes from other intances)
|
||||
*/
|
||||
void AddHierarchicalReference( const KIID_PATH& aPath,
|
||||
const wxString& aRef,
|
||||
int aUnit );
|
||||
int aUnit,
|
||||
const wxString& aValue = wxEmptyString,
|
||||
const wxString& aFootprint = wxEmptyString );
|
||||
|
||||
// returns the unit selection, for the given sheet path.
|
||||
// Returns the instance-specific unit selection for the given sheet path.
|
||||
int GetUnitSelection( const SCH_SHEET_PATH* aSheet ) const;
|
||||
|
||||
// Set the unit selection, for the given sheet path.
|
||||
void SetUnitSelection( const SCH_SHEET_PATH* aSheet, int aUnitSelection );
|
||||
|
||||
// Returns the instance-specific value for the given sheet path.
|
||||
const wxString GetValue( const SCH_SHEET_PATH* sheet ) const;
|
||||
void SetValue( const SCH_SHEET_PATH* sheet, const wxString& aValue );
|
||||
|
||||
// Returns the instance-specific footprint assignment for the given sheet path.
|
||||
const wxString GetFootprint( const SCH_SHEET_PATH* sheet ) const;
|
||||
void SetFootprint( const SCH_SHEET_PATH* sheet, const wxString& aFootprint );
|
||||
|
||||
// Geometric transforms (used in block operations):
|
||||
|
||||
void Move( const wxPoint& aMoveVector ) override
|
||||
|
|
|
@ -44,20 +44,14 @@
|
|||
*/
|
||||
//#define SEXPR_SCHEMATIC_FILE_VERSION 20200310 // Initial version. Sheet fields were named
|
||||
// incorectly (using symbol field vocabulary).
|
||||
|
||||
//#define SEXPR_SCHEMATIC_FILE_VERSION 20200506 // Used "page" instead of "paper" for paper
|
||||
// sizes.
|
||||
|
||||
//#define SEXPR_SCHEMATIC_FILE_VERSION 20200512 // Add support for exclude from BOM.
|
||||
|
||||
//#define SEXPR_SCHEMATIC_FILE_VERSION 20200602 // Add support for exclude from board.
|
||||
|
||||
//#define SEXPR_SCHEMATIC_FILE_VERSION 20200608 // Add support for bus and junction properties.
|
||||
|
||||
//#define SEXPR_SCHEMATIC_FILE_VERSION 20200618 // Disallow duplicate field ids.
|
||||
|
||||
//#define SEXPR_SCHEMATIC_FILE_VERSION 20200714 // Add alternate pin definitions.
|
||||
|
||||
//#define SEXPR_SCHEMATIC_FILE_VERSION 20200820
|
||||
//#define SEXPR_SCHEMATIC_FILE_VERSION 20200827 // Remove host tag
|
||||
|
||||
#define SEXPR_SCHEMATIC_FILE_VERSION 20200827 // Remove host tag
|
||||
#define SEXPR_SCHEMATIC_FILE_VERSION 20200828 // Add footprint to symbol_instances.
|
||||
|
|
|
@ -54,12 +54,12 @@ class SCH_REFERENCE
|
|||
///< used to annotate by X or Y position
|
||||
int m_Unit; ///< The unit number for components with multiple parts
|
||||
///< per package.
|
||||
wxString m_Value; ///< The component value.
|
||||
wxString m_Footprint; ///< The footprint assigned.
|
||||
SCH_SHEET_PATH m_SheetPath; ///< The sheet path for this reference.
|
||||
bool m_IsNew; ///< True if not yet annotated.
|
||||
int m_SheetNum; ///< The sheet number for the reference.
|
||||
KIID m_Uuid; ///< UUID of the component.
|
||||
EDA_TEXT* m_Value; ///< The component value of the reference. It is the
|
||||
///< same for all instances.
|
||||
int m_NumRef; ///< The numeric part of the reference designator.
|
||||
int m_Flag;
|
||||
|
||||
|
@ -74,7 +74,6 @@ public:
|
|||
m_Entry = NULL;
|
||||
m_Unit = 0;
|
||||
m_IsNew = false;
|
||||
m_Value = NULL;
|
||||
m_NumRef = 0;
|
||||
m_Flag = 0;
|
||||
m_SheetNum = 0;
|
||||
|
@ -92,9 +91,14 @@ public:
|
|||
SCH_SHEET_PATH& GetSheetPath() { return m_SheetPath; }
|
||||
|
||||
int GetUnit() const { return m_Unit; }
|
||||
|
||||
void SetUnit( int aUnit ) { m_Unit = aUnit; }
|
||||
|
||||
const wxString GetValue() const { return m_Value; }
|
||||
void SetValue( const wxString& aValue ) { m_Value = aValue; }
|
||||
|
||||
const wxString GetFootprint() const { return m_Footprint; }
|
||||
void SetFootprint( const wxString& aFP ) { m_Footprint = aFP; }
|
||||
|
||||
void SetSheetNumber( int aSheetNumber ) { m_SheetNum = aSheetNumber; }
|
||||
|
||||
const wxString GetPath() const
|
||||
|
@ -168,7 +172,7 @@ public:
|
|||
|
||||
int CompareValue( const SCH_REFERENCE& item ) const
|
||||
{
|
||||
return m_Value->GetText().Cmp( item.m_Value->GetText() );
|
||||
return m_Value.Cmp( item.m_Value );
|
||||
}
|
||||
|
||||
int CompareRef( const SCH_REFERENCE& item ) const
|
||||
|
|
|
@ -1084,49 +1084,6 @@ SCH_TEXT* SCH_SCREEN::GetLabel( const wxPoint& aPosition, int aAccuracy )
|
|||
}
|
||||
|
||||
|
||||
bool SCH_SCREEN::SetComponentFootprint( SCH_SHEET_PATH* aSheetPath, const wxString& aReference,
|
||||
const wxString& aFootPrint, bool aSetVisible )
|
||||
{
|
||||
SCH_COMPONENT* component;
|
||||
bool found = false;
|
||||
|
||||
for( SCH_ITEM* item : Items().OfType( SCH_COMPONENT_T ) )
|
||||
{
|
||||
component = static_cast<SCH_COMPONENT*>( item );
|
||||
|
||||
if( aReference.CmpNoCase( component->GetRef( aSheetPath ) ) == 0 )
|
||||
{
|
||||
// Found: Init Footprint Field
|
||||
|
||||
/* Give a reasonable value to the field position and
|
||||
* orientation, if the text is empty at position 0, because
|
||||
* it is probably not yet initialized
|
||||
*/
|
||||
SCH_FIELD * fpfield = component->GetField( FOOTPRINT );
|
||||
if( fpfield->GetText().IsEmpty()
|
||||
&& ( fpfield->GetTextPos() == component->GetPosition() ) )
|
||||
{
|
||||
fpfield->SetTextAngle( component->GetField( VALUE )->GetTextAngle() );
|
||||
fpfield->SetTextPos( component->GetField( VALUE )->GetTextPos() );
|
||||
fpfield->SetTextSize( component->GetField( VALUE )->GetTextSize() );
|
||||
|
||||
if( fpfield->GetTextAngle() == 0.0 )
|
||||
fpfield->Offset( wxPoint( 0, Mils2iu( 100 ) ) );
|
||||
else
|
||||
fpfield->Offset( wxPoint( Mils2iu( 100 ), 0 ) );
|
||||
}
|
||||
|
||||
fpfield->SetText( aFootPrint );
|
||||
fpfield->SetVisible( aSetVisible );
|
||||
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
void SCH_SCREEN::AddLibSymbol( LIB_PART* aLibSymbol )
|
||||
{
|
||||
wxCHECK( aLibSymbol, /* void */ );
|
||||
|
|
|
@ -452,19 +452,6 @@ public:
|
|||
*/
|
||||
SCH_TEXT* GetLabel( const wxPoint& aPosition, int aAccuracy = 0 );
|
||||
|
||||
/**
|
||||
* Search this screen for a symbol with \a aReference and set the footprint field to
|
||||
* \a aFootPrint if found.
|
||||
*
|
||||
* @param aSheetPath The sheet path used to look up the reference designator.
|
||||
* @param aReference The reference designator of the component.
|
||||
* @param aFootPrint The value to set the footprint field.
|
||||
* @param aSetVisible The value to set the field visibility flag.
|
||||
* @return True if \a aReference was found otherwise false.
|
||||
*/
|
||||
bool SetComponentFootprint( SCH_SHEET_PATH* aSheetPath, const wxString& aReference,
|
||||
const wxString& aFootPrint, bool aSetVisible );
|
||||
|
||||
/**
|
||||
* Fetch a list of unique #LIB_PART object pointers required to properly render each
|
||||
* #SCH_COMPONENT in this schematic.
|
||||
|
|
|
@ -1835,8 +1835,18 @@ void SCH_SEXPR_PARSER::parseSchSymbolInstances( SCH_SCREEN* aScreen )
|
|||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_value:
|
||||
instance.m_Value = FromUTF8();
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_footprint:
|
||||
instance.m_Footprint = FromUTF8();
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
default:
|
||||
Expecting( "path or unit" );
|
||||
Expecting( "path, unit, value or footprint" );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,8 +20,6 @@
|
|||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <boost/algorithm/string/join.hpp>
|
||||
#include <cctype>
|
||||
|
||||
// For some reason wxWidgets is built with wxUSE_BASE64 unset so expose the wxWidgets
|
||||
// base64 code.
|
||||
|
@ -29,7 +27,6 @@
|
|||
#include <wx/base64.h>
|
||||
#include <wx/mstream.h>
|
||||
#include <advanced_config.h>
|
||||
#include <build_version.h>
|
||||
#include <pgm_base.h>
|
||||
#include <trace_helpers.h>
|
||||
#include <sch_bitmap.h>
|
||||
|
@ -183,22 +180,11 @@ static float getPinAngle( int aOrientation )
|
|||
{
|
||||
switch( aOrientation )
|
||||
{
|
||||
case PIN_RIGHT:
|
||||
return 0.0;
|
||||
|
||||
case PIN_LEFT:
|
||||
return 180.0;
|
||||
|
||||
case PIN_UP:
|
||||
return 90.0;
|
||||
|
||||
case PIN_DOWN:
|
||||
return 270.0;
|
||||
|
||||
default:
|
||||
wxFAIL_MSG( "Missing symbol library pin orientation type" );
|
||||
|
||||
return 0.0;
|
||||
case PIN_RIGHT: return 0.0;
|
||||
case PIN_LEFT: return 180.0;
|
||||
case PIN_UP: return 90.0;
|
||||
case PIN_DOWN: return 270.0;
|
||||
default: wxFAIL_MSG( "Missing symbol library pin orientation type" ); return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -726,9 +712,11 @@ void SCH_SEXPR_PLUGIN::Format( SCH_SHEET* aSheet )
|
|||
{
|
||||
m_out->Print( 2, "(path %s\n",
|
||||
m_out->Quotew( instances[i].GetPath() ).c_str() );
|
||||
m_out->Print( 3, "(reference %s) (unit %d)\n",
|
||||
m_out->Print( 3, "(reference %s) (unit %d) (value %s) (footprint %s)\n",
|
||||
m_out->Quotew( instances[i].GetRef() ).c_str(),
|
||||
instances[i].GetUnit() );
|
||||
instances[i].GetUnit(),
|
||||
m_out->Quotew( instances[i].GetValue() ).c_str(),
|
||||
m_out->Quotew( instances[i].GetFootprint() ).c_str() );
|
||||
m_out->Print( 2, ")\n" );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -309,18 +309,6 @@ void SCH_SHEET_PATH::GetMultiUnitComponents( SCH_MULTI_UNIT_REFERENCE_MAP& aRefL
|
|||
}
|
||||
|
||||
|
||||
bool SCH_SHEET_PATH::SetComponentFootprint( const wxString& aReference, const wxString& aFootPrint,
|
||||
bool aSetVisible )
|
||||
{
|
||||
SCH_SCREEN* screen = LastScreen();
|
||||
|
||||
if( screen == NULL )
|
||||
return false;
|
||||
|
||||
return screen->SetComponentFootprint( this, aReference, aFootPrint, aSetVisible );
|
||||
}
|
||||
|
||||
|
||||
bool SCH_SHEET_PATH::operator==( const SCH_SHEET_PATH& d1 ) const
|
||||
{
|
||||
return m_current_hash == d1.GetCurrentHash();
|
||||
|
@ -704,18 +692,6 @@ void SCH_SHEET_LIST::GetMultiUnitComponents( SCH_MULTI_UNIT_REFERENCE_MAP &aRefL
|
|||
}
|
||||
|
||||
|
||||
bool SCH_SHEET_LIST::SetComponentFootprint( const wxString& aReference,
|
||||
const wxString& aFootPrint, bool aSetVisible )
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
for( SCH_SHEET_PATH& sheet : *this )
|
||||
found = sheet.SetComponentFootprint( aReference, aFootPrint, aSetVisible );
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
bool SCH_SHEET_LIST::TestForRecursion( const SCH_SHEET_LIST& aSrcSheetHierarchy,
|
||||
const wxString& aDestFileName )
|
||||
{
|
||||
|
@ -767,7 +743,7 @@ SCH_SHEET_PATH* SCH_SHEET_LIST::FindSheetForScreen( SCH_SCREEN* aScreen )
|
|||
|
||||
|
||||
void SCH_SHEET_LIST::UpdateSymbolInstances(
|
||||
const std::vector<COMPONENT_INSTANCE_REFERENCE>& aSymbolInstances )
|
||||
const std::vector<COMPONENT_INSTANCE_REFERENCE>& aSymbolInstances )
|
||||
{
|
||||
SCH_REFERENCE_LIST symbolInstances;
|
||||
|
||||
|
@ -777,15 +753,14 @@ void SCH_SHEET_LIST::UpdateSymbolInstances(
|
|||
|
||||
// Calculating the name of a path is somewhat expensive; on large designs with many components
|
||||
// this can blow up to a serious amount of time when loading the schematic
|
||||
auto getName =
|
||||
[&pathNameCache]( const KIID_PATH& aPath ) -> const wxString&
|
||||
{
|
||||
if( pathNameCache.count( aPath ) )
|
||||
return pathNameCache.at( aPath );
|
||||
auto getName = [&pathNameCache]( const KIID_PATH& aPath ) -> const wxString&
|
||||
{
|
||||
if( pathNameCache.count( aPath ) )
|
||||
return pathNameCache.at( aPath );
|
||||
|
||||
pathNameCache[aPath] = aPath.AsString();
|
||||
return pathNameCache[aPath];
|
||||
};
|
||||
pathNameCache[aPath] = aPath.AsString();
|
||||
return pathNameCache[aPath];
|
||||
};
|
||||
|
||||
for( size_t i = 0; i < symbolInstances.GetCount(); i++ )
|
||||
{
|
||||
|
@ -794,11 +769,10 @@ void SCH_SHEET_LIST::UpdateSymbolInstances(
|
|||
wxString path = symbolInstances[i].GetPath();
|
||||
|
||||
auto it = std::find_if( aSymbolInstances.begin(), aSymbolInstances.end(),
|
||||
[ path, &getName ]( const COMPONENT_INSTANCE_REFERENCE& r ) -> bool
|
||||
{
|
||||
return path == getName( r.m_Path );
|
||||
}
|
||||
);
|
||||
[ path, &getName ]( const COMPONENT_INSTANCE_REFERENCE& r ) -> bool
|
||||
{
|
||||
return path == getName( r.m_Path );
|
||||
} );
|
||||
|
||||
if( it == aSymbolInstances.end() )
|
||||
{
|
||||
|
@ -813,7 +787,8 @@ void SCH_SHEET_LIST::UpdateSymbolInstances(
|
|||
// Symbol instance paths are stored and looked up in memory with the root path so use
|
||||
// the full path here.
|
||||
symbol->AddHierarchicalReference( symbolInstances[i].GetSheetPath().Path(),
|
||||
it->m_Reference, it->m_Unit );
|
||||
it->m_Reference, it->m_Unit, it->m_Value,
|
||||
it->m_Footprint );
|
||||
symbol->GetField( REFERENCE )->SetText( it->m_Reference );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,8 +43,14 @@
|
|||
struct COMPONENT_INSTANCE_REFERENCE
|
||||
{
|
||||
KIID_PATH m_Path;
|
||||
|
||||
// Things that can be annotated:
|
||||
wxString m_Reference;
|
||||
int m_Unit;
|
||||
|
||||
// Things that can be back-annotated:
|
||||
wxString m_Value;
|
||||
wxString m_Footprint;
|
||||
};
|
||||
|
||||
|
||||
|
@ -276,19 +282,6 @@ public:
|
|||
void GetMultiUnitComponents( SCH_MULTI_UNIT_REFERENCE_MAP &aRefList,
|
||||
bool aIncludePowerSymbols = true ) const;
|
||||
|
||||
/**
|
||||
* Function SetFootprintField
|
||||
* searches last sheet in the path for a component with \a aReference and set the footprint
|
||||
* field to \a aFootPrint if found.
|
||||
*
|
||||
* @param aReference The reference designator of the component.
|
||||
* @param aFootPrint The value to set the footprint field.
|
||||
* @param aSetVisible The value to set the field visibility flag.
|
||||
* @return true if \a aReference was found otherwise false.
|
||||
*/
|
||||
bool SetComponentFootprint( const wxString& aReference, const wxString& aFootPrint,
|
||||
bool aSetVisible );
|
||||
|
||||
/**
|
||||
* Function TestForRecursion
|
||||
*
|
||||
|
@ -409,19 +402,6 @@ public:
|
|||
void GetMultiUnitComponents( SCH_MULTI_UNIT_REFERENCE_MAP &aRefList,
|
||||
bool aIncludePowerSymbols = true ) const;
|
||||
|
||||
/**
|
||||
* Function SetFootprintField
|
||||
* searches all the sheets for a component with \a aReference and set the footprint
|
||||
* field to \a aFootPrint if found.
|
||||
*
|
||||
* @param aReference The reference designator of the component.
|
||||
* @param aFootPrint The value to set the footprint field.
|
||||
* @param aSetVisible The value to set the field visibility flag.
|
||||
* @return True if \a aReference was found otherwise false.
|
||||
*/
|
||||
bool SetComponentFootprint( const wxString& aReference, const wxString& aFootPrint,
|
||||
bool aSetVisible );
|
||||
|
||||
/**
|
||||
* Function TestForRecursion
|
||||
*
|
||||
|
|
|
@ -33,6 +33,7 @@ end
|
|||
extends
|
||||
fill
|
||||
font
|
||||
footprint
|
||||
global_label
|
||||
hide
|
||||
hierarchical_label
|
||||
|
@ -117,6 +118,7 @@ type
|
|||
unit
|
||||
unspecified
|
||||
uuid
|
||||
value
|
||||
version
|
||||
width
|
||||
wire
|
||||
|
|
|
@ -68,8 +68,7 @@ void SCH_EDITOR_CONTROL::BackAnnotateFootprints( const std::string& aChangedSetO
|
|||
|
||||
wxString reference = (UTF8&) ref->second.front().first;
|
||||
|
||||
// Ensure the "fpid" node contains a footprint name,
|
||||
// and get it if exists
|
||||
// Ensure the "fpid" node contains a footprint name, and get it if exists
|
||||
if( ref->second.get_child( "fpid" ).size() )
|
||||
{
|
||||
wxString tmp = (UTF8&) ref->second.get_child( "fpid" ).front().first;
|
||||
|
@ -87,16 +86,17 @@ void SCH_EDITOR_CONTROL::BackAnnotateFootprints( const std::string& aChangedSetO
|
|||
// Note: it can be not unique (multiple parts per package)
|
||||
// So we *do not* stop the search here
|
||||
SCH_COMPONENT* component = refs[ii].GetComp();
|
||||
SCH_FIELD* fpfield = component->GetField( FOOTPRINT );
|
||||
const wxString& oldfp = fpfield->GetText();
|
||||
SCH_SHEET_PATH* sheetPath = &refs[ii].GetSheetPath();
|
||||
wxString oldfp = refs[ii].GetFootprint();
|
||||
|
||||
if( !oldfp && fpfield->IsVisible() )
|
||||
fpfield->SetVisible( false );
|
||||
if( oldfp.IsEmpty() && component->GetField( FOOTPRINT )->IsVisible() )
|
||||
component->GetField( FOOTPRINT )->SetVisible( false );
|
||||
|
||||
if( oldfp != footprint )
|
||||
{
|
||||
isChanged = true;
|
||||
|
||||
fpfield->SetText( footprint );
|
||||
component->SetFootprint( sheetPath, footprint );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -185,9 +185,9 @@ bool SCH_EDITOR_CONTROL::processCmpToFootprintLinkFile( const wxString& aFullFil
|
|||
// Note: it can be not unique (multiple units per part)
|
||||
// So we *do not* stop the search here
|
||||
SCH_COMPONENT* component = referencesList[ii].GetComp();
|
||||
SCH_FIELD* fpfield = component->GetField( FOOTPRINT );
|
||||
SCH_SHEET_PATH* sheetPath = &referencesList[ii].GetSheetPath();
|
||||
|
||||
fpfield->SetText( footprint );
|
||||
component->SetFootprint( sheetPath, footprint );
|
||||
|
||||
if( aForceVisibilityState )
|
||||
component->GetField( FOOTPRINT )->SetVisible( aVisibilityState );
|
||||
|
|
|
@ -80,7 +80,6 @@ bool BACK_ANNOTATE::BackAnnotateSymbols( const std::string& aNetlist )
|
|||
|
||||
getChangeList();
|
||||
checkForUnusedSymbols();
|
||||
checkSharedSchematicErrors();
|
||||
|
||||
applyChangelist();
|
||||
|
||||
|
@ -295,88 +294,6 @@ void BACK_ANNOTATE::checkForUnusedSymbols()
|
|||
}
|
||||
|
||||
|
||||
bool BACK_ANNOTATE::checkReuseViolation( PCB_MODULE_DATA& aFirst, PCB_MODULE_DATA& aSecond )
|
||||
{
|
||||
if( m_processFootprints && aFirst.m_footprint != aSecond.m_footprint )
|
||||
return false;
|
||||
|
||||
if( m_processValues && aFirst.m_value != aSecond.m_value )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BACK_ANNOTATE::checkSharedSchematicErrors()
|
||||
{
|
||||
std::sort( m_changelist.begin(), m_changelist.end(),
|
||||
[]( CHANGELIST_ITEM& a, CHANGELIST_ITEM& b )
|
||||
{
|
||||
return a.first.GetComp() > b.first.GetComp();
|
||||
} );
|
||||
|
||||
// We don't check that if no footprints or values updating
|
||||
if( !m_processFootprints && !m_processValues )
|
||||
return;
|
||||
|
||||
// We will count how many times every component used in our changelist
|
||||
// Component in this case is SCH_COMPONENT which can be used by more than one symbol
|
||||
int usageCount = 1;
|
||||
|
||||
for( auto it = m_changelist.begin(); it != m_changelist.end(); ++it )
|
||||
{
|
||||
int compUsage = it->first.GetComp()->GetInstanceReferences().size();
|
||||
|
||||
if( compUsage == 1 )
|
||||
continue;
|
||||
|
||||
// If that's not the last reference in list and references share same component
|
||||
if( ( it + 1 ) != m_changelist.end() && it->first.GetComp() == ( it + 1 )->first.GetComp() )
|
||||
{
|
||||
++usageCount;
|
||||
|
||||
if( !checkReuseViolation( *it->second, *( it + 1 )->second ) )
|
||||
{
|
||||
// Refs share same component but have different values or footprints
|
||||
it->first.GetComp()->SetFlags( SKIP_STRUCT );
|
||||
|
||||
wxString msg;
|
||||
msg.Printf( _( "\"%s\" and \"%s\" use the same schematic symbol.\n"
|
||||
"They cannot have different footprints or values." ),
|
||||
( it + 1 )->second->m_ref,
|
||||
it->second->m_ref );
|
||||
m_reporter.ReportTail( msg, RPT_SEVERITY_ERROR );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Next ref uses different component, so we count all components number for current
|
||||
one. We compare that number to stored in the component itself. If that differs, it
|
||||
means that this particular component is reused in some other project. */
|
||||
if( !m_ignoreOtherProjects && compUsage > usageCount )
|
||||
{
|
||||
SCH_COMPONENT* comp = it->first.GetComp();
|
||||
PCB_MODULE_DATA tmp{ "",
|
||||
comp->GetField( FOOTPRINT )->GetText(),
|
||||
comp->GetField( VALUE )->GetText(),
|
||||
{} };
|
||||
|
||||
if( !checkReuseViolation( tmp, *it->second ) )
|
||||
{
|
||||
it->first.GetComp()->SetFlags( SKIP_STRUCT );
|
||||
|
||||
wxString msg;
|
||||
msg.Printf( _( "Unable to change \"%s\" footprint or value because associated"
|
||||
" symbol is reused in the another project" ),
|
||||
it->second->m_ref );
|
||||
m_reporter.ReportTail( msg, RPT_SEVERITY_ERROR );
|
||||
}
|
||||
}
|
||||
usageCount = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BACK_ANNOTATE::applyChangelist()
|
||||
{
|
||||
std::set<wxString> handledNetChanges;
|
||||
|
@ -389,8 +306,8 @@ void BACK_ANNOTATE::applyChangelist()
|
|||
PCB_MODULE_DATA& module = *item.second;
|
||||
SCH_COMPONENT* comp = ref.GetComp();
|
||||
SCH_SCREEN* screen = ref.GetSheetPath().LastScreen();
|
||||
wxString oldFootprint = comp->GetField( FOOTPRINT )->GetText();
|
||||
wxString oldValue = comp->GetField( VALUE )->GetText();
|
||||
wxString oldFootprint = ref.GetFootprint();
|
||||
wxString oldValue = ref.GetValue();
|
||||
bool skip = ( ref.GetComp()->GetFlags() & SKIP_STRUCT ) > 0;
|
||||
|
||||
if( m_processReferences && ref.GetRef() != module.m_ref && !skip )
|
||||
|
@ -415,14 +332,14 @@ void BACK_ANNOTATE::applyChangelist()
|
|||
++m_changesCount;
|
||||
msg.Printf( _( "Change %s footprint from \"%s\" to \"%s\"." ),
|
||||
ref.GetFullRef(),
|
||||
comp->GetField( FOOTPRINT )->GetText(),
|
||||
oldFootprint,
|
||||
module.m_footprint );
|
||||
|
||||
if( !m_dryRun )
|
||||
{
|
||||
m_frame->SaveCopyInUndoList( screen, comp, UNDO_REDO::CHANGED, m_appendUndo );
|
||||
m_appendUndo = true;
|
||||
ref.GetComp()->GetField( FOOTPRINT )->SetText( module.m_footprint );
|
||||
comp->SetFootprint( &ref.GetSheetPath(), module.m_footprint );
|
||||
}
|
||||
|
||||
m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION );
|
||||
|
@ -433,14 +350,14 @@ void BACK_ANNOTATE::applyChangelist()
|
|||
++m_changesCount;
|
||||
msg.Printf( _( "Change %s value from \"%s\" to \"%s\"." ),
|
||||
ref.GetFullRef(),
|
||||
comp->GetField( VALUE )->GetText(),
|
||||
oldValue,
|
||||
module.m_value );
|
||||
|
||||
if( !m_dryRun )
|
||||
{
|
||||
m_frame->SaveCopyInUndoList( screen, comp, UNDO_REDO::CHANGED, m_appendUndo );
|
||||
m_appendUndo = true;
|
||||
comp->GetField( VALUE )->SetText( module.m_value );
|
||||
comp->SetValue( &ref.GetSheetPath(), module.m_value );
|
||||
}
|
||||
|
||||
m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION );
|
||||
|
|
|
@ -121,15 +121,6 @@ private:
|
|||
int m_changesCount; // Number of user-level changes
|
||||
bool m_appendUndo;
|
||||
|
||||
/**
|
||||
* @brief Check if modules has different data. Check only if corresponding \ref m_boardAdapter
|
||||
* flag is rised
|
||||
* @param aFirst first module to compare
|
||||
* @param aSecond second module to compare
|
||||
* @return true if no violation
|
||||
*/
|
||||
bool checkReuseViolation( PCB_MODULE_DATA& aFirst, PCB_MODULE_DATA& aSecond );
|
||||
|
||||
/**
|
||||
* @brief Parse netlist sent over KiWay epress mail interface and fill \ref m_pcbModules
|
||||
* @param aPayload - netlist from PCBnew
|
||||
|
@ -146,11 +137,6 @@ private:
|
|||
*/
|
||||
void checkForUnusedSymbols();
|
||||
|
||||
/**
|
||||
* @brief Check for errors connected to reusing schematic in project or between projects
|
||||
*/
|
||||
void checkSharedSchematicErrors();
|
||||
|
||||
/**
|
||||
* @brief Apply changelist to the schematic
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue