Prune pasted data of non-enabled layers.
Fixes https://gitlab.com/kicad/code/kicad/issues/11997
This commit is contained in:
parent
aeb7447102
commit
5b3bd9be83
|
@ -182,6 +182,12 @@ public:
|
||||||
|
|
||||||
virtual void SetLayerSet( LSET aLayers )
|
virtual void SetLayerSet( LSET aLayers )
|
||||||
{
|
{
|
||||||
|
if( aLayers.count() == 1 )
|
||||||
|
{
|
||||||
|
SetLayer( aLayers.Seq()[0] );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
wxFAIL_MSG( wxT( "Attempted to SetLayerSet() on a single-layer object." ) );
|
wxFAIL_MSG( wxT( "Attempted to SetLayerSet() on a single-layer object." ) );
|
||||||
|
|
||||||
// Derived classes which support multiple layers must implement this
|
// Derived classes which support multiple layers must implement this
|
||||||
|
|
|
@ -696,6 +696,77 @@ static void pasteFootprintItemsToFootprintEditor( FOOTPRINT* aClipFootprint, BOA
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PCB_CONTROL::pruneItemLayers( std::vector<BOARD_ITEM*>& aItems )
|
||||||
|
{
|
||||||
|
LSET enabledLayers = board()->GetEnabledLayers();
|
||||||
|
std::vector<BOARD_ITEM*> returnItems;
|
||||||
|
bool fpItemDeleted = false;
|
||||||
|
|
||||||
|
auto processFPItem =
|
||||||
|
[&]( FOOTPRINT* aFootprint, BOARD_ITEM* aItem )
|
||||||
|
{
|
||||||
|
LSET allowed = aItem->GetLayerSet() & enabledLayers;
|
||||||
|
|
||||||
|
if( allowed.any() )
|
||||||
|
{
|
||||||
|
aItem->SetLayerSet( allowed );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
aFootprint->Remove( aItem );
|
||||||
|
fpItemDeleted = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for( BOARD_ITEM* item : aItems )
|
||||||
|
{
|
||||||
|
if( item->Type() == PCB_FOOTPRINT_T )
|
||||||
|
{
|
||||||
|
FOOTPRINT* fp = static_cast<FOOTPRINT*>( item );
|
||||||
|
|
||||||
|
if( !enabledLayers.test( fp->Reference().GetLayer() ) )
|
||||||
|
fp->Reference().SetLayer( fp->IsFlipped() ? B_SilkS : F_SilkS );
|
||||||
|
|
||||||
|
if( !enabledLayers.test( fp->Value().GetLayer() ) )
|
||||||
|
fp->Value().SetLayer( fp->IsFlipped() ? B_Fab : F_Fab );
|
||||||
|
|
||||||
|
// NOTE: all traversals from the back as processFPItem() might delete the item
|
||||||
|
|
||||||
|
for( int ii = static_cast<int>( fp->Pads().size() ) - 1; ii >= 0; ii-- )
|
||||||
|
processFPItem( fp, fp->Pads()[ii] );
|
||||||
|
|
||||||
|
for( int ii = static_cast<int>( fp->Zones().size() ) - 1; ii >= 0; ii-- )
|
||||||
|
processFPItem( fp, fp->Zones()[ii] );
|
||||||
|
|
||||||
|
for( int ii = static_cast<int>( fp->GraphicalItems().size() ) - 1; ii >= 0; ii-- )
|
||||||
|
processFPItem( fp, fp->GraphicalItems()[ii] );
|
||||||
|
|
||||||
|
if( fp->GraphicalItems().size() || fp->Pads().size() || fp->Zones().size() )
|
||||||
|
returnItems.push_back( fp );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LSET allowed = item->GetLayerSet() & enabledLayers;
|
||||||
|
|
||||||
|
if( allowed.any() )
|
||||||
|
{
|
||||||
|
item->SetLayerSet( allowed );
|
||||||
|
returnItems.push_back( item );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ( returnItems.size() < aItems.size() ) || fpItemDeleted )
|
||||||
|
{
|
||||||
|
DisplayError( m_frame, _( "Warning: some pasted items were on layers which are not "
|
||||||
|
"present in the current board.\n"
|
||||||
|
"These items could not be pasted.\n" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
aItems = returnItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int PCB_CONTROL::Paste( const TOOL_EVENT& aEvent )
|
int PCB_CONTROL::Paste( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
CLIPBOARD_IO pi;
|
CLIPBOARD_IO pi;
|
||||||
|
@ -803,6 +874,8 @@ int PCB_CONTROL::Paste( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
delete clipBoard;
|
delete clipBoard;
|
||||||
|
|
||||||
|
pruneItemLayers( pastedItems );
|
||||||
|
|
||||||
placeBoardItems( pastedItems, true, true, mode == PASTE_MODE::UNIQUE_ANNOTATIONS );
|
placeBoardItems( pastedItems, true, true, mode == PASTE_MODE::UNIQUE_ANNOTATIONS );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -841,6 +914,8 @@ int PCB_CONTROL::Paste( const TOOL_EVENT& aEvent )
|
||||||
pastedItems.push_back( clipFootprint );
|
pastedItems.push_back( clipFootprint );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pruneItemLayers( pastedItems );
|
||||||
|
|
||||||
placeBoardItems( pastedItems, true, true, mode == PASTE_MODE::UNIQUE_ANNOTATIONS );
|
placeBoardItems( pastedItems, true, true, mode == PASTE_MODE::UNIQUE_ANNOTATIONS );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -956,6 +1031,8 @@ int PCB_CONTROL::placeBoardItems( BOARD* aBoard, bool aAnchorAtOrigin, bool aRea
|
||||||
// selection created aBoard that has the group and all descendants in it.
|
// selection created aBoard that has the group and all descendants in it.
|
||||||
moveUnflaggedItems( aBoard->Groups(), items, isNew );
|
moveUnflaggedItems( aBoard->Groups(), items, isNew );
|
||||||
|
|
||||||
|
pruneItemLayers( items );
|
||||||
|
|
||||||
return placeBoardItems( items, isNew, aAnchorAtOrigin, aReannotateDuplicates );
|
return placeBoardItems( items, isNew, aAnchorAtOrigin, aReannotateDuplicates );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -109,6 +109,12 @@ private:
|
||||||
*/
|
*/
|
||||||
void unfilledZoneCheck();
|
void unfilledZoneCheck();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper for pasting. Remove non-enabled layers from the items in \a aItems. If an item
|
||||||
|
* exists only on non-enabled layers, it will be removed entirely.
|
||||||
|
*/
|
||||||
|
void pruneItemLayers( std::vector<BOARD_ITEM*>& aItems );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add and select or just select for move/place command a list of board items.
|
* Add and select or just select for move/place command a list of board items.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue