Commit 46fcb07b authored by jean-pierre charras's avatar jean-pierre charras

Gerbview: export_to_pcbnew enhancement and fixes.

parent 4dee08c3
...@@ -17,6 +17,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR} ...@@ -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
) )
......
...@@ -419,7 +419,7 @@ void GERBER_DRAW_ITEM::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, int aDrawMode, ...@@ -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 ),
......
...@@ -10,13 +10,50 @@ ...@@ -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 ) ...@@ -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,53 +103,83 @@ void GERBVIEW_FRAME::ExportDataInPcbnewFormat( wxCommandEvent& event ) ...@@ -68,53 +103,83 @@ 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]; // delete redundant vias
for( TRACK * track = m_pcb->m_Track; track; track = track->Next() )
{
if( track->m_Shape != VIA_THROUGH )
continue;
// Search and delete others vias
TRACK* next_track;
TRACK* alt_track = track->Next();
for( ; alt_track; alt_track = next_track )
{
next_track = alt_track->Next();
if( alt_track->m_Shape != VIA_THROUGH )
continue;
if( alt_track->m_Start != track->m_Start )
continue;
fprintf( File, "$SETUP\n" ); // delete track
sprintf( text, "InternalUnit %f INCH\n", 1.0 / PCB_INTERNAL_UNIT ); alt_track->UnLink();
fprintf( File, "%s", text ); delete alt_track;
}
}
}
bool GBR_TO_PCB_EXPORTER::WriteSetup( )
{
fprintf( m_file, "$SETUP\n" );
fprintf( m_file, "InternalUnit %f INCH\n", 1.0 / PCB_INTERNAL_UNIT );
fprintf( File, "Layers %d\n", Pcb->GetCopperLayerCount() ); fprintf( m_file, "Layers %d\n", m_pcb->GetCopperLayerCount() );
fprintf( File, "$EndSETUP\n\n" ); fprintf( m_file, "$EndSETUP\n\n" );
return 1; return true;
} }
static bool WriteGeneralDescrPcb( BOARD* Pcb, FILE* File ) bool GBR_TO_PCB_EXPORTER::WriteGeneralDescrPcb( )
{ {
int NbLayers; int nbLayers;
/* Print the copper layer count */ /* Print the copper layer count */
NbLayers = Pcb->GetCopperLayerCount(); nbLayers = m_pcb->GetCopperLayerCount();
fprintf( File, "$GENERAL\n" ); if( nbLayers <= 1 ) // Minimal layers count in Pcbnew is 2
fprintf( File, "LayerCount %d\n", NbLayers ); {
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 */ /* Compute and print the board bounding box */
Pcb->ComputeBoundingBox(); m_pcb->ComputeBoundingBox();
fprintf( File, "Di %d %d %d %d\n", fprintf( m_file, "Di %d %d %d %d\n",
Pcb->m_BoundaryBox.GetX(), Pcb->m_BoundaryBox.GetY(), m_pcb->m_BoundaryBox.GetX(), m_pcb->m_BoundaryBox.GetY(),
Pcb->m_BoundaryBox.GetRight(), m_pcb->m_BoundaryBox.GetRight(),
Pcb->m_BoundaryBox.GetBottom() ); m_pcb->m_BoundaryBox.GetBottom() );
fprintf( File, "$EndGENERAL\n\n" ); fprintf( m_file, "$EndGENERAL\n\n" );
return TRUE; return true;
} }
...@@ -124,17 +189,13 @@ static bool WriteGeneralDescrPcb( BOARD* Pcb, FILE* File ) ...@@ -124,17 +189,13 @@ static bool WriteGeneralDescrPcb( BOARD* Pcb, FILE* File )
* @param LayerLookUpTable = look up table: pcbnew layer for each gerber layer * @param LayerLookUpTable = look up table: pcbnew layer for each gerber layer
* @return 1 if OK, 0 if fail * @return 1 if OK, 0 if fail
*/ */
static int SavePcbFormatAscii( GERBVIEW_FRAME* frame, FILE* aFile, bool GBR_TO_PCB_EXPORTER::ExportPcb( int* LayerLookUpTable )
int* LayerLookUpTable )
{ {
char line[256]; char line[256];
BOARD* gerberPcb = frame->GetBoard(); BOARD* gerberPcb = m_gerbview_frame->GetBoard();
BOARD* pcb;
wxBeginBusyCursor();
// create an image of gerber data // create an image of gerber data
pcb = new BOARD( NULL, frame ); m_pcb = new BOARD( NULL, m_gerbview_frame );
BOARD_ITEM* item = gerberPcb->m_Drawings; BOARD_ITEM* item = gerberPcb->m_Drawings;
for( ; item; item = item->Next() ) for( ; item; item = item->Next() )
{ {
...@@ -145,105 +206,147 @@ static int SavePcbFormatAscii( GERBVIEW_FRAME* frame, FILE* aFile, ...@@ -145,105 +206,147 @@ static int SavePcbFormatAscii( GERBVIEW_FRAME* frame, FILE* aFile,
continue; continue;
if( pcb_layer_number > LAST_COPPER_LAYER ) if( pcb_layer_number > LAST_COPPER_LAYER )
{ export_non_copper_item( gerb_item, pcb_layer_number );
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 else
if( gerb_item->m_Shape == GBR_SPOT_CIRCLE export_copper_item( gerb_item, pcb_layer_number );
|| 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 cleanBoard();
for( TRACK * track = pcb->m_Track; track; track = track->Next() )
{
if( track->m_Shape != VIA_THROUGH )
continue;
// Search and delete others vias // Switch the locale to standard C (needed to print floating point numbers)
TRACK* next_track; SetLocaleTo_C_standard();
TRACK* alt_track = track->Next();
for( ; alt_track; alt_track = next_track )
{
next_track = alt_track->Next();
if( alt_track->m_Shape != VIA_THROUGH )
continue;
if( alt_track->m_Start != track->m_Start ) // write PCB header
continue; fprintf( m_file, "PCBNEW-BOARD Version %d date %s\n\n", g_CurrentVersionPCB,
DateAndTime( line ) );
WriteGeneralDescrPcb( );
WriteSetup( );
// delete track // write items on file
alt_track->UnLink(); m_pcb->Save( m_file );
delete alt_track;
SetLocaleTo_Default(); // revert to the current locale
return true;
}
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;
} }
} }
// Switch the locale to standard C (needed to print floating point numbers m_pcb->Add( drawitem );
// like 1.3) }
SetLocaleTo_C_standard();
// write the PCB heading void GBR_TO_PCB_EXPORTER::export_copper_item( GERBER_DRAW_ITEM* aGbrItem, int aLayer )
fprintf( aFile, "PCBNEW-BOARD Version %d date %s\n\n", g_CurrentVersionPCB, {
DateAndTime( line ) ); switch( aGbrItem->m_Shape )
WriteGeneralDescrPcb( pcb, aFile ); {
WriteSetup( aFile, pcb ); 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;
// write the useful part of the pcb case GBR_ARC:
pcb->Save( aFile ); // export_segarc_copper_item( aGbrItem, aLayer );
break;
// the destructor should destroy all owned sub-objects default:
delete pcb; export_segline_copper_item( aGbrItem, aLayer );
break;
}
}
SetLocaleTo_Default(); // revert to the current locale void GBR_TO_PCB_EXPORTER::export_segline_copper_item( GERBER_DRAW_ITEM* aGbrItem, int aLayer )
wxEndBusyCursor(); {
return 1; 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 );
} }
...@@ -2,16 +2,19 @@ ...@@ -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 { ...@@ -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: ...@@ -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() ...@@ -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 ) : ...@@ -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
// Provide a separate FlexGrid sizer for every sixteen sets of controls // layer has been mapped to a pcbnew layer or is not being
if( ii % 16 == 0 ) // exported at all). (Experimentation has shown that if a text
{ // control is used to depict which pcbnew layer that each Gerber
// Each Gerber layer has an associated static text string (to // layer is mapped to (instead of a static text string), then
// identify that layer), a button (for invoking a child dialog // those controls do not behave in a fully satisfactory manner
// box to change which pcbnew layer that the Gerber layer is // in the Linux version. Even when the read-only attribute is
// mapped to), and a second static text string (to depict which // specified for all of those controls, they can still be selected
// pcbnew layer that the Gerber layer has been mapped to). Each // when the arrow keys or Tab key is used to step through all of
// of those items are placed into the left hand column, middle // the controls within the dialog box, and directives to set the
// column, and right hand column (respectively) of the Flexgrid // foreground color of the text of each such control to blue (to
// sizer, and the color of the second text string is set to // indicate that the text is of a read-only nature) are disregarded.
// fuchsia or blue (to respectively indicate whether the Gerber // Specify a FlexGrid sizer with an appropriate number of rows
// layer has been mapped to a pcbnew layer or is not being // and three columns. If nb_items < 16, then the number of rows
// exported at all). (Experimentation has shown that if a text // is nb_items; otherwise, the number of rows is 16 (with two
// control is used to depict which pcbnew layer that each Gerber // separate columns of controls being used if nb_items > 16).
// layer is mapped to (instead of a static text string), then
// those controls do not behave in a fully satisfactory manner if( ii == 16 )
// in the Linux version. Even when the read-only attribute is flexColumnBoxSizer = m_flexRightColumnBoxSizer;
// 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 ) : ...@@ -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 ) : ...@@ -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 ) ...@@ -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 ) ...@@ -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 );
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment