diff --git a/eeschema/component_references_lister.cpp b/eeschema/component_references_lister.cpp index 45872e7ac5..09235f70f9 100644 --- a/eeschema/component_references_lister.cpp +++ b/eeschema/component_references_lister.cpp @@ -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 ); } diff --git a/eeschema/erc.cpp b/eeschema/erc.cpp index 1065d0cae8..8defe81daa 100644 --- a/eeschema/erc.cpp +++ b/eeschema/erc.cpp @@ -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& 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 ) diff --git a/eeschema/files-io.cpp b/eeschema/files-io.cpp index 746d867833..35e95c10bd 100644 --- a/eeschema/files-io.cpp +++ b/eeschema/files-io.cpp @@ -926,7 +926,7 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType ) SCH_COMPONENT* cmp = static_cast( 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() ) { diff --git a/eeschema/sch_component.cpp b/eeschema/sch_component.cpp index cbbee4da0b..e394e09578 100644 --- a/eeschema/sch_component.cpp +++ b/eeschema/sch_component.cpp @@ -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( 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( 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( 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 = _( "" ); aList.push_back( MSG_PANEL_ITEM( _( "Footprint" ), msg, DARKRED ) ); diff --git a/eeschema/sch_component.h b/eeschema/sch_component.h index 386968a9fa..93eacd9a46 100644 --- a/eeschema/sch_component.h +++ b/eeschema/sch_component.h @@ -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 diff --git a/eeschema/sch_file_versions.h b/eeschema/sch_file_versions.h index c175fa42fa..9b51d14759 100644 --- a/eeschema/sch_file_versions.h +++ b/eeschema/sch_file_versions.h @@ -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. diff --git a/eeschema/sch_reference_list.h b/eeschema/sch_reference_list.h index f53378f929..946de2ce73 100644 --- a/eeschema/sch_reference_list.h +++ b/eeschema/sch_reference_list.h @@ -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 diff --git a/eeschema/sch_screen.cpp b/eeschema/sch_screen.cpp index d7491f541d..cf825a90af 100644 --- a/eeschema/sch_screen.cpp +++ b/eeschema/sch_screen.cpp @@ -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( 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 */ ); diff --git a/eeschema/sch_screen.h b/eeschema/sch_screen.h index 275788b0e0..332413ff21 100644 --- a/eeschema/sch_screen.h +++ b/eeschema/sch_screen.h @@ -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. diff --git a/eeschema/sch_sexpr_parser.cpp b/eeschema/sch_sexpr_parser.cpp index cdfafd96fb..a9f8fa001b 100644 --- a/eeschema/sch_sexpr_parser.cpp +++ b/eeschema/sch_sexpr_parser.cpp @@ -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" ); } } diff --git a/eeschema/sch_sexpr_plugin.cpp b/eeschema/sch_sexpr_plugin.cpp index 0bcb788ea2..37fcfb5653 100644 --- a/eeschema/sch_sexpr_plugin.cpp +++ b/eeschema/sch_sexpr_plugin.cpp @@ -20,8 +20,6 @@ */ #include -#include -#include // For some reason wxWidgets is built with wxUSE_BASE64 unset so expose the wxWidgets // base64 code. @@ -29,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -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" ); } } diff --git a/eeschema/sch_sheet_path.cpp b/eeschema/sch_sheet_path.cpp index eb3cfa0ab9..f56d834387 100644 --- a/eeschema/sch_sheet_path.cpp +++ b/eeschema/sch_sheet_path.cpp @@ -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& aSymbolInstances ) + const std::vector& 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 ); } } diff --git a/eeschema/sch_sheet_path.h b/eeschema/sch_sheet_path.h index 14d7f847fc..96d6199964 100644 --- a/eeschema/sch_sheet_path.h +++ b/eeschema/sch_sheet_path.h @@ -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 * diff --git a/eeschema/schematic.keywords b/eeschema/schematic.keywords index 98fec3ee84..2f3c3dd726 100644 --- a/eeschema/schematic.keywords +++ b/eeschema/schematic.keywords @@ -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 diff --git a/eeschema/tools/backanno.cpp b/eeschema/tools/backanno.cpp index 6702afb4eb..61dbf9685c 100644 --- a/eeschema/tools/backanno.cpp +++ b/eeschema/tools/backanno.cpp @@ -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 ); diff --git a/eeschema/tools/backannotate.cpp b/eeschema/tools/backannotate.cpp index 5453c38ed2..0e52499ed1 100644 --- a/eeschema/tools/backannotate.cpp +++ b/eeschema/tools/backannotate.cpp @@ -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 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 ); diff --git a/eeschema/tools/backannotate.h b/eeschema/tools/backannotate.h index 06be4835ba..9509fe706f 100644 --- a/eeschema/tools/backannotate.h +++ b/eeschema/tools/backannotate.h @@ -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 */