Better approximation for pads in Export Gerber to Pcbnew

We can't get all the way there because we can't create pads outside
of modules and the Gerbers don't store any grouping/footprint info.
This change moves us from outputing a via for every flashed item
(some of which don't even have holes) to synthesizing pads from
flashed items using a via (when they have holes) and a copper polygon.

This is much better for SMD pads, perhaps better for regular pads,
and no worse for vias.
This commit is contained in:
Jeff Young 2020-06-06 16:35:46 +01:00
parent 40250c427a
commit 39d4e422ea
7 changed files with 513 additions and 623 deletions

View File

@ -1,8 +1,8 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Aug 4 2017)
// C++ code generated with wxFormBuilder (version Oct 26 2018)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "dialog_layers_select_to_pcb_base.h"
@ -116,7 +116,7 @@ LAYERS_MAP_DIALOG_BASE::LAYERS_MAP_DIALOG_BASE( wxWindow* parent, wxWindowID id,
sbUpperSizer->Add( bRightSizer, 0, wxALIGN_CENTER_VERTICAL, 5 );
bSizerMain->Add( sbUpperSizer, 1, wxEXPAND, 5 );
bSizerMain->Add( sbUpperSizer, 1, wxEXPAND|wxALL, 5 );
m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
bSizerMain->Add( m_staticline1, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
@ -133,6 +133,7 @@ LAYERS_MAP_DIALOG_BASE::LAYERS_MAP_DIALOG_BASE( wxWindow* parent, wxWindowID id,
this->SetSizer( bSizerMain );
this->Layout();
bSizerMain->Fit( this );
this->Centre( wxBOTH );
}

File diff suppressed because it is too large Load Diff

View File

@ -1,18 +1,15 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Aug 4 2017)
// C++ code generated with wxFormBuilder (version Oct 26 2018)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#ifndef __DIALOG_LAYERS_SELECT_TO_PCB_BASE_H__
#define __DIALOG_LAYERS_SELECT_TO_PCB_BASE_H__
#pragma once
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
class DIALOG_SHIM;
#include "dialog_shim.h"
#include <wx/string.h>
#include <wx/stattext.h>
@ -23,6 +20,9 @@ class DIALOG_SHIM;
#include <wx/sizer.h>
#include <wx/statline.h>
#include <wx/combobox.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/button.h>
#include <wx/dialog.h>
@ -78,9 +78,8 @@ class LAYERS_MAP_DIALOG_BASE : public DIALOG_SHIM
public:
LAYERS_MAP_DIALOG_BASE( wxWindow* parent, wxWindowID id = ID_LAYERS_MAP_DIALOG_BASE, const wxString& title = _("Layer Selection"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 386,333 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
LAYERS_MAP_DIALOG_BASE( wxWindow* parent, wxWindowID id = ID_LAYERS_MAP_DIALOG_BASE, const wxString& title = _("Layer Selection"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~LAYERS_MAP_DIALOG_BASE();
};
#endif //__DIALOG_LAYERS_SELECT_TO_PCB_BASE_H__

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2012-2014 Jean-Pierre Charras jp.charras at wanadoo.fr
* Copyright (C) 1992-2014 KiCad Developers, see change_log.txt for contributors.
* Copyright (C) 1992-2020 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -46,16 +46,15 @@ enum layer_sel_id {
};
class SELECT_LAYER_DIALOG : public wxDialog
class SELECT_LAYER_DIALOG : public DIALOG_SHIM
{
private:
wxRadioBox* m_layerList;
wxRadioBox* m_layerRadioBox;
std::vector <int> m_layerId;
public:
// Constructor and destructor
SELECT_LAYER_DIALOG( GERBVIEW_FRAME* parent, int aDefaultLayer,
int aCopperLayerCount, bool aShowDeselectOption );
SELECT_LAYER_DIALOG( GERBVIEW_FRAME* parent, int aDefaultLayer, int aCopperLayerCount );
~SELECT_LAYER_DIALOG() { };
private:
@ -88,12 +87,9 @@ END_EVENT_TABLE()
* different radiobutton is clicked on) prior to then clicking on the "Deselect"
* button provided within the "Layer selection:" dialog box).
*/
int GERBVIEW_FRAME::SelectPCBLayer( int aDefaultLayer, int aCopperLayerCount,
bool aShowDeselectOption )
int GERBVIEW_FRAME::SelectPCBLayer( int aDefaultLayer, int aCopperLayerCount )
{
SELECT_LAYER_DIALOG* frame = new SELECT_LAYER_DIALOG( this, aDefaultLayer,
aCopperLayerCount,
aShowDeselectOption );
SELECT_LAYER_DIALOG* frame = new SELECT_LAYER_DIALOG( this, aDefaultLayer, aCopperLayerCount );
int layer = frame->ShowModal();
frame->Destroy();
@ -107,17 +103,15 @@ int GERBVIEW_FRAME::SelectPCBLayer( int aDefaultLayer, int aCopperLayerCount,
* radiobuttons, in which case they are positioned (in a vertical line)
* to the right of that radiobox.
*/
SELECT_LAYER_DIALOG::SELECT_LAYER_DIALOG( GERBVIEW_FRAME* parent,
int aDefaultLayer, int aCopperLayerCount,
bool aShowDeselectOption ) :
wxDialog( parent, -1, _( "Select Layer:" ), wxPoint( -1, -1 ),
wxSize( 470, 250 ),
SELECT_LAYER_DIALOG::SELECT_LAYER_DIALOG( GERBVIEW_FRAME* parent, int aDefaultLayer,
int aCopperLayerCount ) :
DIALOG_SHIM( parent, -1, _( "Select Layer:" ), wxDefaultPosition, wxDefaultSize,
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER )
{
wxButton* button;
int ii;
wxArrayString layerList;
int layerSelect = -1;
int selected = -1;
// Build the layer list; first build copper layers list
int layerCount = 0;
@ -128,8 +122,8 @@ SELECT_LAYER_DIALOG::SELECT_LAYER_DIALOG( GERBVIEW_FRAME* parent,
{
layerList.Add( GetPCBDefaultLayerName( ii ) );
if( ii == aDefaultLayer )
layerSelect = layerCount;
if( aDefaultLayer == ii )
selected = layerCount;
m_layerId.push_back( ii );
layerCount++;
@ -144,46 +138,54 @@ SELECT_LAYER_DIALOG::SELECT_LAYER_DIALOG( GERBVIEW_FRAME* parent,
layerList.Add( GetPCBDefaultLayerName( ii ) );
if( ii == aDefaultLayer )
layerSelect = layerCount;
if( aDefaultLayer == ii )
selected = layerCount;
m_layerId.push_back( ii );
layerCount++;
}
// When appropriate, also provide a "(Deselect)" radiobutton
if( aShowDeselectOption )
{
layerList.Add( _( "Hole data" ) );
if( aDefaultLayer == UNDEFINED_LAYER )
selected = layerCount;
m_layerId.push_back( UNDEFINED_LAYER );
layerCount++;
layerList.Add( _( "Do not export" ) );
if( UNSELECTED_LAYER == aDefaultLayer )
layerSelect = layerCount;
if( aDefaultLayer == UNSELECTED_LAYER )
selected = layerCount;
m_layerId.push_back( UNSELECTED_LAYER );
layerCount++;
}
m_layerList = new wxRadioBox( this, ID_LAYER_SELECT, _( "Layer" ),
wxPoint( -1, -1 ), wxSize( -1, -1 ),
layerList,
(layerCount < 8) ? layerCount : 8,
m_layerRadioBox = new wxRadioBox( this, ID_LAYER_SELECT, _( "Layer" ), wxDefaultPosition,
wxDefaultSize, layerList, std::min( layerCount, 12 ),
wxRA_SPECIFY_ROWS );
if( layerSelect >= 0 )
m_layerList->SetSelection( layerSelect );
if( selected >= 0 )
m_layerRadioBox->SetSelection( selected );
wxBoxSizer* FrameBoxSizer = new wxBoxSizer( wxHORIZONTAL );
SetSizer( FrameBoxSizer );
FrameBoxSizer->Add( m_layerList, 0, wxALIGN_TOP | wxALL, 5 );
wxBoxSizer* ButtonBoxSizer = new wxBoxSizer( wxVERTICAL );
FrameBoxSizer->Add( ButtonBoxSizer, 0, wxALIGN_BOTTOM | wxALL, 0 );
wxBoxSizer* mainSizer = new wxBoxSizer( wxHORIZONTAL );
SetSizer( mainSizer );
mainSizer->Add( m_layerRadioBox, 1, wxEXPAND | wxALIGN_TOP | wxALL, 5 );
wxBoxSizer* buttonsSizer = new wxBoxSizer( wxVERTICAL );
mainSizer->Add( buttonsSizer, 0, wxALIGN_BOTTOM | wxALL, 5 );
button = new wxButton( this, wxID_OK, _( "OK" ) );
button->SetDefault();
ButtonBoxSizer->Add( button, 0, wxGROW | wxALL, 5 );
buttonsSizer->Add( button, 0, wxGROW | wxALL, 5 );
button = new wxButton( this, wxID_CANCEL, _( "Cancel" ) );
ButtonBoxSizer->Add( button, 0, wxGROW | wxALL, 5 );
buttonsSizer->Add( button, 0, wxGROW | wxALL, 5 );
#ifdef __WXOSX__
// Hack to fix clipped radio buttons on OSX
wxSize size = m_layerRadioBox->GetBestSize() + wxSize( 20, 0 );
m_layerRadioBox->SetMinSize( size );
#endif
GetSizer()->SetSizeHints( this );
@ -193,7 +195,7 @@ SELECT_LAYER_DIALOG::SELECT_LAYER_DIALOG( GERBVIEW_FRAME* parent,
void SELECT_LAYER_DIALOG::OnLayerSelected( wxCommandEvent& event )
{
int ii = m_layerId[m_layerList->GetSelection()];
int ii = m_layerId[m_layerRadioBox->GetSelection()];
EndModal( ii );
}

View File

@ -34,19 +34,32 @@
#include <confirm.h>
#include <macros.h>
#include <trigo.h>
#include <gerbview.h>
#include <gerbview_frame.h>
#include <gerber_file_image.h>
#include <gerber_file_image_list.h>
#include <select_layers_to_pcb.h>
#include <build_version.h>
#include <wildcards_and_files_ext.h>
#include "excellon_image.h"
// Imported function
extern const wxString GetPCBDefaultLayerName( LAYER_NUM aLayerNumber );
struct EXPORT_VIA
{
EXPORT_VIA( const wxPoint& aPos, int aSize, int aDrill ) :
m_Pos( aPos ),
m_Size( aSize ),
m_Drill( aDrill )
{ }
wxPoint m_Pos;
int m_Size;
int m_Drill;
};
/* A helper class to export a Gerber set of files to Pcbnew
*/
class GBR_TO_PCB_EXPORTER
@ -56,9 +69,7 @@ private:
wxString m_pcb_file_name; // BOARD file to write to
FILE* m_fp; // the board file
int m_pcbCopperLayersCount;
std::vector<wxPoint> m_vias_coordinates; // list of already generated vias,
// used to export only once a via
// having a given coordinate
std::vector<EXPORT_VIA> m_vias;
public:
GBR_TO_PCB_EXPORTER( GERBVIEW_FRAME* aFrame, const wxString& aFileName );
~GBR_TO_PCB_EXPORTER();
@ -70,6 +81,22 @@ public:
bool ExportPcb( LAYER_NUM* aLayerLookUpTable, int aCopperLayers );
private:
/**
* collect holes from a drill layer.
* We'll use these later when writing pads & vias.
* @param aGbrItem
*/
void collect_hole( GERBER_DRAW_ITEM* aGbrItem );
/**
* write a via to the board file.
* Some of these will represent actual vias while others are used to represent
* holes in pads. (We can't generate actual pads because the Gerbers don't contain
* info on how to group them into modules.)
* @param aVia
*/
void export_via( const EXPORT_VIA& aVia );
/**
* write a non copper line or arc to the board file.
* @param aGbrItem = the Gerber item (line, arc) to export
@ -93,7 +120,7 @@ private:
void writePcbZoneItem( GERBER_DRAW_ITEM* aGbrItem, LAYER_NUM aLayer );
/**
* write a track or via) to the board file.
* write a track (or via) to the board file.
* @param aGbrItem = the Gerber item (line, arc, flashed) to export
* @param aLayer = the copper layer to use
*/
@ -101,10 +128,13 @@ private:
/**
* Function export_flashed_copper_item
* write a via to the board file (always uses a via through).
* write a synthetic pad to the board file.
* We can't create real pads because the Gerbers don't store grouping/footprint info.
* So we synthesize a pad with a via for the hole (if present) and a copper polygon for
* the pad.
* @param aGbrItem = the flashed Gerber item to export
*/
void export_flashed_copper_item( GERBER_DRAW_ITEM* aGbrItem );
void export_flashed_copper_item( GERBER_DRAW_ITEM* aGbrItem, LAYER_NUM aLayer );
/**
* Function export_segline_copper_item
@ -237,10 +267,22 @@ bool GBR_TO_PCB_EXPORTER::ExportPcb( LAYER_NUM* aLayerLookUpTable, int aCopperLa
writePcbHeader( aLayerLookUpTable );
// create an image of gerber data
// First: non copper layers:
const int pcbCopperLayerMax = 31;
GERBER_FILE_IMAGE_LIST* images = m_gerbview_frame->GetGerberLayout()->GetImagesList();
// First collect all the holes. We'll use these to generate pads, vias, etc.
for( unsigned layer = 0; layer < images->ImagesMaxCount(); ++layer )
{
EXCELLON_IMAGE* excellon = dynamic_cast<EXCELLON_IMAGE*>( images->GetGbrImage( layer ) );
if( excellon == NULL ) // Layer not yet used or not a drill image
continue;
for( GERBER_DRAW_ITEM* gerb_item : excellon->GetItems() )
collect_hole( gerb_item );
}
// Next: non copper layers:
for( unsigned layer = 0; layer < images->ImagesMaxCount(); ++layer )
{
GERBER_FILE_IMAGE* gerber = images->GetGbrImage( layer );
@ -277,6 +319,10 @@ bool GBR_TO_PCB_EXPORTER::ExportPcb( LAYER_NUM* aLayerLookUpTable, int aCopperLa
export_copper_item( gerb_item, pcb_layer_number );
}
// Now write out the holes we collected earlier as vias
for( const EXPORT_VIA& via : m_vias )
export_via( via );
fprintf( m_fp, ")\n" );
fclose( m_fp );
@ -388,6 +434,44 @@ void GBR_TO_PCB_EXPORTER::export_non_copper_item( GERBER_DRAW_ITEM* aGbrItem, LA
}
/*
* Many holes will be pads, but we have no way to create those without modules, and creating
* a module per pad is not really viable.
*
* So we use vias to mimic holes, with the loss of any hole shape (as we only have round holes
* in vias at present).
*
* We start out with a via size minimally larger than the hole. We'll leave it this way if
* the pad gets drawn as a copper polygon, or increase it to the proper size if it has a
* circular, concentric copper flashing.
*/
void GBR_TO_PCB_EXPORTER::collect_hole( GERBER_DRAW_ITEM* aGbrItem )
{
int size = std::min( aGbrItem->m_Size.x, aGbrItem->m_Size.y );
m_vias.emplace_back( aGbrItem->m_Start, size + 1, size );
}
void GBR_TO_PCB_EXPORTER::export_via( const EXPORT_VIA& aVia )
{
wxPoint via_pos = aVia.m_Pos;
// Reverse Y axis:
via_pos.y = -via_pos.y;
// Layers are Front to Back
fprintf( m_fp, " (via (at %s %s) (size %s) (drill %s)",
Double2Str( MapToPcbUnits( via_pos.x ) ).c_str(),
Double2Str( MapToPcbUnits( via_pos.y ) ).c_str(),
Double2Str( MapToPcbUnits( aVia.m_Size ) ).c_str(),
Double2Str( MapToPcbUnits( aVia.m_Drill ) ).c_str() );
fprintf( m_fp, " (layers %s %s))\n",
TO_UTF8( GetPCBDefaultLayerName( F_Cu ) ),
TO_UTF8( GetPCBDefaultLayerName( B_Cu ) ) );
}
void GBR_TO_PCB_EXPORTER::export_copper_item( GERBER_DRAW_ITEM* aGbrItem, LAYER_NUM aLayer )
{
switch( aGbrItem->m_Shape )
@ -395,8 +479,7 @@ void GBR_TO_PCB_EXPORTER::export_copper_item( GERBER_DRAW_ITEM* aGbrItem, LAYER_
case GBR_SPOT_CIRCLE:
case GBR_SPOT_RECT:
case GBR_SPOT_OVAL:
// replace spots with vias when possible
export_flashed_copper_item( aGbrItem );
export_flashed_copper_item( aGbrItem, aLayer );
break;
case GBR_ARC:
@ -505,36 +588,43 @@ void GBR_TO_PCB_EXPORTER::export_segarc_copper_item( GERBER_DRAW_ITEM* aGbrItem,
/*
* creates a via from a flashed gerber item.
* Flashed items are usually pads or vias, so we try to export all of them
* using vias
* Flashed items are usually pads or vias. Pads are problematic because we have no way to
* represent one in Pcbnew outside of a module (and creating a module per pad isn't really
* viable).
* If we've already created a via from a hole, and the flashed copper item is a simple circle
* then we'll enlarge the via to the proper size. Otherwise we create a copper polygon to
* represent the flashed item (which is presumably a pad).
*/
void GBR_TO_PCB_EXPORTER::export_flashed_copper_item( GERBER_DRAW_ITEM* aGbrItem )
void GBR_TO_PCB_EXPORTER::export_flashed_copper_item( GERBER_DRAW_ITEM* aGbrItem,
LAYER_NUM aLayer )
{
// First, explore already created vias, before creating a new via
for( unsigned ii = 0; ii < m_vias_coordinates.size(); ii++ )
static D_CODE flashed_item_D_CODE( 0 );
D_CODE* d_codeDescr = aGbrItem->GetDcodeDescr();
SHAPE_POLY_SET polygon;
if( d_codeDescr == NULL )
d_codeDescr = &flashed_item_D_CODE;
if( aGbrItem->m_Shape == GBR_SPOT_CIRCLE )
{
if( m_vias_coordinates[ii] == aGbrItem->m_Start ) // Already created
// See if there's a via that we can enlarge to fit this flashed item
for( EXPORT_VIA& via : m_vias )
{
if( via.m_Pos == aGbrItem->m_Start )
{
via.m_Size = std::max( via.m_Size, aGbrItem->m_Size.x );
return;
}
m_vias_coordinates.push_back( aGbrItem->m_Start );
wxPoint via_pos = aGbrItem->m_Start;
int width = (aGbrItem->m_Size.x + aGbrItem->m_Size.y) / 2;
// Reverse Y axis:
via_pos.y = -via_pos.y;
// Layers are Front to Back
fprintf( m_fp, " (via (at %s %s) (size %s)",
Double2Str( MapToPcbUnits(via_pos.x) ).c_str(),
Double2Str( MapToPcbUnits(via_pos.y) ).c_str(),
Double2Str( MapToPcbUnits( width ) ).c_str() );
fprintf( m_fp, " (layers %s %s))\n",
TO_UTF8( GetPCBDefaultLayerName( F_Cu ) ),
TO_UTF8( GetPCBDefaultLayerName( B_Cu ) ) );
}
}
d_codeDescr->ConvertShapeToPolygon();
wxPoint offset = aGbrItem->GetABPosition( aGbrItem->m_Start );
writePcbPolygon( d_codeDescr->m_Polygon, aLayer, offset );
}
void GBR_TO_PCB_EXPORTER::writePcbHeader( LAYER_NUM* aLayerLookUpTable )
{

View File

@ -122,7 +122,6 @@ public:
/** Install the dialog box for layer selection
* @param aDefaultLayer = Preselection (NB_PCB_LAYERS for "(Deselect)" layer)
* @param aCopperLayerCount = number of copper layers
* @param aShowDeselectOption = display a "(Deselect)" radiobutton (when set to true)
* @return new layer value (NB_PCB_LAYERS when "(Deselect)" radiobutton selected),
* or -1 if canceled
*
@ -134,7 +133,7 @@ public:
* different radiobutton is clicked on) prior to then clicking on the "Deselect"
* button provided within the "Layer selection:" dialog box).
*/
int SelectPCBLayer( int aDefaultLayer, int aOpperLayerCount, bool aNullLayer = false );
int SelectPCBLayer( int aDefaultLayer, int aCopperLayerCount );
///> @copydoc EDA_DRAW_FRAME::SetGridColor()
virtual void SetGridColor( COLOR4D aColor ) override;

View File

@ -158,24 +158,18 @@ void LAYERS_MAP_DIALOG::initDialog()
// Provide a text string to identify the Gerber layer
msg.Printf( _( "Layer %d" ), m_buttonTable[ii] + 1 );
label = new wxStaticText( this,
wxID_STATIC, msg, wxDefaultPosition,
wxDefaultSize, 0 );
label = new wxStaticText( this, wxID_STATIC, msg );
flexColumnBoxSizer->Add( label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
/* Add file name and extension without path. */
wxFileName fn( images->GetGbrImage( ii )->m_FileName );
label = new wxStaticText( this,
wxID_STATIC, fn.GetFullName(),
wxDefaultPosition, wxDefaultSize );
flexColumnBoxSizer->Add( label, 0,
wxALIGN_CENTER_VERTICAL | wxALL, 5 );
label = new wxStaticText( this, wxID_STATIC, fn.GetFullName() );
flexColumnBoxSizer->Add( label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
// Provide a button for this layer (which will invoke a child dialog box)
item_ID = ID_BUTTON_0 + ii;
wxButton * Button = new wxButton( this,
item_ID, wxT( "..." ),
wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT );
wxButton * Button = new wxButton( this, item_ID, wxT( "..." ), wxDefaultPosition,
wxDefaultSize, wxBU_EXACTFIT );
flexColumnBoxSizer->Add( Button, 0, wxALIGN_CENTER_VERTICAL | wxALL );
@ -195,14 +189,13 @@ void LAYERS_MAP_DIALOG::initDialog()
if( ii == 0 )
{
msg = _( "Do not export" );
text = new wxStaticText( this,
item_ID, msg, wxDefaultPosition,
wxDefaultSize, 0 );
text = new wxStaticText( this, item_ID, msg );
goodSize = text->GetSize();
for( LAYER_NUM jj = 0; jj < GERBER_DRAWLAYERS_COUNT; ++jj )
{
text->SetLabel( GetPCBDefaultLayerName( jj ) );
if( goodSize.x < text->GetSize().x )
goodSize.x = text->GetSize().x;
}
@ -213,13 +206,10 @@ void LAYERS_MAP_DIALOG::initDialog()
else
{
msg = GetPCBDefaultLayerName( m_layersLookUpTable[m_buttonTable[ii]] );
text = new wxStaticText( this,
item_ID, msg, wxDefaultPosition,
wxDefaultSize, 0 );
text = new wxStaticText( this, item_ID, msg );
}
text->SetMinSize( goodSize );
flexColumnBoxSizer->Add( text, 1, wxALIGN_CENTER_VERTICAL | wxALL,
5 );
flexColumnBoxSizer->Add( text, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
m_layersList[ii] = text;
}
@ -310,6 +300,11 @@ void LAYERS_MAP_DIALOG::OnGetSetup( wxCommandEvent& event )
m_layersList[ii]->SetLabel( _( "Do not export" ) );
m_layersList[ii]->SetForegroundColour( *wxBLUE );
}
else if( layer == UNDEFINED_LAYER )
{
m_layersList[ii]->SetLabel( _( "Hole data" ) );
m_layersList[ii]->SetForegroundColour( wxColour( 255, 0, 128 ) );
}
else
{
m_layersList[ii]->SetLabel( GetPCBDefaultLayerName( layer ) );
@ -332,12 +327,12 @@ void LAYERS_MAP_DIALOG::OnSelectLayer( wxCommandEvent& event )
LAYER_NUM jj = m_layersLookUpTable[m_buttonTable[ii]];
if( jj != UNSELECTED_LAYER && !IsValidLayer( jj ) )
if( jj != UNSELECTED_LAYER && jj != UNDEFINED_LAYER && !IsValidLayer( jj ) )
jj = B_Cu; // (Defaults to "Copper" layer.)
jj = m_Parent->SelectPCBLayer( jj, m_exportBoardCopperLayersCount, true );
jj = m_Parent->SelectPCBLayer( jj, m_exportBoardCopperLayersCount );
if( jj != UNSELECTED_LAYER && !IsValidLayer( jj ) )
if( jj != UNSELECTED_LAYER && jj != UNDEFINED_LAYER && !IsValidLayer( jj ) )
return;
if( jj != m_layersLookUpTable[m_buttonTable[ii]] )
@ -352,6 +347,14 @@ void LAYERS_MAP_DIALOG::OnSelectLayer( wxCommandEvent& event )
// that this layer is *not* being exported)
m_layersList[ii]->SetForegroundColour( *wxBLUE );
}
else if( jj == UNDEFINED_LAYER )
{
m_layersList[ii]->SetLabel( _( "Hole data" ) );
// Change the text color to fuchsia (to highlight
// that this layer *is* being exported)
m_layersList[ii]->SetForegroundColour( wxColour( 255, 0, 128 ) );
}
else
{
m_layersList[ii]->SetLabel( GetPCBDefaultLayerName( jj ) );
@ -387,7 +390,7 @@ void LAYERS_MAP_DIALOG::OnOkClick( wxCommandEvent& event )
if( inner_layer_max > m_exportBoardCopperLayersCount-2 )
{
wxMessageBox(
_("The exported board has not enough copper layers to handle selected inner layers") );
_("Exported board does not have enough copper layers to handle selected inner layers") );
return;
}