From 346b7178b75b67c75d02c5661eb13b1565584992 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Sat, 24 Oct 2020 21:55:32 +0100 Subject: [PATCH] Repair the way other units are collected when syncing symbol fields. Fixes https://gitlab.com/kicad/code/kicad/issues/6106 --- eeschema/dialogs/dialog_edit_one_field.cpp | 40 +++++++++++++------ eeschema/dialogs/dialog_symbol_properties.cpp | 15 ++++--- eeschema/ee_collectors.cpp | 24 ++++------- eeschema/ee_collectors.h | 2 +- 4 files changed, 47 insertions(+), 34 deletions(-) diff --git a/eeschema/dialogs/dialog_edit_one_field.cpp b/eeschema/dialogs/dialog_edit_one_field.cpp index 72801920bb..3d48cd6212 100644 --- a/eeschema/dialogs/dialog_edit_one_field.cpp +++ b/eeschema/dialogs/dialog_edit_one_field.cpp @@ -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. // Of course the component must be annotated to collect other units. - if( editFrame && parent && parent->Type() == SCH_COMPONENT_T - && ( fieldType == VALUE || fieldType == FOOTPRINT || fieldType == DATASHEET ) ) + if( editFrame && parent && parent->Type() == SCH_COMPONENT_T ) { - SCH_COMPONENT* thisUnit = static_cast( parent ); + SCH_COMPONENT* symbol = static_cast( parent ); - for( SCH_SHEET_PATH& sheet : editFrame->Schematic().GetSheets() ) + if( symbol->IsAnnotated( aSheetPath ) && ( fieldType == VALUE + || fieldType == FOOTPRINT + || fieldType == DATASHEET ) ) { - SCH_SCREEN* screen = sheet.LastScreen(); - std::vector otherUnits; + wxString ref = symbol->GetRef( aSheetPath ); + int unit = symbol->GetUnit(); - CollectOtherUnits( sheet, thisUnit, &otherUnits ); - - for( SCH_COMPONENT* otherUnit : otherUnits ) + for( SCH_SHEET_PATH& sheet : editFrame->Schematic().GetSheets() ) { - editFrame->SaveCopyInUndoList( screen, otherUnit, UNDO_REDO::CHANGED, true /* append */); - otherUnit->GetField( fieldType )->SetText( m_text ); - editFrame->UpdateItem( otherUnit ); + SCH_SCREEN* screen = sheet.LastScreen(); + std::vector otherUnits; + 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 ); + } } } } diff --git a/eeschema/dialogs/dialog_symbol_properties.cpp b/eeschema/dialogs/dialog_symbol_properties.cpp index 437f0e9192..7284e8515a 100644 --- a/eeschema/dialogs/dialog_symbol_properties.cpp +++ b/eeschema/dialogs/dialog_symbol_properties.cpp @@ -693,20 +693,25 @@ bool DIALOG_SYMBOL_PROPERTIES::TransferDataFromWindow() // The value, footprint and datasheet fields and exclude from bill of materials setting // 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() ) { SCH_SCREEN* screen = sheet.LastScreen(); std::vector otherUnits; + constexpr bool appendUndo = true; - CollectOtherUnits( sheet, m_comp, &otherUnits ); + CollectOtherUnits( ref, unit, sheet, &otherUnits ); for( SCH_COMPONENT* otherUnit : otherUnits ) { - GetParent()->SaveCopyInUndoList( screen, otherUnit, UNDO_REDO::CHANGED, true /* append */); - otherUnit->GetField( VALUE )->SetText( m_fields->at( VALUE ).GetText() ); - otherUnit->GetField( FOOTPRINT )->SetText( m_fields->at( FOOTPRINT ).GetText() ); + GetParent()->SaveCopyInUndoList( screen, otherUnit, UNDO_REDO::CHANGED, + appendUndo ); + otherUnit->SetValue( m_fields->at( VALUE ).GetText() ); + otherUnit->SetFootprint( m_fields->at( FOOTPRINT ).GetText() ); otherUnit->GetField( DATASHEET )->SetText( m_fields->at( DATASHEET ).GetText() ); otherUnit->SetIncludeInBom( !m_cbExcludeFromBom->IsChecked() ); otherUnit->SetIncludeOnBoard( !m_cbExcludeFromBoard->IsChecked() ); diff --git a/eeschema/ee_collectors.cpp b/eeschema/ee_collectors.cpp index c947511a71..3a4e76db05 100644 --- a/eeschema/ee_collectors.cpp +++ b/eeschema/ee_collectors.cpp @@ -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* otherUnits ) { - // Obviously, one can collect other units only if aUnit is annotated. - if( aUnit->GetUnitCount() > 1 && aUnit->IsAnnotated( &aSheet ) ) + SCH_REFERENCE_LIST components; + aSheet.GetComponents( components ); + + for( unsigned i = 0; i < components.GetCount(); i++ ) { - const LIB_ID thisLibId = aUnit->GetLibId(); - const wxString thisRef = aUnit->GetRef( &aSheet ); - int thisUnit = aUnit->GetUnit(); + SCH_REFERENCE component = components[i]; - SCH_REFERENCE_LIST components; - aSheet.GetComponents( components ); - - 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() ); - } + if( component.GetRef() == aRef && component.GetUnit() != aUnit ) + otherUnits->push_back( component.GetComp() ); } } diff --git a/eeschema/ee_collectors.h b/eeschema/ee_collectors.h index f8ffbdaa7c..ac272fa134 100644 --- a/eeschema/ee_collectors.h +++ b/eeschema/ee_collectors.h @@ -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* otherUnits ); #endif // EE_COLLECTORS_H