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
{
if( m_flags & (STRUCT_DELETED | SKIP_STRUCT ) )

View File

@ -119,6 +119,11 @@ public:
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.
*

View File

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

View File

@ -752,7 +752,7 @@ void SCH_EDIT_FRAME::AddCopyForRepeatItem( const SCH_ITEM* 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.
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() );
LIB_TEXT* textLine = static_cast<LIB_TEXT*>( libtext->Clone() );
LIB_TEXT* textLine = static_cast<LIB_TEXT*>( libtext->Duplicate() );
textLine->SetText( strings[ii] );
textLine->SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
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 )
continue;
LIB_ITEM* newItem = (LIB_ITEM*) item.Clone();
LIB_ITEM* newItem = (LIB_ITEM*) item.Duplicate();
newItem->SetParent( symbol );
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 )
return 0;
// Doing a duplicate of a new object doesn't really make any sense; we'd just end
// up dragging around a stack of objects...
if( selection.Front()->IsNew() )
return 0;
if( !selection.Front()->IsMoving() )
commit.Modify( symbol, m_frame->GetScreen() );
commit.Modify( symbol, m_frame->GetScreen() );
EDA_ITEMS newItems;
int symbolLastPinNumber = -1;
for( unsigned ii = 0; ii < selection.GetSize(); ++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 )
{
symbolLastPinNumber = symbol->GetMaxPinNumber();
}
LIB_PIN* newPin = static_cast<LIB_PIN*>( newItem );
handlePinDuplication( static_cast<LIB_PIN*>( oldItem ),
static_cast<LIB_PIN*>( newItem ), symbolLastPinNumber );
if( !newPin->GetNumber().IsEmpty() )
newPin->SetNumber( wxString::Format( wxT( "%i" ), symbol->GetMaxPinNumber() + 1 ) );
}
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() )
continue;
newPin = (LIB_PIN*) aPin->Clone();
newPin = (LIB_PIN*) aPin->Duplicate();
// To avoid mistakes, gives this pin a new pin number because
// 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.
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;
pin->ClearFlags();

View File

@ -266,7 +266,7 @@ public:
*
* @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