Don't use Clone() for duplicating. It returns the same UUID.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/14162
This commit is contained in:
Jeff Young 2023-09-03 19:05:33 +01:00
parent 911266fe02
commit c2057ba1bc
8 changed files with 30 additions and 29 deletions

View File

@ -112,6 +112,15 @@ bool LIB_ITEM::operator<( const LIB_ITEM& aOther ) const
} }
LIB_ITEM* LIB_ITEM::Duplicate() const
{
LIB_ITEM* dupe = static_cast<LIB_ITEM*>( Clone() );
const_cast<KIID&>( dupe->m_Uuid ) = KIID();
return dupe;
}
bool LIB_ITEM::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const bool LIB_ITEM::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
{ {
if( m_flags & (STRUCT_DELETED | SKIP_STRUCT ) ) if( m_flags & (STRUCT_DELETED | SKIP_STRUCT ) )

View File

@ -119,6 +119,11 @@ public:
return false; return false;
} }
/**
* Create a copy of this #LIB_ITEM (with a new Uuid).
*/
LIB_ITEM* Duplicate() const;
/** /**
* Begin drawing a symbol library draw item at \a aPosition. * Begin drawing a symbol library draw item at \a aPosition.
* *

View File

@ -1481,12 +1481,9 @@ int LIB_SYMBOL::GetMaxPinNumber() const
{ {
const LIB_PIN* pin = static_cast<const LIB_PIN*>( &item ); const LIB_PIN* pin = static_cast<const LIB_PIN*>( &item );
long currentPinNumber = 0; long currentPinNumber = 0;
bool isNum = pin->GetNumber().ToLong( &currentPinNumber );
if( isNum && currentPinNumber > maxPinNumber ) if( pin->GetNumber().ToLong( &currentPinNumber ) )
{ maxPinNumber = std::max( maxPinNumber, (int) currentPinNumber );
maxPinNumber = currentPinNumber;
}
} }
return maxPinNumber; return maxPinNumber;
@ -1598,7 +1595,7 @@ void LIB_SYMBOL::SetUnitCount( int aCount, bool aDuplicateDrawItems )
for( int j = prevCount + 1; j <= aCount; j++ ) for( int j = prevCount + 1; j <= aCount; j++ )
{ {
LIB_ITEM* newItem = (LIB_ITEM*) item.Clone(); LIB_ITEM* newItem = (LIB_ITEM*) item.Duplicate();
newItem->m_unit = j; newItem->m_unit = j;
tmp.push_back( newItem ); tmp.push_back( newItem );
} }
@ -1642,7 +1639,7 @@ void LIB_SYMBOL::SetConversion( bool aSetConvert, bool aDuplicatePins )
if( item.m_convert == 1 ) if( item.m_convert == 1 )
{ {
LIB_ITEM* newItem = (LIB_ITEM*) item.Clone(); LIB_ITEM* newItem = (LIB_ITEM*) item.Duplicate();
newItem->m_convert = 2; newItem->m_convert = 2;
tmp.push_back( newItem ); tmp.push_back( newItem );
} }

View File

@ -752,7 +752,7 @@ void SCH_EDIT_FRAME::AddCopyForRepeatItem( const SCH_ITEM* aItem )
if( aItem ) if( aItem )
{ {
std::unique_ptr<SCH_ITEM> repeatItem( static_cast<SCH_ITEM*>( aItem->Clone() ) ); std::unique_ptr<SCH_ITEM> repeatItem( static_cast<SCH_ITEM*>( aItem->Duplicate() ) );
// Clone() preserves the flags, we want 'em cleared. // Clone() preserves the flags, we want 'em cleared.
repeatItem->ClearFlags(); repeatItem->ClearFlags();

View File

@ -1726,7 +1726,7 @@ const LIB_SYMBOL* CADSTAR_SCH_ARCHIVE_LOADER::loadSymdef( const SYMDEF_ID& aSymd
RotatePoint( linePos, libtext->GetTextPos(), -libtext->GetTextAngle() ); RotatePoint( linePos, libtext->GetTextPos(), -libtext->GetTextAngle() );
LIB_TEXT* textLine = static_cast<LIB_TEXT*>( libtext->Clone() ); LIB_TEXT* textLine = static_cast<LIB_TEXT*>( libtext->Duplicate() );
textLine->SetText( strings[ii] ); textLine->SetText( strings[ii] );
textLine->SetHorizJustify( GR_TEXT_H_ALIGN_LEFT ); textLine->SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
textLine->SetVertJustify( GR_TEXT_V_ALIGN_BOTTOM ); textLine->SetVertJustify( GR_TEXT_V_ALIGN_BOTTOM );

View File

@ -795,7 +795,7 @@ int SYMBOL_EDITOR_EDIT_TOOL::Paste( const TOOL_EVENT& aEvent )
if( item.Type() == LIB_FIELD_T ) if( item.Type() == LIB_FIELD_T )
continue; continue;
LIB_ITEM* newItem = (LIB_ITEM*) item.Clone(); LIB_ITEM* newItem = (LIB_ITEM*) item.Duplicate();
newItem->SetParent( symbol ); newItem->SetParent( symbol );
newItem->SetFlags( IS_NEW | IS_PASTED | SELECTED ); newItem->SetFlags( IS_NEW | IS_PASTED | SELECTED );
@ -835,31 +835,21 @@ int SYMBOL_EDITOR_EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
if( selection.GetSize() == 0 ) if( selection.GetSize() == 0 )
return 0; return 0;
// Doing a duplicate of a new object doesn't really make any sense; we'd just end commit.Modify( symbol, m_frame->GetScreen() );
// up dragging around a stack of objects...
if( selection.Front()->IsNew() )
return 0;
if( !selection.Front()->IsMoving() )
commit.Modify( symbol, m_frame->GetScreen() );
EDA_ITEMS newItems; EDA_ITEMS newItems;
int symbolLastPinNumber = -1;
for( unsigned ii = 0; ii < selection.GetSize(); ++ii ) for( unsigned ii = 0; ii < selection.GetSize(); ++ii )
{ {
LIB_ITEM* oldItem = static_cast<LIB_ITEM*>( selection.GetItem( ii ) ); LIB_ITEM* oldItem = static_cast<LIB_ITEM*>( selection.GetItem( ii ) );
LIB_ITEM* newItem = (LIB_ITEM*) oldItem->Clone(); LIB_ITEM* newItem = static_cast<LIB_ITEM*>( oldItem->Duplicate() );
if( oldItem->Type() == LIB_PIN_T ) if( newItem->Type() == LIB_PIN_T )
{ {
if( symbolLastPinNumber == -1 ) LIB_PIN* newPin = static_cast<LIB_PIN*>( newItem );
{
symbolLastPinNumber = symbol->GetMaxPinNumber();
}
handlePinDuplication( static_cast<LIB_PIN*>( oldItem ), if( !newPin->GetNumber().IsEmpty() )
static_cast<LIB_PIN*>( newItem ), symbolLastPinNumber ); newPin->SetNumber( wxString::Format( wxT( "%i" ), symbol->GetMaxPinNumber() + 1 ) );
} }
oldItem->ClearFlags( IS_NEW | IS_PASTED | SELECTED ); oldItem->ClearFlags( IS_NEW | IS_PASTED | SELECTED );

View File

@ -339,7 +339,7 @@ void SYMBOL_EDITOR_PIN_TOOL::CreateImagePins( LIB_PIN* aPin )
if( ii == aPin->GetUnit() ) if( ii == aPin->GetUnit() )
continue; continue;
newPin = (LIB_PIN*) aPin->Clone(); newPin = (LIB_PIN*) aPin->Duplicate();
// To avoid mistakes, gives this pin a new pin number because // To avoid mistakes, gives this pin a new pin number because
// it does no have the save pin number as the master pin // it does no have the save pin number as the master pin
@ -409,7 +409,7 @@ int SYMBOL_EDITOR_PIN_TOOL::PushPinProperties( const TOOL_EVENT& aEvent )
// Create a new pin based on the previous pin with an incremented pin number. // Create a new pin based on the previous pin with an incremented pin number.
LIB_PIN* SYMBOL_EDITOR_PIN_TOOL::RepeatPin( const LIB_PIN* aSourcePin ) LIB_PIN* SYMBOL_EDITOR_PIN_TOOL::RepeatPin( const LIB_PIN* aSourcePin )
{ {
LIB_PIN* pin = (LIB_PIN*) aSourcePin->Clone(); LIB_PIN* pin = (LIB_PIN*) aSourcePin->Duplicate();
VECTOR2I step; VECTOR2I step;
pin->ClearFlags(); pin->ClearFlags();

View File

@ -266,7 +266,7 @@ public:
* *
* @return A clone of the item. * @return A clone of the item.
*/ */
virtual EDA_ITEM* Clone() const; // should not be inline, to save the ~ 6 bytes per call site. virtual EDA_ITEM* Clone() const;
/** /**
* May be re-implemented for each derived class in order to handle all the types given * May be re-implemented for each derived class in order to handle all the types given