Gerbview: export_to_pcbnew enhancement and fixes.

This commit is contained in:
jean-pierre charras 2011-04-23 21:01:41 +02:00
parent 4dee08c318
commit 46fcb07bcb
4 changed files with 325 additions and 287 deletions

View File

@ -17,6 +17,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}
set(DIALOGS_SRCS set(DIALOGS_SRCS
dialogs/gerbview_dialog_display_options_frame_base.cpp dialogs/gerbview_dialog_display_options_frame_base.cpp
dialogs/gerbview_dialog_display_options_frame.cpp dialogs/gerbview_dialog_display_options_frame.cpp
dialogs/dialog_layers_select_to_pcb_base.cpp
dialogs/dialog_print_using_printer.cpp dialogs/dialog_print_using_printer.cpp
dialogs/dialog_print_using_printer_base.cpp dialogs/dialog_print_using_printer_base.cpp
) )

View File

@ -419,7 +419,7 @@ void GERBER_DRAW_ITEM::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, int aDrawMode,
break; break;
case GBR_ARC: case GBR_ARC:
// Currently, arcs plotted witha rectangular aperture are not supported. // Currently, arcs plotted with a rectangular aperture are not supported.
// a round pen only is expected. // a round pen only is expected.
#if 0 // for arc debug only #if 0 // for arc debug only
GRLine( &aPanel->m_ClipBox, aDC, GetABPosition( m_Start ), GRLine( &aPanel->m_ClipBox, aDC, GetABPosition( m_Start ),

View File

@ -10,13 +10,50 @@
#include "confirm.h" #include "confirm.h"
#include "kicad_string.h" #include "kicad_string.h"
#include "gestfich.h" #include "gestfich.h"
#include "trigo.h"
#include "gerbview.h" #include "gerbview.h"
#include "class_board_design_settings.h" #include "class_board_design_settings.h"
#include "class_gerber_draw_item.h" #include "class_gerber_draw_item.h"
static int SavePcbFormatAscii( GERBVIEW_FRAME* frame,
FILE* File, int* LayerLookUpTable ); /* A helper class to export a Gerber set of files to Pcbnew
*/
class GBR_TO_PCB_EXPORTER
{
GERBVIEW_FRAME* m_gerbview_frame; // the maint gerber frame
FILE * m_file; // .brd file to write to
BOARD* m_pcb; // the board to populate and export
public:
GBR_TO_PCB_EXPORTER(GERBVIEW_FRAME * aFrame, FILE * aFile );
~GBR_TO_PCB_EXPORTER();
bool ExportPcb( int* LayerLookUpTable );
private:
bool WriteSetup( ); // Write the SETUP section data file
bool WriteGeneralDescrPcb( );
void export_non_copper_item( GERBER_DRAW_ITEM* aGbrItem, int aLayer );
void export_copper_item( GERBER_DRAW_ITEM* aGbrItem, int aLayer );
void export_flashed_copper_item( GERBER_DRAW_ITEM* aGbrItem, int aLayer );
void export_segline_copper_item( GERBER_DRAW_ITEM* aGbrItem, int aLayer );
void export_segarc_copper_item( GERBER_DRAW_ITEM* aGbrItem, int aLayer );
void cleanBoard();
};
GBR_TO_PCB_EXPORTER::GBR_TO_PCB_EXPORTER( GERBVIEW_FRAME * aFrame, FILE * aFile )
{
m_gerbview_frame = aFrame;
m_file = aFile;
m_pcb = NULL;
}
GBR_TO_PCB_EXPORTER::~GBR_TO_PCB_EXPORTER()
{
// the destructor should destroy all owned sub-objects
delete m_pcb;
}
/* Export data in pcbnew format /* Export data in pcbnew format
@ -45,8 +82,6 @@ void GERBVIEW_FRAME::ExportDataInPcbnewFormat( wxCommandEvent& event )
wxString PcbExt( wxT( ".brd" ) ); wxString PcbExt( wxT( ".brd" ) );
FILE* dest;
msg = wxT( "*" ) + PcbExt; msg = wxT( "*" ) + PcbExt;
FullFileName = EDA_FileSelector( _( "Board file name:" ), FullFileName = EDA_FileSelector( _( "Board file name:" ),
wxEmptyString, wxEmptyString,
@ -68,143 +103,24 @@ void GERBVIEW_FRAME::ExportDataInPcbnewFormat( wxCommandEvent& event )
if( !IsOK( this, _( "Ok to change the existing file ?" ) ) ) if( !IsOK( this, _( "Ok to change the existing file ?" ) ) )
return; return;
} }
dest = wxFopen( FullFileName, wxT( "wt" ) ); FILE * file = wxFopen( FullFileName, wxT( "wt" ) );
if( dest == 0 ) if( file == NULL )
{ {
msg = _( "Unable to create " ) + FullFileName; msg = _( "Unable to create " ) + FullFileName;
DisplayError( this, msg ); DisplayError( this, msg );
return; return;
} }
GetScreen()->SetFileName( FullFileName ); GetScreen()->SetFileName( FullFileName );
SavePcbFormatAscii( this, dest, LayerLookUpTable ); GBR_TO_PCB_EXPORTER gbr_exporter( this, file );
fclose( dest ); gbr_exporter.ExportPcb( LayerLookUpTable );
fclose( file );
} }
} }
void GBR_TO_PCB_EXPORTER::cleanBoard()
static int WriteSetup( FILE* File, BOARD* Pcb )
{ {
char text[1024];
fprintf( File, "$SETUP\n" );
sprintf( text, "InternalUnit %f INCH\n", 1.0 / PCB_INTERNAL_UNIT );
fprintf( File, "%s", text );
fprintf( File, "Layers %d\n", Pcb->GetCopperLayerCount() );
fprintf( File, "$EndSETUP\n\n" );
return 1;
}
static bool WriteGeneralDescrPcb( BOARD* Pcb, FILE* File )
{
int NbLayers;
/* Print the copper layer count */
NbLayers = Pcb->GetCopperLayerCount();
fprintf( File, "$GENERAL\n" );
fprintf( File, "LayerCount %d\n", NbLayers );
/* Compute and print the board bounding box */
Pcb->ComputeBoundingBox();
fprintf( File, "Di %d %d %d %d\n",
Pcb->m_BoundaryBox.GetX(), Pcb->m_BoundaryBox.GetY(),
Pcb->m_BoundaryBox.GetRight(),
Pcb->m_BoundaryBox.GetBottom() );
fprintf( File, "$EndGENERAL\n\n" );
return TRUE;
}
/* Routine to save the board
* @param frame = pointer to the main frame
* @param File = FILE * pointer to an already opened file
* @param LayerLookUpTable = look up table: pcbnew layer for each gerber layer
* @return 1 if OK, 0 if fail
*/
static int SavePcbFormatAscii( GERBVIEW_FRAME* frame, FILE* aFile,
int* LayerLookUpTable )
{
char line[256];
BOARD* gerberPcb = frame->GetBoard();
BOARD* pcb;
wxBeginBusyCursor();
// create an image of gerber data
pcb = new BOARD( NULL, frame );
BOARD_ITEM* item = gerberPcb->m_Drawings;
for( ; item; item = item->Next() )
{
GERBER_DRAW_ITEM* gerb_item = (GERBER_DRAW_ITEM*) item;
int layer = gerb_item->GetLayer();
int pcb_layer_number = LayerLookUpTable[layer];
if( pcb_layer_number < 0 || pcb_layer_number > LAST_NO_COPPER_LAYER )
continue;
if( pcb_layer_number > LAST_COPPER_LAYER )
{
DRAWSEGMENT* drawitem = new DRAWSEGMENT( pcb, TYPE_DRAWSEGMENT );
drawitem->SetLayer( pcb_layer_number );
drawitem->m_Start = gerb_item->m_Start;
drawitem->m_End = gerb_item->m_End;
drawitem->m_Width = gerb_item->m_Size.x;
if( gerb_item->m_Shape == GBR_ARC )
{
double cx = gerb_item->m_ArcCentre.x;
double cy = gerb_item->m_ArcCentre.y;
double a = atan2( gerb_item->m_Start.y - cy,
gerb_item->m_Start.x - cx );
double b = atan2( gerb_item->m_End.y - cy, gerb_item->m_End.x - cx );
drawitem->m_Shape = S_ARC;
drawitem->m_Angle = (int) fmod(
(a - b) / M_PI * 1800.0 + 3600.0, 3600.0 );
drawitem->m_Start.x = (int) cx;
drawitem->m_Start.y = (int) cy;
}
pcb->Add( drawitem );
}
else
{
TRACK* newtrack;
// replace spots with vias when possible
if( gerb_item->m_Shape == GBR_SPOT_CIRCLE
|| gerb_item->m_Shape == GBR_SPOT_RECT
|| gerb_item->m_Shape == GBR_SPOT_OVAL )
{
newtrack = new SEGVIA( pcb );
// A spot is found, and can be a via: change it to via, and
// delete other
// spots at same location
newtrack->m_Shape = VIA_THROUGH;
newtrack->SetLayer( 0x0F ); // Layers are 0 to 15 (Cu/Cmp)
newtrack->SetDrillDefault();
newtrack->m_Start = newtrack->m_End = gerb_item->m_Start;
newtrack->m_Width = (gerb_item->m_Size.x + gerb_item->m_Size.y) / 2;
}
else // a true TRACK
{
newtrack = new TRACK( pcb );
newtrack->SetLayer( pcb_layer_number );
newtrack->m_Start = gerb_item->m_Start;
newtrack->m_End = gerb_item->m_End;
newtrack->m_Width = gerb_item->m_Size.x;
}
pcb->Add( newtrack );
}
}
// delete redundant vias // delete redundant vias
for( TRACK * track = pcb->m_Track; track; track = track->Next() ) for( TRACK * track = m_pcb->m_Track; track; track = track->Next() )
{ {
if( track->m_Shape != VIA_THROUGH ) if( track->m_Shape != VIA_THROUGH )
continue; continue;
@ -226,24 +142,211 @@ static int SavePcbFormatAscii( GERBVIEW_FRAME* frame, FILE* aFile,
delete alt_track; delete alt_track;
} }
} }
}
// Switch the locale to standard C (needed to print floating point numbers bool GBR_TO_PCB_EXPORTER::WriteSetup( )
// like 1.3) {
fprintf( m_file, "$SETUP\n" );
fprintf( m_file, "InternalUnit %f INCH\n", 1.0 / PCB_INTERNAL_UNIT );
fprintf( m_file, "Layers %d\n", m_pcb->GetCopperLayerCount() );
fprintf( m_file, "$EndSETUP\n\n" );
return true;
}
bool GBR_TO_PCB_EXPORTER::WriteGeneralDescrPcb( )
{
int nbLayers;
/* Print the copper layer count */
nbLayers = m_pcb->GetCopperLayerCount();
if( nbLayers <= 1 ) // Minimal layers count in Pcbnew is 2
{
nbLayers = 2;
m_pcb->SetCopperLayerCount(2);
}
fprintf( m_file, "$GENERAL\n" );
fprintf( m_file, "encoding utf-8\n");
fprintf( m_file, "LayerCount %d\n", nbLayers );
/* Compute and print the board bounding box */
m_pcb->ComputeBoundingBox();
fprintf( m_file, "Di %d %d %d %d\n",
m_pcb->m_BoundaryBox.GetX(), m_pcb->m_BoundaryBox.GetY(),
m_pcb->m_BoundaryBox.GetRight(),
m_pcb->m_BoundaryBox.GetBottom() );
fprintf( m_file, "$EndGENERAL\n\n" );
return true;
}
/* Routine to save the board
* @param frame = pointer to the main frame
* @param File = FILE * pointer to an already opened file
* @param LayerLookUpTable = look up table: pcbnew layer for each gerber layer
* @return 1 if OK, 0 if fail
*/
bool GBR_TO_PCB_EXPORTER::ExportPcb( int* LayerLookUpTable )
{
char line[256];
BOARD* gerberPcb = m_gerbview_frame->GetBoard();
// create an image of gerber data
m_pcb = new BOARD( NULL, m_gerbview_frame );
BOARD_ITEM* item = gerberPcb->m_Drawings;
for( ; item; item = item->Next() )
{
GERBER_DRAW_ITEM* gerb_item = (GERBER_DRAW_ITEM*) item;
int layer = gerb_item->GetLayer();
int pcb_layer_number = LayerLookUpTable[layer];
if( pcb_layer_number < 0 || pcb_layer_number > LAST_NO_COPPER_LAYER )
continue;
if( pcb_layer_number > LAST_COPPER_LAYER )
export_non_copper_item( gerb_item, pcb_layer_number );
else
export_copper_item( gerb_item, pcb_layer_number );
}
cleanBoard();
// Switch the locale to standard C (needed to print floating point numbers)
SetLocaleTo_C_standard(); SetLocaleTo_C_standard();
// write the PCB heading // write PCB header
fprintf( aFile, "PCBNEW-BOARD Version %d date %s\n\n", g_CurrentVersionPCB, fprintf( m_file, "PCBNEW-BOARD Version %d date %s\n\n", g_CurrentVersionPCB,
DateAndTime( line ) ); DateAndTime( line ) );
WriteGeneralDescrPcb( pcb, aFile ); WriteGeneralDescrPcb( );
WriteSetup( aFile, pcb ); WriteSetup( );
// write the useful part of the pcb // write items on file
pcb->Save( aFile ); m_pcb->Save( m_file );
// the destructor should destroy all owned sub-objects
delete pcb;
SetLocaleTo_Default(); // revert to the current locale SetLocaleTo_Default(); // revert to the current locale
wxEndBusyCursor(); return true;
return 1; }
void GBR_TO_PCB_EXPORTER::export_non_copper_item( GERBER_DRAW_ITEM* aGbrItem, int aLayer )
{
DRAWSEGMENT* drawitem = new DRAWSEGMENT( m_pcb, TYPE_DRAWSEGMENT );
drawitem->SetLayer( aLayer );
drawitem->m_Start = aGbrItem->m_Start;
drawitem->m_End = aGbrItem->m_End;
drawitem->m_Width = aGbrItem->m_Size.x;
if( aGbrItem->m_Shape == GBR_ARC )
{
double a = atan2( (double)( aGbrItem->m_Start.y - aGbrItem->m_ArcCentre.y),
(double)( aGbrItem->m_Start.x - aGbrItem->m_ArcCentre.x ) );
double b = atan2( (double)( aGbrItem->m_End.y - aGbrItem->m_ArcCentre.y ),
(double)( aGbrItem->m_End.x - aGbrItem->m_ArcCentre.x ) );
drawitem->m_Shape = S_ARC;
drawitem->m_Angle = wxRound( (a - b) / M_PI * 1800.0 );
drawitem->m_Start = aGbrItem->m_ArcCentre;
if( drawitem->m_Angle < 0 )
{
NEGATE( drawitem->m_Angle );
drawitem->m_End = aGbrItem->m_Start;
}
}
m_pcb->Add( drawitem );
}
void GBR_TO_PCB_EXPORTER::export_copper_item( GERBER_DRAW_ITEM* aGbrItem, int aLayer )
{
switch( aGbrItem->m_Shape )
{
case GBR_SPOT_CIRCLE:
case GBR_SPOT_RECT:
case GBR_SPOT_OVAL:
// replace spots with vias when possible
export_flashed_copper_item( aGbrItem, aLayer );
break;
case GBR_ARC:
// export_segarc_copper_item( aGbrItem, aLayer );
break;
default:
export_segline_copper_item( aGbrItem, aLayer );
break;
}
}
void GBR_TO_PCB_EXPORTER::export_segline_copper_item( GERBER_DRAW_ITEM* aGbrItem, int aLayer )
{
TRACK * newtrack = new TRACK( m_pcb );
newtrack->SetLayer( aLayer );
newtrack->m_Start = aGbrItem->m_Start;
newtrack->m_End = aGbrItem->m_End;
newtrack->m_Width = aGbrItem->m_Size.x;
m_pcb->Add( newtrack );
}
void GBR_TO_PCB_EXPORTER::export_segarc_copper_item( GERBER_DRAW_ITEM* aGbrItem, int aLayer )
{
double a = atan2( (double)( aGbrItem->m_Start.y - aGbrItem->m_ArcCentre.y ),
(double)( aGbrItem->m_Start.x - aGbrItem->m_ArcCentre.x ) );
double b = atan2( (double)( aGbrItem->m_End.y - aGbrItem->m_ArcCentre.y ),
(double)( aGbrItem->m_End.x - aGbrItem->m_ArcCentre.x ) );
int arc_angle = wxRound( ( (a - b) / M_PI * 1800.0 ) );
wxPoint start = aGbrItem->m_Start;
wxPoint end = aGbrItem->m_End;
/* Because Pcbnew does not know arcs in tracks,
* approximate arc by segments (16 segment per 360 deg)
*/
#define DELTA 3600/16
if( arc_angle < 0 )
{
NEGATE( arc_angle );
EXCHG( start, end );
}
wxPoint curr_start = start;
for( int rot = DELTA; rot < (arc_angle - DELTA); rot += DELTA )
{
TRACK * newtrack = new TRACK( m_pcb );
newtrack->SetLayer( aLayer );
newtrack->m_Start = curr_start;
wxPoint curr_end = start;
RotatePoint( &curr_end, aGbrItem->m_ArcCentre, rot );
newtrack->m_End = curr_end;
newtrack->m_Width = aGbrItem->m_Size.x;
m_pcb->Add( newtrack );
curr_start = curr_end;
}
if( end != curr_start )
{
TRACK * newtrack = new TRACK( m_pcb );
newtrack->SetLayer( aLayer );
newtrack->m_Start = curr_start;
newtrack->m_End = end;
newtrack->m_Width = aGbrItem->m_Size.x;
m_pcb->Add( newtrack );
}
}
/*
* 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
*/
void GBR_TO_PCB_EXPORTER::export_flashed_copper_item( GERBER_DRAW_ITEM* aGbrItem, int aLayer )
{
SEGVIA * newtrack = new SEGVIA( m_pcb );
newtrack->m_Shape = VIA_THROUGH;
newtrack->SetLayer( 0x0F ); // Layers are 0 to 15 (Cu/Cmp)
newtrack->SetDrillDefault();
newtrack->m_Start = newtrack->m_End = aGbrItem->m_Start;
newtrack->m_Width = (aGbrItem->m_Size.x + aGbrItem->m_Size.y) / 2;
m_pcb->Add( newtrack );
} }

View File

@ -2,16 +2,19 @@
/* Dialog frame to choose gerber layers and pcb layers */ /* Dialog frame to choose gerber layers and pcb layers */
/*******************************************************/ /*******************************************************/
/* select_layers_to_pcb.cpp */ /**
* @file select_layers_to_pcb.cpp
*/
#include "fctsys.h" #include "fctsys.h"
#include "common.h" #include "common.h"
#include "gerbview.h" #include "gerbview.h"
#include "class_board_design_settings.h" #include "class_board_design_settings.h"
#include "class_GERBER.h" #include "class_GERBER.h"
#include "wx/statline.h" #include "wx/statline.h"
#include "dialogs/dialog_layers_select_to_pcb_base.h"
#define LAYER_UNSELECTED NB_LAYERS #define LAYER_UNSELECTED NB_LAYERS
static int ButtonTable[32]; // Indexes buttons to Gerber layers static int ButtonTable[32]; // Indexes buttons to Gerber layers
@ -25,23 +28,18 @@ enum swap_layer_id {
}; };
class SWAP_LAYERS_DIALOG : public wxDialog class LAYERS_TABLE_DIALOG : public LAYERS_TABLE_DIALOG_BASE
{ {
private: private:
GERBVIEW_FRAME* m_Parent; GERBVIEW_FRAME* m_Parent;
wxBoxSizer* OuterBoxSizer;
wxBoxSizer* MainBoxSizer;
wxFlexGridSizer* FlexColumnBoxSizer;
wxStaticText* label; wxStaticText* label;
wxButton* Button; wxButton* Button;
wxStaticText* text; wxStaticText* text;
wxStaticLine* Line;
wxStdDialogButtonSizer* StdDialogButtonSizer;
public: public:
SWAP_LAYERS_DIALOG( GERBVIEW_FRAME* parent ); LAYERS_TABLE_DIALOG( GERBVIEW_FRAME* parent );
~SWAP_LAYERS_DIALOG() {}; ~LAYERS_TABLE_DIALOG() {};
private: private:
void OnSelectLayer( wxCommandEvent& event ); void OnSelectLayer( wxCommandEvent& event );
@ -52,12 +50,10 @@ private:
}; };
BEGIN_EVENT_TABLE( SWAP_LAYERS_DIALOG, wxDialog ) BEGIN_EVENT_TABLE( LAYERS_TABLE_DIALOG, wxDialog )
EVT_COMMAND_RANGE( ID_BUTTON_0, ID_BUTTON_0 + 31, EVT_COMMAND_RANGE( ID_BUTTON_0, ID_BUTTON_0 + 31,
wxEVT_COMMAND_BUTTON_CLICKED, wxEVT_COMMAND_BUTTON_CLICKED,
SWAP_LAYERS_DIALOG::OnSelectLayer ) LAYERS_TABLE_DIALOG::OnSelectLayer )
EVT_BUTTON( wxID_OK, SWAP_LAYERS_DIALOG::OnOkClick )
EVT_BUTTON( wxID_CANCEL, SWAP_LAYERS_DIALOG::OnCancelClick )
END_EVENT_TABLE() END_EVENT_TABLE()
@ -67,30 +63,24 @@ END_EVENT_TABLE()
*/ */
int* GERBVIEW_FRAME::InstallDialogLayerPairChoice( ) int* GERBVIEW_FRAME::InstallDialogLayerPairChoice( )
{ {
SWAP_LAYERS_DIALOG* frame = new SWAP_LAYERS_DIALOG( this ); LAYERS_TABLE_DIALOG* frame = new LAYERS_TABLE_DIALOG( this );
int ii = frame->ShowModal(); int ii = frame->ShowModal();
frame->Destroy(); frame->Destroy();
if( ii >= 0 ) if( ii == wxID_OK )
return LayerLookUpTable; return LayerLookUpTable;
else else
return NULL; return NULL;
} }
SWAP_LAYERS_DIALOG::SWAP_LAYERS_DIALOG( GERBVIEW_FRAME* parent ) : LAYERS_TABLE_DIALOG::LAYERS_TABLE_DIALOG( GERBVIEW_FRAME* parent ) :
wxDialog( parent, -1, _( "Layer selection:" ), wxPoint( -1, -1 ), LAYERS_TABLE_DIALOG_BASE( parent )
wxDefaultSize, wxDEFAULT_DIALOG_STYLE | MAYBE_RESIZE_BORDER )
{ {
OuterBoxSizer = NULL;
MainBoxSizer = NULL;
FlexColumnBoxSizer = NULL;
label = NULL; label = NULL;
Button = NULL; Button = NULL;
text = NULL; text = NULL;
Line = NULL;
StdDialogButtonSizer = NULL;
m_Parent = parent; m_Parent = parent;
@ -118,113 +108,90 @@ SWAP_LAYERS_DIALOG::SWAP_LAYERS_DIALOG( GERBVIEW_FRAME* parent ) :
// buttons should be some other size in that version. // buttons should be some other size in that version.
// Compute a reasonable number of copper layers // Compute a reasonable number of copper layers
int pcb_layer_number = 0; int pcb_copper_layer_count = 0;
for( ii = 0; ii < 32; ii++ ) for( ii = 0; ii < 32; ii++ )
{ {
if( g_GERBER_List[ii] != NULL ) if( g_GERBER_List[ii] != NULL )
pcb_layer_number++; pcb_copper_layer_count++;
// Specify the default value for each member of these arrays. // Specify the default value for each member of these arrays.
ButtonTable[ii] = -1; ButtonTable[ii] = -1;
LayerLookUpTable[ii] = LAYER_UNSELECTED; LayerLookUpTable[ii] = LAYER_UNSELECTED;
} }
m_Parent->GetBoard()->SetCopperLayerCount(pcb_layer_number);
pcb_layer_number = 0; // Ensure we have at least 2 copper layers and NB_COPPER_LAYERS copper layers max
if( pcb_copper_layer_count < 2 )
pcb_copper_layer_count = 2;
if( pcb_copper_layer_count > NB_COPPER_LAYERS )
pcb_copper_layer_count = NB_COPPER_LAYERS;
m_Parent->GetBoard()->SetCopperLayerCount(pcb_copper_layer_count);
int pcb_layer_num = 0;
for( nb_items = 0, ii = 0; ii < 32; ii++ ) for( nb_items = 0, ii = 0; ii < 32; ii++ )
{ {
if( g_GERBER_List[ii] == NULL ) if( g_GERBER_List[ii] == NULL )
continue; continue;
if( (pcb_layer_number == m_Parent->GetBoard()->GetCopperLayerCount() - 1) if( (pcb_layer_num == m_Parent->GetBoard()->GetCopperLayerCount() - 1)
&& (m_Parent->GetBoard()->GetCopperLayerCount() > 1) ) && (m_Parent->GetBoard()->GetCopperLayerCount() > 1) )
pcb_layer_number = LAYER_N_FRONT; pcb_layer_num = LAYER_N_FRONT;
ButtonTable[nb_items] = ii; ButtonTable[nb_items] = ii;
LayerLookUpTable[ii] = pcb_layer_number; LayerLookUpTable[ii] = pcb_layer_num;
nb_items++; nb_items++;
pcb_layer_number++; pcb_layer_num++;
} }
OuterBoxSizer = new wxBoxSizer( wxVERTICAL ); if( nb_items <= 16 )
SetSizer( OuterBoxSizer ); m_staticlineSep->Hide();
MainBoxSizer = new wxBoxSizer( wxHORIZONTAL );
OuterBoxSizer->Add( MainBoxSizer, 1, wxGROW | wxLEFT | wxRIGHT | wxTOP, 5 );
wxFlexGridSizer* flexColumnBoxSizer = m_flexLeftColumnBoxSizer;
for( ii = 0; ii < nb_items; ii++ ) for( ii = 0; ii < nb_items; ii++ )
{ {
// If more than 16 Gerber layers are used, provide a vertical line to // Each Gerber layer has an associated static text string (to
// separate the two FlexGrid sizers // identify that layer), a button (for invoking a child dialog
if( (nb_items > 16) && (ii == 16) ) // box to change which pcbnew layer that the Gerber layer is
{ // mapped to), and a second static text string (to depict which
Line = new wxStaticLine( this, -1, wxDefaultPosition, wxDefaultSize, // pcbnew layer that the Gerber layer has been mapped to). Each
wxLI_VERTICAL ); // of those items are placed into the left hand column, middle
MainBoxSizer->Add( Line, 0, wxGROW | wxLEFT | wxRIGHT, 5 ); // column, and right hand column (respectively) of the Flexgrid
} // sizer, and the color of the second text string is set to
// fuchsia or blue (to respectively indicate whether the Gerber
// layer has been mapped to a pcbnew layer or is not being
// exported at all). (Experimentation has shown that if a text
// control is used to depict which pcbnew layer that each Gerber
// layer is mapped to (instead of a static text string), then
// those controls do not behave in a fully satisfactory manner
// in the Linux version. Even when the read-only attribute is
// specified for all of those controls, they can still be selected
// when the arrow keys or Tab key is used to step through all of
// the controls within the dialog box, and directives to set the
// foreground color of the text of each such control to blue (to
// indicate that the text is of a read-only nature) are disregarded.
// Specify a FlexGrid sizer with an appropriate number of rows
// and three columns. If nb_items < 16, then the number of rows
// is nb_items; otherwise, the number of rows is 16 (with two
// separate columns of controls being used if nb_items > 16).
// Provide a separate FlexGrid sizer for every sixteen sets of controls if( ii == 16 )
if( ii % 16 == 0 ) flexColumnBoxSizer = m_flexRightColumnBoxSizer;
{
// Each Gerber layer has an associated static text string (to
// identify that layer), a button (for invoking a child dialog
// box to change which pcbnew layer that the Gerber layer is
// mapped to), and a second static text string (to depict which
// pcbnew layer that the Gerber layer has been mapped to). Each
// of those items are placed into the left hand column, middle
// column, and right hand column (respectively) of the Flexgrid
// sizer, and the color of the second text string is set to
// fuchsia or blue (to respectively indicate whether the Gerber
// layer has been mapped to a pcbnew layer or is not being
// exported at all). (Experimentation has shown that if a text
// control is used to depict which pcbnew layer that each Gerber
// layer is mapped to (instead of a static text string), then
// those controls do not behave in a fully satisfactory manner
// in the Linux version. Even when the read-only attribute is
// specified for all of those controls, they can still be selected
// when the arrow keys or Tab key is used to step through all of
// the controls within the dialog box, and directives to set the
// foreground color of the text of each such control to blue (to
// indicate that the text is of a read-only nature) are disregarded.
// Specify a FlexGrid sizer with an appropriate number of rows
// and three columns. If nb_items < 16, then the number of rows
// is nb_items; otherwise, the number of rows is 16 (with two
// separate columns of controls being used if nb_items > 16).
if( nb_items < 16 )
FlexColumnBoxSizer = new wxFlexGridSizer( nb_items, 4, 0, 0 );
else
FlexColumnBoxSizer = new wxFlexGridSizer( 16, 4, 0, 0 );
// Specify that all of the rows can be expanded.
for( int jj = 0; jj < MIN( nb_items, 16 ); jj++ )
{
FlexColumnBoxSizer->AddGrowableRow( jj );
}
// Specify that (just) the right-hand column can be expanded.
FlexColumnBoxSizer->AddGrowableCol( 2 );
MainBoxSizer->Add( FlexColumnBoxSizer, 1, wxGROW | wxTOP, 5 );
}
// Provide a text string to identify the Gerber layer // Provide a text string to identify the Gerber layer
msg = _( "Layer " ); msg.Printf( _( "Layer %d" ), ButtonTable[ii] + 1 );
msg << ButtonTable[ii] + 1;
label = new wxStaticText( this, wxID_STATIC, msg, wxDefaultPosition, label = new wxStaticText( this, wxID_STATIC, msg, wxDefaultPosition,
wxDefaultSize, wxALIGN_RIGHT ); wxDefaultSize, wxALIGN_RIGHT );
FlexColumnBoxSizer->Add( label, 0, flexColumnBoxSizer->Add( label, 0,
wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL |
wxALL, 5 ); wxRIGHT|wxLEFT, 5 );
/* Add file name and extension without path. */ /* Add file name and extension without path. */
wxFileName fn( g_GERBER_List[ii]->m_FileName ); wxFileName fn( g_GERBER_List[ii]->m_FileName );
label = new wxStaticText( this, wxID_STATIC, fn.GetFullName(), label = new wxStaticText( this, wxID_STATIC, fn.GetFullName(),
wxDefaultPosition, wxDefaultSize ); wxDefaultPosition, wxDefaultSize );
FlexColumnBoxSizer->Add( label, 0, flexColumnBoxSizer->Add( label, 0,
wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL |
wxALL, 5 ); wxRIGHT|wxLEFT, 5 );
// Provide a button for this layer (which will invoke a child dialog box) // Provide a button for this layer (which will invoke a child dialog box)
item_ID = ID_BUTTON_0 + ii; item_ID = ID_BUTTON_0 + ii;
@ -232,9 +199,9 @@ SWAP_LAYERS_DIALOG::SWAP_LAYERS_DIALOG( GERBVIEW_FRAME* parent ) :
Button = new wxButton( this, item_ID, wxT( "..." ), Button = new wxButton( this, item_ID, wxT( "..." ),
wxDefaultPosition, wxSize( w, h ), 0 ); wxDefaultPosition, wxSize( w, h ), 0 );
FlexColumnBoxSizer->Add( Button, 0, flexColumnBoxSizer->Add( Button, 0,
wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
wxALL, 5 ); wxRIGHT|wxLEFT, 5 );
// Provide another text string to specify which pcbnew layer that this // Provide another text string to specify which pcbnew layer that this
// Gerber layer is initially mapped to, and set the initial text to // Gerber layer is initially mapped to, and set the initial text to
@ -273,57 +240,20 @@ SWAP_LAYERS_DIALOG::SWAP_LAYERS_DIALOG( GERBVIEW_FRAME* parent ) :
wxDefaultSize, 0 ); wxDefaultSize, 0 );
} }
text->SetMinSize( goodSize ); text->SetMinSize( goodSize );
FlexColumnBoxSizer->Add( text, 1, flexColumnBoxSizer->Add( text, 1,
wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxRIGHT| wxLEFT,
5 ); 5 );
layer_list[ii] = text; layer_list[ii] = text;
} }
// If required, provide spacers to occupy otherwise blank cells within the
// second FlexGrid sizer. (As it incorporates three columns, three spacers
// are thus required for each otherwise unused row.)
if( 16 < nb_items && nb_items < 32 )
{
for( ii = 4 * nb_items; ii < 96; ii++ )
{
FlexColumnBoxSizer->Add( 5, h, 0,
wxALIGN_CENTER_HORIZONTAL |
wxALIGN_CENTER_VERTICAL | wxLEFT |
wxRIGHT | wxBOTTOM, 5 );
}
}
// Provide a line to separate the controls which have been provided so far
// from the OK and Cancel buttons (which will be provided after this line)
Line = new wxStaticLine( this, -1, wxDefaultPosition, wxDefaultSize,
wxLI_HORIZONTAL );
OuterBoxSizer->Add( Line, 0, wxGROW | wxLEFT | wxRIGHT | wxTOP, 5 );
// Provide a StdDialogButtonSizer to accommodate the OK and Cancel buttons;
// using that type of sizer results in those buttons being automatically
// located in positions appropriate for each (OS) version of KiCad.
StdDialogButtonSizer = new wxStdDialogButtonSizer;
OuterBoxSizer->Add( StdDialogButtonSizer, 0, wxGROW | wxALL, 10 );
Button = new wxButton( this, wxID_OK, _( "&OK" ), wxDefaultPosition,
wxDefaultSize, 0 );
StdDialogButtonSizer->AddButton( Button );
Button = new wxButton( this, wxID_CANCEL, _( "&Cancel" ),
wxDefaultPosition, wxDefaultSize, 0 );
StdDialogButtonSizer->AddButton( Button );
StdDialogButtonSizer->Realize();
// Resize the dialog // Resize the dialog
if( GetSizer() ) GetSizer()->SetSizeHints( this );
{ Centre();
GetSizer()->SetSizeHints( this );
}
} }
void SWAP_LAYERS_DIALOG::OnSelectLayer( wxCommandEvent& event ) void LAYERS_TABLE_DIALOG::OnSelectLayer( wxCommandEvent& event )
{ {
int ii, jj; int ii, jj;
@ -365,13 +295,13 @@ void SWAP_LAYERS_DIALOG::OnSelectLayer( wxCommandEvent& event )
} }
void SWAP_LAYERS_DIALOG::OnCancelClick( wxCommandEvent& event ) void LAYERS_TABLE_DIALOG::OnCancelClick( wxCommandEvent& event )
{ {
EndModal( -1 ); EndModal( wxID_CANCEL );
} }
void SWAP_LAYERS_DIALOG::OnOkClick( wxCommandEvent& event ) void LAYERS_TABLE_DIALOG::OnOkClick( wxCommandEvent& event )
{ {
int ii; int ii;
bool AsCmpLayer = false; bool AsCmpLayer = false;
@ -395,10 +325,14 @@ void SWAP_LAYERS_DIALOG::OnOkClick( wxCommandEvent& event )
if( AsCmpLayer ) if( AsCmpLayer )
layers_count++; layers_count++;
if( layers_count > NB_COPPER_LAYERS ) // should not occur. if( layers_count > NB_COPPER_LAYERS ) // should not occur.
layers_count = NB_COPPER_LAYERS; layers_count = NB_COPPER_LAYERS;
if( layers_count < 2 )
layers_count = 2;
m_Parent->GetBoard()->SetCopperLayerCount( layers_count ); m_Parent->GetBoard()->SetCopperLayerCount( layers_count );
EndModal( 1 ); EndModal( wxID_OK );
} }