Pcbnew, Fix issue when trying to create a drawing (line,circle,arc,polygon):

Display a error message if no free graphic layer is enabled, to switch from
a copper layer.

Fixes #3916
https://gitlab.com/kicad/code/kicad/issues/3916
This commit is contained in:
jean-pierre charras 2020-02-24 19:55:07 +01:00
parent a70cf464d6
commit d62fde0d79
2 changed files with 75 additions and 4 deletions

View File

@ -220,6 +220,12 @@ int DRAWING_TOOL::DrawLine( const TOOL_EVENT& aEvent )
if( m_editModules && !m_frame->GetModel() ) if( m_editModules && !m_frame->GetModel() )
return 0; return 0;
if( !hasDrawingLayerAvailable() )
{
wxMessageBox( _("No enabled graphic layer to create a graphic item") );
return 0;
}
BOARD_ITEM_CONTAINER* parent = m_frame->GetModel(); BOARD_ITEM_CONTAINER* parent = m_frame->GetModel();
DRAWSEGMENT* line = m_editModules ? new EDGE_MODULE( (MODULE*) parent ) : new DRAWSEGMENT; DRAWSEGMENT* line = m_editModules ? new EDGE_MODULE( (MODULE*) parent ) : new DRAWSEGMENT;
@ -264,6 +270,12 @@ int DRAWING_TOOL::DrawCircle( const TOOL_EVENT& aEvent )
if( m_editModules && !m_frame->GetModel() ) if( m_editModules && !m_frame->GetModel() )
return 0; return 0;
if( !hasDrawingLayerAvailable() )
{
wxMessageBox( _("No enabled graphic layer to create a graphic item") );
return 0;
}
BOARD_ITEM_CONTAINER* parent = m_frame->GetModel(); BOARD_ITEM_CONTAINER* parent = m_frame->GetModel();
DRAWSEGMENT* circle = m_editModules ? new EDGE_MODULE( (MODULE*) parent ) : new DRAWSEGMENT; DRAWSEGMENT* circle = m_editModules ? new EDGE_MODULE( (MODULE*) parent ) : new DRAWSEGMENT;
BOARD_COMMIT commit( m_frame ); BOARD_COMMIT commit( m_frame );
@ -301,6 +313,12 @@ int DRAWING_TOOL::DrawArc( const TOOL_EVENT& aEvent )
if( m_editModules && !m_frame->GetModel() ) if( m_editModules && !m_frame->GetModel() )
return 0; return 0;
if( !hasDrawingLayerAvailable() )
{
wxMessageBox( _("No enabled graphic layer to create a graphic item") );
return 0;
}
BOARD_ITEM_CONTAINER* parent = m_frame->GetModel(); BOARD_ITEM_CONTAINER* parent = m_frame->GetModel();
DRAWSEGMENT* arc = m_editModules ? new EDGE_MODULE( (MODULE*) parent ) : new DRAWSEGMENT; DRAWSEGMENT* arc = m_editModules ? new EDGE_MODULE( (MODULE*) parent ) : new DRAWSEGMENT;
BOARD_COMMIT commit( m_frame ); BOARD_COMMIT commit( m_frame );
@ -508,6 +526,12 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
if( m_editModules && !m_frame->GetModel() ) if( m_editModules && !m_frame->GetModel() )
return 0; return 0;
if( !hasDrawingLayerAvailable() )
{
wxMessageBox( _("No enabled graphic layer to create a graphic item") );
return 0;
}
DIMENSION* dimension = NULL; DIMENSION* dimension = NULL;
BOARD_COMMIT commit( m_frame ); BOARD_COMMIT commit( m_frame );
GRID_HELPER grid( m_frame ); GRID_HELPER grid( m_frame );
@ -1372,7 +1396,15 @@ int DRAWING_TOOL::drawZone( bool aKeepout, ZONE_MODE aMode )
params.m_sourceZone = sourceZone; params.m_sourceZone = sourceZone;
if( aMode == ZONE_MODE::GRAPHIC_POLYGON ) if( aMode == ZONE_MODE::GRAPHIC_POLYGON )
{
if( !hasDrawingLayerAvailable() )
{
wxMessageBox( _("No enabled graphic layer to create a graphic item") );
return 0;
}
params.m_layer = getDrawingLayer(); params.m_layer = getDrawingLayer();
}
else if( aMode == ZONE_MODE::SIMILAR ) else if( aMode == ZONE_MODE::SIMILAR )
params.m_layer = sourceZone->GetLayer(); params.m_layer = sourceZone->GetLayer();
else else
@ -1828,19 +1860,40 @@ int DRAWING_TOOL::getSegmentWidth( PCB_LAYER_ID aLayer ) const
return m_board->GetDesignSettings().GetLineThickness( aLayer ); return m_board->GetDesignSettings().GetLineThickness( aLayer );
} }
// A list of suitable layers for drawings, used in getDrawingLayer() to
// automatically switch from a copper layer to a not specialized drawing layer
// and hasDrawingLayerAvailable()
static LSET suitableDrawLayers( 4, F_SilkS, B_SilkS, Dwgs_User, Cmts_User );
PCB_LAYER_ID DRAWING_TOOL::getDrawingLayer() const PCB_LAYER_ID DRAWING_TOOL::getDrawingLayer() const
{ {
// at least one of suitableDrawLayers is expected enabled
PCB_LAYER_ID layer = m_frame->GetActiveLayer(); PCB_LAYER_ID layer = m_frame->GetActiveLayer();
LSET enabledLayer = m_frame->GetBoard()->GetEnabledLayers();
if( IsCopperLayer( layer ) ) if( IsCopperLayer( layer ) )
{ {
wxASSERT( hasDrawingLayerAvailable() );
layer = Dwgs_User;
if( !enabledLayer[Dwgs_User] )
layer = Cmts_User;
if( layer == F_Cu ) if( layer == F_Cu )
layer = F_SilkS; {
if( enabledLayer[F_SilkS] )
layer = F_SilkS;
else if( enabledLayer[B_SilkS] )
layer = B_SilkS;
}
else if( layer == B_Cu ) else if( layer == B_Cu )
layer = B_SilkS; {
else if( enabledLayer[B_SilkS] )
layer = Dwgs_User; layer = B_SilkS;
else if( enabledLayer[F_SilkS] )
layer = F_SilkS;
}
m_frame->SetActiveLayer( layer ); m_frame->SetActiveLayer( layer );
} }
@ -1849,4 +1902,18 @@ PCB_LAYER_ID DRAWING_TOOL::getDrawingLayer() const
} }
bool DRAWING_TOOL::hasDrawingLayerAvailable() const
{
PCB_LAYER_ID layer = m_frame->GetActiveLayer();
if( !IsCopperLayer( layer ) ) // Already on a non copper layer
return true;
// If the active layer is a copper layer, see if a graphic layer is available
LSET enabledLayer = m_frame->GetBoard()->GetEnabledLayers();
return ( enabledLayer & suitableDrawLayers ).any();
}
const unsigned int DRAWING_TOOL::WIDTH_STEP = Millimeter2iu( 0.1 ); const unsigned int DRAWING_TOOL::WIDTH_STEP = Millimeter2iu( 0.1 );

View File

@ -258,6 +258,10 @@ private:
///> Selects a non-copper layer for drawing ///> Selects a non-copper layer for drawing
PCB_LAYER_ID getDrawingLayer() const; PCB_LAYER_ID getDrawingLayer() const;
///> Test for a enabled non-copper layer suitable for drawing
///> @return true if at lesat one is enabled
bool hasDrawingLayerAvailable() const;
KIGFX::VIEW* m_view; KIGFX::VIEW* m_view;
KIGFX::VIEW_CONTROLS* m_controls; KIGFX::VIEW_CONTROLS* m_controls;
BOARD* m_board; BOARD* m_board;