Repair the way other units are collected when syncing symbol fields.

Fixes https://gitlab.com/kicad/code/kicad/issues/6106
This commit is contained in:
Jeff Young 2020-10-24 21:55:32 +01:00
parent 16b0689841
commit 346b7178b7
4 changed files with 47 additions and 34 deletions

View File

@ -425,23 +425,39 @@ void DIALOG_SCH_EDIT_ONE_FIELD::UpdateField( SCH_FIELD* aField, SCH_SHEET_PATH*
// The value, footprint and datasheet fields should be kept in sync in multi-unit parts. // The value, footprint and datasheet fields should be kept in sync in multi-unit parts.
// Of course the component must be annotated to collect other units. // Of course the component must be annotated to collect other units.
if( editFrame && parent && parent->Type() == SCH_COMPONENT_T if( editFrame && parent && parent->Type() == SCH_COMPONENT_T )
&& ( fieldType == VALUE || fieldType == FOOTPRINT || fieldType == DATASHEET ) )
{ {
SCH_COMPONENT* thisUnit = static_cast<SCH_COMPONENT*>( parent ); SCH_COMPONENT* symbol = static_cast<SCH_COMPONENT*>( parent );
for( SCH_SHEET_PATH& sheet : editFrame->Schematic().GetSheets() ) if( symbol->IsAnnotated( aSheetPath ) && ( fieldType == VALUE
|| fieldType == FOOTPRINT
|| fieldType == DATASHEET ) )
{ {
SCH_SCREEN* screen = sheet.LastScreen(); wxString ref = symbol->GetRef( aSheetPath );
std::vector<SCH_COMPONENT*> otherUnits; int unit = symbol->GetUnit();
CollectOtherUnits( sheet, thisUnit, &otherUnits ); for( SCH_SHEET_PATH& sheet : editFrame->Schematic().GetSheets() )
for( SCH_COMPONENT* otherUnit : otherUnits )
{ {
editFrame->SaveCopyInUndoList( screen, otherUnit, UNDO_REDO::CHANGED, true /* append */); SCH_SCREEN* screen = sheet.LastScreen();
otherUnit->GetField( fieldType )->SetText( m_text ); std::vector<SCH_COMPONENT*> otherUnits;
editFrame->UpdateItem( otherUnit ); constexpr bool appendUndo = true;
CollectOtherUnits( ref, unit, sheet, &otherUnits );
for( SCH_COMPONENT* otherUnit : otherUnits )
{
editFrame->SaveCopyInUndoList( screen, otherUnit, UNDO_REDO::CHANGED,
appendUndo );
if( fieldType == VALUE )
otherUnit->SetValue( m_text );
else if( fieldType == FOOTPRINT )
otherUnit->SetFootprint( m_text );
else
otherUnit->GetField( fieldType )->SetText( m_text );
editFrame->UpdateItem( otherUnit );
}
} }
} }
} }

View File

@ -693,20 +693,25 @@ bool DIALOG_SYMBOL_PROPERTIES::TransferDataFromWindow()
// The value, footprint and datasheet fields and exclude from bill of materials setting // The value, footprint and datasheet fields and exclude from bill of materials setting
// should be kept in sync in multi-unit parts. // should be kept in sync in multi-unit parts.
if( m_comp->GetUnitCount() > 1 ) if( m_comp->GetUnitCount() > 1 && m_comp->IsAnnotated( &GetParent()->GetCurrentSheet() ) )
{ {
wxString ref = m_comp->GetRef( &GetParent()->GetCurrentSheet() );
int unit = m_comp->GetUnit();
for( SCH_SHEET_PATH& sheet : GetParent()->Schematic().GetSheets() ) for( SCH_SHEET_PATH& sheet : GetParent()->Schematic().GetSheets() )
{ {
SCH_SCREEN* screen = sheet.LastScreen(); SCH_SCREEN* screen = sheet.LastScreen();
std::vector<SCH_COMPONENT*> otherUnits; std::vector<SCH_COMPONENT*> otherUnits;
constexpr bool appendUndo = true;
CollectOtherUnits( sheet, m_comp, &otherUnits ); CollectOtherUnits( ref, unit, sheet, &otherUnits );
for( SCH_COMPONENT* otherUnit : otherUnits ) for( SCH_COMPONENT* otherUnit : otherUnits )
{ {
GetParent()->SaveCopyInUndoList( screen, otherUnit, UNDO_REDO::CHANGED, true /* append */); GetParent()->SaveCopyInUndoList( screen, otherUnit, UNDO_REDO::CHANGED,
otherUnit->GetField( VALUE )->SetText( m_fields->at( VALUE ).GetText() ); appendUndo );
otherUnit->GetField( FOOTPRINT )->SetText( m_fields->at( FOOTPRINT ).GetText() ); otherUnit->SetValue( m_fields->at( VALUE ).GetText() );
otherUnit->SetFootprint( m_fields->at( FOOTPRINT ).GetText() );
otherUnit->GetField( DATASHEET )->SetText( m_fields->at( DATASHEET ).GetText() ); otherUnit->GetField( DATASHEET )->SetText( m_fields->at( DATASHEET ).GetText() );
otherUnit->SetIncludeInBom( !m_cbExcludeFromBom->IsChecked() ); otherUnit->SetIncludeInBom( !m_cbExcludeFromBom->IsChecked() );
otherUnit->SetIncludeOnBoard( !m_cbExcludeFromBoard->IsChecked() ); otherUnit->SetIncludeOnBoard( !m_cbExcludeFromBoard->IsChecked() );

View File

@ -186,26 +186,18 @@ bool EE_COLLECTOR::IsCorner() const
} }
void CollectOtherUnits( SCH_SHEET_PATH& aSheet, SCH_COMPONENT* aUnit, void CollectOtherUnits( const wxString& aRef, int aUnit, SCH_SHEET_PATH& aSheet,
std::vector<SCH_COMPONENT*>* otherUnits ) std::vector<SCH_COMPONENT*>* otherUnits )
{ {
// Obviously, one can collect other units only if aUnit is annotated. SCH_REFERENCE_LIST components;
if( aUnit->GetUnitCount() > 1 && aUnit->IsAnnotated( &aSheet ) ) aSheet.GetComponents( components );
for( unsigned i = 0; i < components.GetCount(); i++ )
{ {
const LIB_ID thisLibId = aUnit->GetLibId(); SCH_REFERENCE component = components[i];
const wxString thisRef = aUnit->GetRef( &aSheet );
int thisUnit = aUnit->GetUnit();
SCH_REFERENCE_LIST components; if( component.GetRef() == aRef && component.GetUnit() != aUnit )
aSheet.GetComponents( components ); otherUnits->push_back( component.GetComp() );
for( unsigned i = 0; i < components.GetCount(); i++ )
{
SCH_REFERENCE component = components[i];
if( component.GetRef() == thisRef && component.GetUnit() != thisUnit )
otherUnits->push_back( component.GetComp() );
}
} }
} }

View File

@ -111,7 +111,7 @@ public:
}; };
void CollectOtherUnits( SCH_SHEET_PATH& aSheet, SCH_COMPONENT* aUnit, void CollectOtherUnits( const wxString& thisRef, int thisUnit, SCH_SHEET_PATH& aSheet,
std::vector<SCH_COMPONENT*>* otherUnits ); std::vector<SCH_COMPONENT*>* otherUnits );
#endif // EE_COLLECTORS_H #endif // EE_COLLECTORS_H