From b5960dfb40a1cd28dddd3ef4b5ead121e16f08ed Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Fri, 24 Jul 2020 18:02:56 +0200 Subject: [PATCH] class D_PAD: add Copy ctor and operator =. Due to the fact basic primitives for custom pads are now managed by a list of pointer, the default copy ctor and default operator = do not work (the basic primitives list must be duplicated). It fixes issues related to primitives list id pad edition, footprint edition and undo/redo Fixes #4958 https://gitlab.com/kicad/code/kicad/issues/4958 --- pcbnew/class_pad.cpp | 24 ++++++++++++++++++++++- pcbnew/class_pad.h | 25 ++++++++++++++++++------ pcbnew/dialogs/dialog_pad_properties.cpp | 4 ++-- pcbnew/pad_custom_shape_functions.cpp | 14 +++++++------ 4 files changed, 52 insertions(+), 15 deletions(-) diff --git a/pcbnew/class_pad.cpp b/pcbnew/class_pad.cpp index 199dc67453..173b6cf424 100644 --- a/pcbnew/class_pad.cpp +++ b/pcbnew/class_pad.cpp @@ -96,6 +96,28 @@ D_PAD::D_PAD( MODULE* parent ) : } +D_PAD::D_PAD( const D_PAD& aOther ) : + BOARD_CONNECTED_ITEM( aOther.GetParent(), PCB_PAD_T ) +{ + BOARD_CONNECTED_ITEM::operator=( aOther ); + ImportSettingsFrom( aOther ); + SetPosition( aOther.GetPosition() ); + SetPos0( aOther.GetPos0() ); +} + + +D_PAD& D_PAD::operator=( const D_PAD &aOther ) +{ + BOARD_CONNECTED_ITEM::operator=( aOther ); + + ImportSettingsFrom( aOther ); + SetPosition( aOther.GetPosition() ); + SetPos0( aOther.GetPos0() ); + + return *this; +} + + LSET D_PAD::StandardMask() { static LSET saved = LSET::AllCuMask() | LSET( 2, B_Mask, F_Mask ); @@ -1210,7 +1232,7 @@ void D_PAD::ImportSettingsFrom( const D_PAD& aMasterPad ) SetThermalGap( aMasterPad.GetThermalGap() ); // Add or remove custom pad shapes: - SetPrimitives( aMasterPad.GetPrimitives() ); + ReplacePrimitives( aMasterPad.GetPrimitives() ); SetAnchorPadShape( aMasterPad.GetAnchorPadShape() ); m_shapesDirty = true; diff --git a/pcbnew/class_pad.h b/pcbnew/class_pad.h index 7d04fc5ed5..c5253a2c04 100644 --- a/pcbnew/class_pad.h +++ b/pcbnew/class_pad.h @@ -65,8 +65,10 @@ class D_PAD : public BOARD_CONNECTED_ITEM public: D_PAD( MODULE* parent ); - // Do not create a copy constructor & operator=. - // The ones generated by the compiler are adequate. + // Copy constructor & operator= are needed because the list of basic shapes + // must be duplicated in copy. + D_PAD( const D_PAD& aPad ); + D_PAD& operator=( const D_PAD &aOther ); /* * Default layers used for pads, according to the pad type. @@ -285,14 +287,25 @@ public: void MirrorXPrimitives( int aX ); /** - * Import to the basic shape list + * Clear the current primitive list and import a basic shape (primitive) list. + * Each item is a duplicate of the initial items in list, + * so the initial list in not modified and not managed by this pad */ - void SetPrimitives( const std::vector>& aPrimitivesList ); + void ReplacePrimitives( const std::vector>& aPrimitivesList ); /** - * Add to the basic shape list + * Import a basic shape (primitive) list and add items to the current list. + * Each item is a duplicate of the initial items in list, + * so the initial list in not modified and not managed by this pad + */ + void AppendPrimitives( const std::vector>& aPrimitivesList ); + + /** + * Add items to the basic shape list + */ + /** + * Add item to the primitive shape list */ - void AddPrimitives( const std::vector>& aPrimitivesList ); void AddPrimitive( DRAWSEGMENT* aPrimitive ); /** diff --git a/pcbnew/dialogs/dialog_pad_properties.cpp b/pcbnew/dialogs/dialog_pad_properties.cpp index 40938d7bc8..db9a231dbd 100644 --- a/pcbnew/dialogs/dialog_pad_properties.cpp +++ b/pcbnew/dialogs/dialog_pad_properties.cpp @@ -1371,7 +1371,7 @@ bool DIALOG_PAD_PROPERTIES::TransferDataFromWindow() m_currentPad->SetAnchorPadShape( m_padMaster->GetAnchorPadShape() ); - m_currentPad->SetPrimitives( m_padMaster->GetPrimitives() ); + m_currentPad->ReplacePrimitives( m_padMaster->GetPrimitives() ); if( m_isFlipped ) { @@ -1474,7 +1474,7 @@ bool DIALOG_PAD_PROPERTIES::transferDataToPad( D_PAD* aPad ) PAD_SHAPE_RECT : PAD_SHAPE_CIRCLE ); if( aPad->GetShape() == PAD_SHAPE_CUSTOM ) - aPad->SetPrimitives( m_primitives ); + aPad->ReplacePrimitives( m_primitives ); // Read pad clearances values: aPad->SetLocalClearance( m_clearance.GetValue() ); diff --git a/pcbnew/pad_custom_shape_functions.cpp b/pcbnew/pad_custom_shape_functions.cpp index 0d250c82b2..1a33cbede5 100644 --- a/pcbnew/pad_custom_shape_functions.cpp +++ b/pcbnew/pad_custom_shape_functions.cpp @@ -135,23 +135,24 @@ void D_PAD::AddPrimitiveRect( const wxPoint& aStart, const wxPoint& aEnd, int aT } -void D_PAD::SetPrimitives( const std::vector>& aPrimitivesList ) +void D_PAD::ReplacePrimitives( const std::vector>& aPrimitivesList ) { // clear old list - m_editPrimitives.clear(); + DeletePrimitivesList(); - // Import to the basic shape list + // Import to the given shape list if( aPrimitivesList.size() ) - m_editPrimitives = aPrimitivesList; + AppendPrimitives( aPrimitivesList ); m_shapesDirty = true; } -void D_PAD::AddPrimitives( const std::vector>& aPrimitivesList ) +void D_PAD::AppendPrimitives( const std::vector>& aPrimitivesList ) { + // Add duplicates of aPrimitivesList to the pad primitives list: for( const std::shared_ptr& prim : aPrimitivesList ) - m_editPrimitives.push_back( prim ); + AddPrimitive( new DRAWSEGMENT( *prim ) ); m_shapesDirty = true; } @@ -169,6 +170,7 @@ void D_PAD::AddPrimitive( DRAWSEGMENT* aPrimitive ) void D_PAD::DeletePrimitivesList() { m_editPrimitives.clear(); + m_shapesDirty = true; }