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
This commit is contained in:
jean-pierre charras 2020-07-24 18:02:56 +02:00
parent f97c50bfde
commit b5960dfb40
4 changed files with 52 additions and 15 deletions

View File

@ -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() LSET D_PAD::StandardMask()
{ {
static LSET saved = LSET::AllCuMask() | LSET( 2, B_Mask, F_Mask ); 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() ); SetThermalGap( aMasterPad.GetThermalGap() );
// Add or remove custom pad shapes: // Add or remove custom pad shapes:
SetPrimitives( aMasterPad.GetPrimitives() ); ReplacePrimitives( aMasterPad.GetPrimitives() );
SetAnchorPadShape( aMasterPad.GetAnchorPadShape() ); SetAnchorPadShape( aMasterPad.GetAnchorPadShape() );
m_shapesDirty = true; m_shapesDirty = true;

View File

@ -65,8 +65,10 @@ class D_PAD : public BOARD_CONNECTED_ITEM
public: public:
D_PAD( MODULE* parent ); D_PAD( MODULE* parent );
// Do not create a copy constructor & operator=. // Copy constructor & operator= are needed because the list of basic shapes
// The ones generated by the compiler are adequate. // 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. * Default layers used for pads, according to the pad type.
@ -285,14 +287,25 @@ public:
void MirrorXPrimitives( int aX ); 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<std::shared_ptr<DRAWSEGMENT>>& aPrimitivesList ); void ReplacePrimitives( const std::vector<std::shared_ptr<DRAWSEGMENT>>& 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<std::shared_ptr<DRAWSEGMENT>>& aPrimitivesList );
/**
* Add items to the basic shape list
*/
/**
* Add item to the primitive shape list
*/ */
void AddPrimitives( const std::vector<std::shared_ptr<DRAWSEGMENT>>& aPrimitivesList );
void AddPrimitive( DRAWSEGMENT* aPrimitive ); void AddPrimitive( DRAWSEGMENT* aPrimitive );
/** /**

View File

@ -1371,7 +1371,7 @@ bool DIALOG_PAD_PROPERTIES::TransferDataFromWindow()
m_currentPad->SetAnchorPadShape( m_padMaster->GetAnchorPadShape() ); m_currentPad->SetAnchorPadShape( m_padMaster->GetAnchorPadShape() );
m_currentPad->SetPrimitives( m_padMaster->GetPrimitives() ); m_currentPad->ReplacePrimitives( m_padMaster->GetPrimitives() );
if( m_isFlipped ) if( m_isFlipped )
{ {
@ -1474,7 +1474,7 @@ bool DIALOG_PAD_PROPERTIES::transferDataToPad( D_PAD* aPad )
PAD_SHAPE_RECT : PAD_SHAPE_CIRCLE ); PAD_SHAPE_RECT : PAD_SHAPE_CIRCLE );
if( aPad->GetShape() == PAD_SHAPE_CUSTOM ) if( aPad->GetShape() == PAD_SHAPE_CUSTOM )
aPad->SetPrimitives( m_primitives ); aPad->ReplacePrimitives( m_primitives );
// Read pad clearances values: // Read pad clearances values:
aPad->SetLocalClearance( m_clearance.GetValue() ); aPad->SetLocalClearance( m_clearance.GetValue() );

View File

@ -135,23 +135,24 @@ void D_PAD::AddPrimitiveRect( const wxPoint& aStart, const wxPoint& aEnd, int aT
} }
void D_PAD::SetPrimitives( const std::vector<std::shared_ptr<DRAWSEGMENT>>& aPrimitivesList ) void D_PAD::ReplacePrimitives( const std::vector<std::shared_ptr<DRAWSEGMENT>>& aPrimitivesList )
{ {
// clear old list // clear old list
m_editPrimitives.clear(); DeletePrimitivesList();
// Import to the basic shape list // Import to the given shape list
if( aPrimitivesList.size() ) if( aPrimitivesList.size() )
m_editPrimitives = aPrimitivesList; AppendPrimitives( aPrimitivesList );
m_shapesDirty = true; m_shapesDirty = true;
} }
void D_PAD::AddPrimitives( const std::vector<std::shared_ptr<DRAWSEGMENT>>& aPrimitivesList ) void D_PAD::AppendPrimitives( const std::vector<std::shared_ptr<DRAWSEGMENT>>& aPrimitivesList )
{ {
// Add duplicates of aPrimitivesList to the pad primitives list:
for( const std::shared_ptr<DRAWSEGMENT>& prim : aPrimitivesList ) for( const std::shared_ptr<DRAWSEGMENT>& prim : aPrimitivesList )
m_editPrimitives.push_back( prim ); AddPrimitive( new DRAWSEGMENT( *prim ) );
m_shapesDirty = true; m_shapesDirty = true;
} }
@ -169,6 +170,7 @@ void D_PAD::AddPrimitive( DRAWSEGMENT* aPrimitive )
void D_PAD::DeletePrimitivesList() void D_PAD::DeletePrimitivesList()
{ {
m_editPrimitives.clear(); m_editPrimitives.clear();
m_shapesDirty = true; m_shapesDirty = true;
} }