Prune pasted data of non-enabled layers.
Fixes https://gitlab.com/kicad/code/kicad/issues/11997
(cherry picked from commit 5b3bd9be83
)
This commit is contained in:
parent
bb7362ceba
commit
e21995c401
|
@ -148,6 +148,12 @@ public:
|
|||
virtual LSET GetLayerSet() const { return LSET( m_layer ); }
|
||||
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." ) );
|
||||
|
||||
// Derived classes which support multiple layers must implement this
|
||||
|
|
|
@ -724,6 +724,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 )
|
||||
{
|
||||
CLIPBOARD_IO pi;
|
||||
|
@ -813,6 +884,8 @@ int PCB_CONTROL::Paste( const TOOL_EVENT& aEvent )
|
|||
|
||||
delete clipBoard;
|
||||
|
||||
pruneItemLayers( pastedItems );
|
||||
|
||||
placeBoardItems( pastedItems, true, true,
|
||||
pasteMode == PASTE_MODE::UNIQUE_ANNOTATIONS );
|
||||
}
|
||||
|
@ -859,6 +932,8 @@ int PCB_CONTROL::Paste( const TOOL_EVENT& aEvent )
|
|||
pastedItems.push_back( clipFootprint );
|
||||
}
|
||||
|
||||
pruneItemLayers( pastedItems );
|
||||
|
||||
placeBoardItems( pastedItems, true, true, pasteMode == PASTE_MODE::UNIQUE_ANNOTATIONS );
|
||||
break;
|
||||
}
|
||||
|
@ -974,6 +1049,8 @@ int PCB_CONTROL::placeBoardItems( BOARD* aBoard, bool aAnchorAtOrigin, bool aRea
|
|||
// selection created aBoard that has the group and all descendants in it.
|
||||
moveUnflaggedItems( aBoard->Groups(), items, isNew );
|
||||
|
||||
pruneItemLayers( items );
|
||||
|
||||
return placeBoardItems( items, isNew, aAnchorAtOrigin, aReannotateDuplicates );
|
||||
}
|
||||
|
||||
|
|
|
@ -109,6 +109,12 @@ private:
|
|||
*/
|
||||
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.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue