Improve delete-unused-layers to better handle multi-layer items.

Fixes https://gitlab.com/kicad/code/kicad/issues/5116
This commit is contained in:
Jeff Young 2020-08-09 12:22:09 +01:00
parent f2d91862c7
commit 4317881012
14 changed files with 93 additions and 86 deletions

View File

@ -181,11 +181,15 @@ public:
/** /**
* Function GetLayerSet * Function GetLayerSet
* returns a "layer mask", which is a bitmap of all layers on which the * returns a std::bitset of all layers on which the item physically resides.
* TRACK segment or VIA physically resides.
* @return int - a layer mask, see layers_id_colors_visibility.h.
*/ */
virtual LSET GetLayerSet() const { return LSET( m_Layer ); } virtual LSET GetLayerSet() const { return LSET( m_Layer ); }
virtual void SetLayerSet( LSET aLayers )
{
wxFAIL_MSG( "Attempted to SetLayerSet() on a single-layer object." );
// Derived classes which support multiple layers must implement this
}
/** /**
* Function SetLayer * Function SetLayer
@ -196,8 +200,6 @@ public:
*/ */
virtual void SetLayer( PCB_LAYER_ID aLayer ) virtual void SetLayer( PCB_LAYER_ID aLayer )
{ {
// trap any invalid layers, then go find the caller and fix it.
// wxASSERT( unsigned( aLayer ) < unsigned( NB_PCB_LAYERS ) );
m_Layer = aLayer; m_Layer = aLayer;
} }

View File

@ -87,19 +87,6 @@ MARKER_PCB* MARKER_PCB::Deserialize( const wxString& data )
} }
/* tests to see if this object is on the given layer.
* DRC markers are not really on a copper layer, but
* MARKER_PCB::IsOnCopperLayer return true if aLayer is a cooper layer,
* because this test is often used to locad a marker
* param aLayer The layer to test for.
* return bool - true if on given layer, else false.
*/
bool MARKER_PCB::IsOnLayer( PCB_LAYER_ID aLayer ) const
{
return IsCopperLayer( aLayer );
}
void MARKER_PCB::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) void MARKER_PCB::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
{ {
aList.emplace_back( _( "Type" ), _( "Marker" ), DARKCYAN ); aList.emplace_back( _( "Type" ), _( "Marker" ), DARKCYAN );

View File

@ -78,8 +78,6 @@ public:
return HitTestMarker( aPosition, aAccuracy ); return HitTestMarker( aPosition, aAccuracy );
} }
bool IsOnLayer( PCB_LAYER_ID aLayer ) const override;
GAL_LAYER_ID GetColorLayer() const; GAL_LAYER_ID GetColorLayer() const;
void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override; void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;

View File

@ -331,7 +331,7 @@ public:
bool IsDirty() const { return m_shapesDirty; } bool IsDirty() const { return m_shapesDirty; }
void SetLayerSet( LSET aLayerMask ) { m_layerMask = aLayerMask; } void SetLayerSet( LSET aLayers ) override { m_layerMask = aLayers; }
LSET GetLayerSet() const override { return m_layerMask; } LSET GetLayerSet() const override { return m_layerMask; }
void SetAttribute( PAD_ATTR_T aAttribute ); void SetAttribute( PAD_ATTR_T aAttribute );

View File

@ -397,6 +397,23 @@ LSET VIA::GetLayerSet() const
} }
void VIA::SetLayerSet( LSET aLayerSet )
{
bool first = true;
for( PCB_LAYER_ID layer : aLayerSet.Seq() )
{
if( first )
{
m_Layer = layer;
first = false;
}
m_BottomLayer = layer;
}
}
void VIA::SetLayerPair( PCB_LAYER_ID aTopLayer, PCB_LAYER_ID aBottomLayer ) void VIA::SetLayerPair( PCB_LAYER_ID aTopLayer, PCB_LAYER_ID aBottomLayer )
{ {

View File

@ -381,6 +381,7 @@ public:
bool IsOnLayer( PCB_LAYER_ID aLayer ) const override; bool IsOnLayer( PCB_LAYER_ID aLayer ) const override;
virtual LSET GetLayerSet() const override; virtual LSET GetLayerSet() const override;
virtual void SetLayerSet( LSET aLayers ) override;
/** /**
* Function SetLayerPair * Function SetLayerPair

View File

@ -107,8 +107,7 @@ public:
void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override; void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;
void SetLayerSet( LSET aLayerSet ); void SetLayerSet( LSET aLayerSet ) override;
virtual LSET GetLayerSet() const override; virtual LSET GetLayerSet() const override;
wxString GetZoneName() const { return m_zoneName; } wxString GetZoneName() const { return m_zoneName; }

View File

@ -586,12 +586,7 @@ SEARCH_RESULT PCB_LAYER_COLLECTOR::Inspect( EDA_ITEM* testItem, void* testData )
{ {
BOARD_ITEM* item = (BOARD_ITEM*) testItem; BOARD_ITEM* item = (BOARD_ITEM*) testItem;
if( item->Type() == PCB_PAD_T ) // multilayer if( item->IsOnLayer( m_layer_id ) )
{
if( static_cast<D_PAD*>( item )->IsOnLayer( m_layer_id ) )
Append( testItem );
}
else if( item->GetLayer() == m_layer_id )
Append( testItem ); Append( testItem );
return SEARCH_RESULT::CONTINUE; return SEARCH_RESULT::CONTINUE;

View File

@ -417,17 +417,15 @@ bool DIALOG_COPPER_ZONE::AcceptOptions( bool aUseExportableSetupOnly )
return true; return true;
// Get the layer selection for this zone // Get the layer selection for this zone
int layer = -1; int layers = 0;
for( int ii = 0; ii < m_layers->GetItemCount(); ++ii ) for( int ii = 0; ii < m_layers->GetItemCount(); ++ii )
{ {
if( m_layers->GetToggleValue( (unsigned) ii, 0 ) ) if( m_layers->GetToggleValue( (unsigned) ii, 0 ) )
{ layers++;
layer = ii;
break;
}
} }
if( layer < 0 ) if( layers == 0 )
{ {
DisplayError( this, _( "No layer selected." ) ); DisplayError( this, _( "No layer selected." ) );
return false; return false;
@ -468,10 +466,12 @@ void DIALOG_COPPER_ZONE::OnLayerSelection( wxDataViewEvent& event )
int row = m_layers->ItemToRow( event.GetItem() ); int row = m_layers->ItemToRow( event.GetItem() );
bool checked = m_layers->GetToggleValue( row, 0 );
wxVariant layerID; wxVariant layerID;
m_layers->GetValue( layerID, row, 2 ); m_layers->GetValue( layerID, row, 2 );
m_settings.m_Layers.set( ToLAYER_ID( layerID.GetInteger() ),
m_layers->GetToggleValue( row, 0 ) ); m_settings.m_Layers.set( ToLAYER_ID( layerID.GetInteger() ), checked );
} }

View File

@ -517,19 +517,26 @@ bool PANEL_SETUP_LAYERS::TransferDataFromWindow()
{ {
PCB_LAYER_COLLECTOR collector; PCB_LAYER_COLLECTOR collector;
for( auto layer_id : removedLayers ) for( PCB_LAYER_ID layer_id : removedLayers )
{ {
collector.SetLayerId( layer_id ); collector.SetLayerId( layer_id );
collector.Collect( m_pcb, GENERAL_COLLECTOR::BoardLevelItems ); collector.Collect( m_pcb, GENERAL_COLLECTOR::BoardLevelItems );
// Bye-bye items on removed layer. // Bye-bye items on removed layer.
if( collector.GetCount() != 0 ) for( int i = 0; i < collector.GetCount(); i++ )
{ {
BOARD_ITEM* item = collector[i];
LSET layers = item->GetLayerSet();
layers.reset( layer_id );
hasRemovedBoardItems = true; hasRemovedBoardItems = true;
for( int i = 0; i < collector.GetCount(); i++ ) if( layers.any() )
{
item->SetLayerSet( layers );
}
else
{ {
BOARD_ITEM* item = collector[i];
m_pcb->Remove( item ); m_pcb->Remove( item );
delete item; delete item;
} }
@ -756,13 +763,15 @@ bool PANEL_SETUP_LAYERS::compareCopperLayerCount( BOARD* aWorkingBoard, BOARD* a
if( newNumLayers < currNumLayers ) if( newNumLayers < currNumLayers )
{ {
wxMessageDialog dlg( this, wxString msg = wxString::Format( _( "Imported settings have fewer copper layers than "
wxString::Format( "the current board (%i instead of %i).\n\n"
wxT( "Imported settings have fewer copper layers than current board (%i instead of %i)." "Continue and delete the extra inner copper layers "
"\n\nContinue and delete extra inner copper layers from current board?" ), "from the current board?" ),
newNumLayers, currNumLayers ), newNumLayers,
_( "Inner Layers To Be Deleted" ), currNumLayers );
wxICON_WARNING | wxSTAY_ON_TOP | wxYES | wxNO | wxNO_DEFAULT );
wxMessageDialog dlg( this, msg, _( "Inner Layers To Be Deleted" ),
wxICON_WARNING | wxSTAY_ON_TOP | wxYES | wxNO | wxNO_DEFAULT );
if( wxID_NO == dlg.ShowModal() ) if( wxID_NO == dlg.ShowModal() )
okToDeleteCopperLayers = false; okToDeleteCopperLayers = false;

View File

@ -382,31 +382,30 @@ void FOOTPRINT_EDIT_FRAME::OnEditItemRequest( BOARD_ITEM* aItem )
case PCB_MODULE_ZONE_AREA_T: case PCB_MODULE_ZONE_AREA_T:
{ {
ZONE_CONTAINER* zone = static_cast<ZONE_CONTAINER*>( aItem ); ZONE_CONTAINER* zone = static_cast<ZONE_CONTAINER*>( aItem );
bool success = false; bool success = false;
if( zone ) ZONE_SETTINGS zoneSettings;
{
ZONE_SETTINGS zoneSettings;
zoneSettings << *zone;
if( zone->GetIsKeepout() )
{
success = InvokeKeepoutAreaEditor( this, &zoneSettings );
}
else if( zone->IsOnCopperLayer() )
{
success = InvokeCopperZonesEditor( this, &zoneSettings );
}
else
{
success = InvokeNonCopperZonesEditor( this, &zoneSettings );
}
if( success ) zoneSettings << *static_cast<ZONE_CONTAINER*>( aItem );
{
BOARD_COMMIT commit( this ); if( zone->GetIsKeepout() )
commit.Modify( zone ); {
commit.Push( _( "Edit Zone" ) ); success = InvokeKeepoutAreaEditor( this, &zoneSettings );
zoneSettings.ExportSetting( *zone ); }
} else if( zone->IsOnCopperLayer() )
{
success = InvokeCopperZonesEditor( this, &zoneSettings );
}
else
{
success = InvokeNonCopperZonesEditor( this, &zoneSettings );
}
if( success )
{
BOARD_COMMIT commit( this );
commit.Modify( zone );
commit.Push( _( "Edit Zone" ) );
zoneSettings.ExportSetting( *static_cast<ZONE_CONTAINER*>( aItem ) );
} }
} }
break; break;

View File

@ -51,16 +51,16 @@ ZONE_CREATE_HELPER::~ZONE_CREATE_HELPER()
std::unique_ptr<ZONE_CONTAINER> ZONE_CREATE_HELPER::createNewZone( bool aKeepout ) std::unique_ptr<ZONE_CONTAINER> ZONE_CREATE_HELPER::createNewZone( bool aKeepout )
{ {
auto& frame = *m_tool.getEditFrame<PCB_BASE_EDIT_FRAME>(); PCB_BASE_EDIT_FRAME* frame = m_tool.getEditFrame<PCB_BASE_EDIT_FRAME>();
auto& board = *m_tool.getModel<BOARD>(); BOARD* board = frame->GetBoard();
BOARD_ITEM_CONTAINER* parent = m_tool.m_frame->GetModel(); BOARD_ITEM_CONTAINER* parent = m_tool.m_frame->GetModel();
KIGFX::VIEW_CONTROLS* controls = m_tool.GetManager()->GetViewControls(); KIGFX::VIEW_CONTROLS* controls = m_tool.GetManager()->GetViewControls();
std::set<int> highlightedNets = board->GetHighLightNetCodes();
// Get the current default settings for zones // Get the current default settings for zones
ZONE_SETTINGS zoneInfo = frame.GetZoneSettings(); ZONE_SETTINGS zoneInfo = frame->GetZoneSettings();
zoneInfo.m_Layers.reset().set( m_params.m_layer ); // TODO(JE) multilayer defaults? zoneInfo.m_Layers.reset().set( m_params.m_layer ); // TODO(JE) multilayer defaults?
zoneInfo.m_NetcodeSelection = zoneInfo.m_NetcodeSelection = highlightedNets.empty() ? -1 : *highlightedNets.begin();
board.GetHighLightNetCodes().empty() ? -1 : *board.GetHighLightNetCodes().begin();
zoneInfo.SetIsKeepout( m_params.m_keepout ); zoneInfo.SetIsKeepout( m_params.m_keepout );
zoneInfo.m_Zone_45_Only = ( m_params.m_leaderMode == POLYGON_GEOM_MANAGER::LEADER_MODE::DEG45 ); zoneInfo.m_Zone_45_Only = ( m_params.m_leaderMode == POLYGON_GEOM_MANAGER::LEADER_MODE::DEG45 );
@ -84,14 +84,14 @@ std::unique_ptr<ZONE_CONTAINER> ZONE_CREATE_HELPER::createNewZone( bool aKeepout
int dialogResult; int dialogResult;
if( m_params.m_keepout ) if( m_params.m_keepout )
dialogResult = InvokeKeepoutAreaEditor( &frame, &zoneInfo ); dialogResult = InvokeKeepoutAreaEditor( frame, &zoneInfo );
else else
{ {
// TODO(JE) combine these dialogs? // TODO(JE) combine these dialogs?
if( ( zoneInfo.m_Layers & LSET::AllCuMask() ).any() ) if( ( zoneInfo.m_Layers & LSET::AllCuMask() ).any() )
dialogResult = InvokeCopperZonesEditor( &frame, &zoneInfo ); dialogResult = InvokeCopperZonesEditor( frame, &zoneInfo );
else else
dialogResult = InvokeNonCopperZonesEditor( &frame, &zoneInfo ); dialogResult = InvokeNonCopperZonesEditor( frame, &zoneInfo );
} }
if( dialogResult == wxID_CANCEL ) if( dialogResult == wxID_CANCEL )
@ -104,9 +104,9 @@ std::unique_ptr<ZONE_CONTAINER> ZONE_CREATE_HELPER::createNewZone( bool aKeepout
// and a MODULE_ZONE_CONTAINER if created in the footprint editor // and a MODULE_ZONE_CONTAINER if created in the footprint editor
wxASSERT( !m_tool.m_editModules || ( parent->Type() == PCB_MODULE_T ) ); wxASSERT( !m_tool.m_editModules || ( parent->Type() == PCB_MODULE_T ) );
auto newZone = m_tool.m_editModules ? std::unique_ptr<ZONE_CONTAINER> newZone = m_tool.m_editModules ?
std::make_unique<MODULE_ZONE_CONTAINER>( parent ) : std::make_unique<MODULE_ZONE_CONTAINER>( parent ) :
std::make_unique<ZONE_CONTAINER>( parent ); std::make_unique<ZONE_CONTAINER>( parent );
// Apply the selected settings // Apply the selected settings
zoneInfo.ExportSetting( *newZone ); zoneInfo.ExportSetting( *newZone );

View File

@ -185,6 +185,7 @@ const static wxSize LAYER_BITMAP_SIZE( 28, 28 ); // wxCocoa impl unhappy if thi
const static wxSize LAYER_BITMAP_SIZE( 24, 16 ); const static wxSize LAYER_BITMAP_SIZE( 24, 16 );
#endif #endif
// A helper for setting up a dialog list for specifying zone layers. Used by all three // A helper for setting up a dialog list for specifying zone layers. Used by all three
// zone settings dialogs. // zone settings dialogs.
void ZONE_SETTINGS::SetupLayersList( wxDataViewListCtrl* aList, PCB_BASE_FRAME* aFrame, void ZONE_SETTINGS::SetupLayersList( wxDataViewListCtrl* aList, PCB_BASE_FRAME* aFrame,
@ -195,8 +196,9 @@ void ZONE_SETTINGS::SetupLayersList( wxDataViewListCtrl* aList, PCB_BASE_FRAME*
LSET layers = aShowCopper ? LSET::AllCuMask( board->GetCopperLayerCount() ) LSET layers = aShowCopper ? LSET::AllCuMask( board->GetCopperLayerCount() )
: LSET::AllNonCuMask(); : LSET::AllNonCuMask();
// In the Footprint Editor In1_Cu is used as a proxy for "all inner layers"
if( aFpEditorMode ) if( aFpEditorMode )
layers.set( In1_Cu ); // a proxy for "all inner layers" layers.set( In1_Cu );
wxDataViewColumn* checkColumn = aList->AppendToggleColumn( wxEmptyString ); wxDataViewColumn* checkColumn = aList->AppendToggleColumn( wxEmptyString );
wxDataViewColumn* layerColumn = aList->AppendIconTextColumn( wxEmptyString ); wxDataViewColumn* layerColumn = aList->AppendIconTextColumn( wxEmptyString );

View File

@ -77,8 +77,6 @@ public:
return HitTestMarker( aPosition, aAccuracy ); return HitTestMarker( aPosition, aAccuracy );
} }
bool IsOnLayer( PCB_LAYER_ID aLayer ) const override;
GAL_LAYER_ID GetColorLayer() const; GAL_LAYER_ID GetColorLayer() const;
void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override; void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;