Commit 57604b0a authored by jean-pierre charras's avatar jean-pierre charras

Gerbview: export_to_pcbnew enhancement and fixes.

parent 81947a4f
......@@ -6,7 +6,7 @@
#endif
#ifndef KICAD_BUILD_VERSION
#define KICAD_BUILD_VERSION "(2011-04-17)"
#define KICAD_BUILD_VERSION "(2011-04-24)"
#endif
......
......@@ -9,15 +9,16 @@
///////////////////////////////////////////////////////////////////////////
BEGIN_EVENT_TABLE( LAYERS_TABLE_DIALOG_BASE, wxDialog )
EVT_BUTTON( ID_STORE_CHOICE, LAYERS_TABLE_DIALOG_BASE::_wxFB_OnStoreSetup )
EVT_BUTTON( ID_GET_PREVIOUS_CHOICE, LAYERS_TABLE_DIALOG_BASE::_wxFB_OnGetSetup )
EVT_BUTTON( ID_RESET_CHOICE, LAYERS_TABLE_DIALOG_BASE::_wxFB_OnResetClick )
EVT_BUTTON( wxID_CANCEL, LAYERS_TABLE_DIALOG_BASE::_wxFB_OnCancelClick )
EVT_BUTTON( wxID_OK, LAYERS_TABLE_DIALOG_BASE::_wxFB_OnOkClick )
BEGIN_EVENT_TABLE( LAYERS_MAP_DIALOG_BASE, wxDialog )
EVT_COMBOBOX( ID_M_COMBOCOPPERLAYERSCOUNT, LAYERS_MAP_DIALOG_BASE::_wxFB_OnBrdLayersCountSelection )
EVT_BUTTON( ID_STORE_CHOICE, LAYERS_MAP_DIALOG_BASE::_wxFB_OnStoreSetup )
EVT_BUTTON( ID_GET_PREVIOUS_CHOICE, LAYERS_MAP_DIALOG_BASE::_wxFB_OnGetSetup )
EVT_BUTTON( ID_RESET_CHOICE, LAYERS_MAP_DIALOG_BASE::_wxFB_OnResetClick )
EVT_BUTTON( wxID_CANCEL, LAYERS_MAP_DIALOG_BASE::_wxFB_OnCancelClick )
EVT_BUTTON( wxID_OK, LAYERS_MAP_DIALOG_BASE::_wxFB_OnOkClick )
END_EVENT_TABLE()
LAYERS_TABLE_DIALOG_BASE::LAYERS_TABLE_DIALOG_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
LAYERS_MAP_DIALOG_BASE::LAYERS_MAP_DIALOG_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
......@@ -42,17 +43,33 @@ LAYERS_TABLE_DIALOG_BASE::LAYERS_TABLE_DIALOG_BASE( wxWindow* parent, wxWindowID
m_staticlineSep = new wxStaticLine( this, ID_M_STATICLINESEP, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL );
sbSizerLayersTable->Add( m_staticlineSep, 0, wxEXPAND | wxALL, 5 );
m_flexRightColumnBoxSizer = new wxFlexGridSizer( 16, 4, 0, 0 );
m_flexRightColumnBoxSizer->AddGrowableCol( 0 );
m_flexRightColumnBoxSizer->AddGrowableCol( 1 );
m_flexRightColumnBoxSizer->AddGrowableCol( 2 );
m_flexRightColumnBoxSizer->AddGrowableCol( 3 );
m_flexRightColumnBoxSizer->SetFlexibleDirection( wxBOTH );
m_flexRightColumnBoxSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
sbUpperSizer->Add( sbSizerLayersTable, 1, wxEXPAND, 5 );
sbSizerLayersTable->Add( m_flexRightColumnBoxSizer, 1, wxEXPAND, 5 );
wxBoxSizer* bRightSizer;
bRightSizer = new wxBoxSizer( wxVERTICAL );
sbUpperSizer->Add( sbSizerLayersTable, 1, wxEXPAND, 5 );
wxBoxSizer* bSizerLyrCnt;
bSizerLyrCnt = new wxBoxSizer( wxVERTICAL );
m_staticTextCopperlayerCount = new wxStaticText( this, ID_M_STATICTEXTCOPPERLAYERCOUNT, _("Copper layers count:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextCopperlayerCount->Wrap( -1 );
bSizerLyrCnt->Add( m_staticTextCopperlayerCount, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
m_comboCopperLayersCount = new wxComboBox( this, ID_M_COMBOCOPPERLAYERSCOUNT, _("2 Layers"), wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
m_comboCopperLayersCount->Append( _("2 Layers") );
m_comboCopperLayersCount->Append( _("4 Layers") );
m_comboCopperLayersCount->Append( _("6 Layers") );
m_comboCopperLayersCount->Append( _("8 Layers") );
m_comboCopperLayersCount->Append( _("10 Layers") );
m_comboCopperLayersCount->Append( _("12 Layers") );
m_comboCopperLayersCount->Append( _("14 Layers") );
m_comboCopperLayersCount->Append( _("16 Layers") );
bSizerLyrCnt->Add( m_comboCopperLayersCount, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
bRightSizer->Add( bSizerLyrCnt, 0, wxEXPAND, 5 );
bRightSizer->Add( 5, 15, 1, wxEXPAND, 5 );
wxBoxSizer* bSizerButtons;
bSizerButtons = new wxBoxSizer( wxVERTICAL );
......@@ -66,7 +83,9 @@ LAYERS_TABLE_DIALOG_BASE::LAYERS_TABLE_DIALOG_BASE( wxWindow* parent, wxWindowID
m_buttonReset = new wxButton( this, ID_RESET_CHOICE, _("Reset"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerButtons->Add( m_buttonReset, 0, wxALL|wxEXPAND, 5 );
sbUpperSizer->Add( bSizerButtons, 0, wxALIGN_CENTER_VERTICAL, 5 );
bRightSizer->Add( bSizerButtons, 0, wxEXPAND, 5 );
sbUpperSizer->Add( bRightSizer, 0, wxALIGN_CENTER_VERTICAL, 5 );
bSizerMain->Add( sbUpperSizer, 1, wxEXPAND, 5 );
......@@ -87,6 +106,6 @@ LAYERS_TABLE_DIALOG_BASE::LAYERS_TABLE_DIALOG_BASE( wxWindow* parent, wxWindowID
this->Centre( wxBOTH );
}
LAYERS_TABLE_DIALOG_BASE::~LAYERS_TABLE_DIALOG_BASE()
LAYERS_MAP_DIALOG_BASE::~LAYERS_MAP_DIALOG_BASE()
{
}
......@@ -18,20 +18,23 @@
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/statbox.h>
#include <wx/stattext.h>
#include <wx/combobox.h>
#include <wx/button.h>
#include <wx/dialog.h>
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// Class LAYERS_TABLE_DIALOG_BASE
/// Class LAYERS_MAP_DIALOG_BASE
///////////////////////////////////////////////////////////////////////////////
class LAYERS_TABLE_DIALOG_BASE : public wxDialog
class LAYERS_MAP_DIALOG_BASE : public wxDialog
{
DECLARE_EVENT_TABLE()
private:
// Private event handlers
void _wxFB_OnBrdLayersCountSelection( wxCommandEvent& event ){ OnBrdLayersCountSelection( event ); }
void _wxFB_OnStoreSetup( wxCommandEvent& event ){ OnStoreSetup( event ); }
void _wxFB_OnGetSetup( wxCommandEvent& event ){ OnGetSetup( event ); }
void _wxFB_OnResetClick( wxCommandEvent& event ){ OnResetClick( event ); }
......@@ -42,7 +45,10 @@ class LAYERS_TABLE_DIALOG_BASE : public wxDialog
protected:
enum
{
ID_M_STATICLINESEP = 1000,
ID_LAYERS_MAP_DIALOG_BASE = 1000,
ID_M_STATICLINESEP,
ID_M_STATICTEXTCOPPERLAYERCOUNT,
ID_M_COMBOCOPPERLAYERSCOUNT,
ID_STORE_CHOICE,
ID_GET_PREVIOUS_CHOICE,
ID_RESET_CHOICE,
......@@ -51,7 +57,9 @@ class LAYERS_TABLE_DIALOG_BASE : public wxDialog
wxStaticBoxSizer* sbSizerLayersTable;
wxFlexGridSizer* m_flexLeftColumnBoxSizer;
wxStaticLine* m_staticlineSep;
wxFlexGridSizer* m_flexRightColumnBoxSizer;
wxStaticText* m_staticTextCopperlayerCount;
wxComboBox* m_comboCopperLayersCount;
wxButton* m_buttonStore;
wxButton* m_buttonRetrieve;
wxButton* m_buttonReset;
......@@ -61,6 +69,7 @@ class LAYERS_TABLE_DIALOG_BASE : public wxDialog
wxButton* m_sdbSizerButtonsCancel;
// Virtual event handlers, overide them in your derived class
virtual void OnBrdLayersCountSelection( wxCommandEvent& event ) { event.Skip(); }
virtual void OnStoreSetup( wxCommandEvent& event ) { event.Skip(); }
virtual void OnGetSetup( wxCommandEvent& event ) { event.Skip(); }
virtual void OnResetClick( wxCommandEvent& event ) { event.Skip(); }
......@@ -70,8 +79,8 @@ class LAYERS_TABLE_DIALOG_BASE : public wxDialog
public:
LAYERS_TABLE_DIALOG_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Layer selection:"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 400,286 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~LAYERS_TABLE_DIALOG_BASE();
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( 400,286 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~LAYERS_MAP_DIALOG_BASE();
};
......
......@@ -15,7 +15,7 @@
#include "gerbview.h"
#include "class_board_design_settings.h"
#include "class_gerber_draw_item.h"
#include "select_layers_to_pcb.h"
/* A helper class to export a Gerber set of files to Pcbnew
*/
......@@ -29,6 +29,7 @@ public:
GBR_TO_PCB_EXPORTER(GERBVIEW_FRAME * aFrame, FILE * aFile );
~GBR_TO_PCB_EXPORTER();
bool ExportPcb( int* LayerLookUpTable );
BOARD* GetBoard() { return m_pcb; }
private:
bool WriteSetup( ); // Write the SETUP section data file
......@@ -45,12 +46,11 @@ GBR_TO_PCB_EXPORTER::GBR_TO_PCB_EXPORTER( GERBVIEW_FRAME * aFrame, FILE * aFile
{
m_gerbview_frame = aFrame;
m_file = aFile;
m_pcb = NULL;
m_pcb = new BOARD( NULL, m_gerbview_frame );
}
GBR_TO_PCB_EXPORTER::~GBR_TO_PCB_EXPORTER()
{
// the destructor should destroy all owned sub-objects
delete m_pcb;
}
......@@ -95,26 +95,31 @@ void GERBVIEW_FRAME::ExportDataInPcbnewFormat( wxCommandEvent& event )
if( FullFileName == wxEmptyString )
return;
int* LayerLookUpTable;
if( ( LayerLookUpTable = InstallDialogLayerPairChoice( ) ) != NULL )
/* Install a dialog frame to choose the mapping
* between gerber layers and pcbnew layers
*/
LAYERS_MAP_DIALOG* dlg = new LAYERS_MAP_DIALOG( this );
int ok = dlg->ShowModal();
dlg->Destroy();
if( ok != wxID_OK )
return;
if( wxFileExists( FullFileName ) )
{
if( wxFileExists( FullFileName ) )
{
if( !IsOK( this, _( "Ok to change the existing file ?" ) ) )
return;
}
FILE * file = wxFopen( FullFileName, wxT( "wt" ) );
if( file == NULL )
{
msg = _( "Unable to create " ) + FullFileName;
DisplayError( this, msg );
if( !IsOK( this, _( "Ok to change the existing file ?" ) ) )
return;
}
GetScreen()->SetFileName( FullFileName );
GBR_TO_PCB_EXPORTER gbr_exporter( this, file );
gbr_exporter.ExportPcb( LayerLookUpTable );
fclose( file );
}
FILE * file = wxFopen( FullFileName, wxT( "wt" ) );
if( file == NULL )
{
msg = _( "Unable to create " ) + FullFileName;
DisplayError( this, msg );
return;
}
GBR_TO_PCB_EXPORTER gbr_exporter( this, file );
gbr_exporter.ExportPcb( dlg->GetLayersLookUpTable() );
fclose( file );
}
void GBR_TO_PCB_EXPORTER::cleanBoard()
......@@ -195,7 +200,6 @@ bool GBR_TO_PCB_EXPORTER::ExportPcb( int* LayerLookUpTable )
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() )
{
......
......@@ -509,14 +509,6 @@ public: GERBVIEW_FRAME( wxWindow* father, const wxString& title,
virtual void PrintPage( wxDC* aDC, int aPrintMasklayer, bool aPrintMirrorMode,
void* aData = NULL );
/**
* Function InstallDialogLayerPairChoice
* Install a dialog frame to choose the equivalence
* between gerber layers and pcbnew layers
* @return the "lookup table" if ok, or NULL
*/
int* InstallDialogLayerPairChoice();
/**
* Function DrawItemsDCodeID
* Draw the DCode value (if exists) corresponding to gerber item
......
This diff is collapsed.
/*******************************************************/
/* Dialog frame to choose gerber layers and pcb layers */
/*******************************************************/
/**
* @file select_layers_to_pcb.h
*/
#ifndef _SELECT_LAYERS_TO_PCB_H_
#define _SELECT_LAYERS_TO_PCB_H_
#include "wx/statline.h"
#include "dialogs/dialog_layers_select_to_pcb_base.h"
#define LAYER_UNSELECTED NB_LAYERS
/*
* This dialog shows the gerber files loaded, and allows user to choose:
* what gerber file and what board layer are used
* the number of copper layers
*/
class LAYERS_MAP_DIALOG : public LAYERS_MAP_DIALOG_BASE
{
private:
GERBVIEW_FRAME* m_Parent;
int m_itemsCount;
int m_exportBoardCopperLayersCount;
wxFlexGridSizer* m_flexRightColumnBoxSizer; // An extra wxFlexGridSizer used
// when we have more than 16 gerber files loaded
int m_layersLookUpTable[32+1]; // Indexes Gerber layers to PCB file layers
// the last value in table is the number of copper layers
int m_buttonTable[32]; // Indexes buttons to Gerber layers
wxStaticText* m_layersList[32]; // Indexes text strings to buttons
public: LAYERS_MAP_DIALOG( GERBVIEW_FRAME* parent );
~LAYERS_MAP_DIALOG() {};
int * GetLayersLookUpTable() { return m_layersLookUpTable; }
int GetCopperLayersCount() { return m_exportBoardCopperLayersCount; }
private:
void initDialog();
void normalizeBrdLayersCount();
void OnBrdLayersCountSelection( wxCommandEvent& event );
void OnSelectLayer( wxCommandEvent& event );
void OnOkClick( wxCommandEvent& event );
void OnCancelClick( wxCommandEvent& event );
void OnStoreSetup( wxCommandEvent& event );
void OnGetSetup( wxCommandEvent& event );
void OnResetClick( wxCommandEvent& event );
DECLARE_EVENT_TABLE()
};
#endif // _SELECT_LAYERS_TO_PCB_H_
......@@ -17,7 +17,7 @@
; General Product Description Definitions
!define PRODUCT_NAME "KiCad"
!define PRODUCT_VERSION "2011.04.17"
!define PRODUCT_VERSION "2011.04.24"
!define PRODUCT_WEB_SITE "http://iut-tice.ujf-grenoble.fr/kicad/"
!define SOURCEFORGE_WEB_SITE "http://kicad.sourceforge.net/"
!define COMPANY_NAME ""
......
/* Set up the basic primitives for Layer control */
#include "fctsys.h"
#include "gr_basic.h"
#include "common.h"
#include "class_drawpanel.h"
#include "confirm.h"
#include "pcbnew.h"
#include "class_board_design_settings.h"
#include "protos.h"
enum layer_sel_id {
......@@ -18,7 +16,7 @@ enum layer_sel_id {
};
class WinEDA_SelLayerFrame : public wxDialog
class SELECT_LAYER_DIALOG : public wxDialog
{
private:
PCB_BASE_FRAME* m_Parent;
......@@ -28,9 +26,9 @@ private:
public:
// Constructor and destructor
WinEDA_SelLayerFrame( PCB_BASE_FRAME* parent, int default_layer,
SELECT_LAYER_DIALOG( PCB_BASE_FRAME* parent, int default_layer,
int min_layer, int max_layer, bool null_layer );
~WinEDA_SelLayerFrame() { };
~SELECT_LAYER_DIALOG() { };
private:
void Sel_Layer( wxCommandEvent& event );
......@@ -40,10 +38,10 @@ private:
};
BEGIN_EVENT_TABLE( WinEDA_SelLayerFrame, wxDialog )
EVT_BUTTON( wxID_OK, WinEDA_SelLayerFrame::Sel_Layer )
EVT_BUTTON( wxID_CANCEL, WinEDA_SelLayerFrame::OnCancelClick )
EVT_RADIOBOX( ID_LAYER_SELECT, WinEDA_SelLayerFrame::Sel_Layer )
BEGIN_EVENT_TABLE( SELECT_LAYER_DIALOG, wxDialog )
EVT_BUTTON( wxID_OK, SELECT_LAYER_DIALOG::Sel_Layer )
EVT_BUTTON( wxID_CANCEL, SELECT_LAYER_DIALOG::OnCancelClick )
EVT_RADIOBOX( ID_LAYER_SELECT, SELECT_LAYER_DIALOG::Sel_Layer )
END_EVENT_TABLE()
......@@ -70,7 +68,7 @@ int PCB_BASE_FRAME::SelectLayer( int default_layer,
bool null_layer )
{
int layer;
WinEDA_SelLayerFrame* frame = new WinEDA_SelLayerFrame( this,
SELECT_LAYER_DIALOG* frame = new SELECT_LAYER_DIALOG( this,
default_layer,
min_layer,
max_layer,
......@@ -88,7 +86,7 @@ int PCB_BASE_FRAME::SelectLayer( int default_layer,
* radiobuttons, in which case they are positioned (in a vertical line)
* to the right of that radiobox.
*/
WinEDA_SelLayerFrame::WinEDA_SelLayerFrame( PCB_BASE_FRAME* parent,
SELECT_LAYER_DIALOG::SELECT_LAYER_DIALOG( PCB_BASE_FRAME* parent,
int default_layer, int min_layer,
int max_layer, bool null_layer ) :
wxDialog( parent, -1, _( "Select Layer:" ), wxPoint( -1, -1 ),
......@@ -165,14 +163,11 @@ WinEDA_SelLayerFrame::WinEDA_SelLayerFrame( PCB_BASE_FRAME* parent,
Button = new wxButton( this, wxID_CANCEL, _( "Cancel" ) );
ButtonBoxSizer->Add( Button, 0, wxGROW | wxALL, 5 );
if( GetSizer() )
{
GetSizer()->SetSizeHints( this );
}
GetSizer()->SetSizeHints( this );
}
void WinEDA_SelLayerFrame::Sel_Layer( wxCommandEvent& event )
void SELECT_LAYER_DIALOG::Sel_Layer( wxCommandEvent& event )
{
int ii = m_LayerId[m_LayerList->GetSelection()];
......@@ -180,7 +175,7 @@ void WinEDA_SelLayerFrame::Sel_Layer( wxCommandEvent& event )
}
void WinEDA_SelLayerFrame::OnCancelClick( wxCommandEvent& event )
void SELECT_LAYER_DIALOG::OnCancelClick( wxCommandEvent& event )
{
EndModal( -1 );
}
......@@ -190,7 +185,7 @@ void WinEDA_SelLayerFrame::OnCancelClick( wxCommandEvent& event )
/* Dialog for the selecting pairs of layers. */
/*********************************************/
class WinEDA_SelLayerPairFrame : public wxDialog
class SELECT_LAYERS_PAIR_DIALOG : public wxDialog
{
private:
PCB_BASE_FRAME* m_Parent;
......@@ -198,8 +193,8 @@ private:
wxRadioBox* m_LayerListBOTTOM;
int m_LayerId[NB_COPPER_LAYERS];
public: WinEDA_SelLayerPairFrame( PCB_BASE_FRAME* parent );
~WinEDA_SelLayerPairFrame() { };
public: SELECT_LAYERS_PAIR_DIALOG( PCB_BASE_FRAME* parent );
~SELECT_LAYERS_PAIR_DIALOG() { };
private:
void OnOkClick( wxCommandEvent& event );
......@@ -209,9 +204,9 @@ private:
};
BEGIN_EVENT_TABLE( WinEDA_SelLayerPairFrame, wxDialog )
EVT_BUTTON( wxID_OK, WinEDA_SelLayerPairFrame::OnOkClick )
EVT_BUTTON( wxID_CANCEL, WinEDA_SelLayerPairFrame::OnCancelClick )
BEGIN_EVENT_TABLE( SELECT_LAYERS_PAIR_DIALOG, wxDialog )
EVT_BUTTON( wxID_OK, SELECT_LAYERS_PAIR_DIALOG::OnOkClick )
EVT_BUTTON( wxID_CANCEL, SELECT_LAYERS_PAIR_DIALOG::OnCancelClick )
END_EVENT_TABLE()
......@@ -232,8 +227,8 @@ void PCB_BASE_FRAME::SelectLayerPair()
return;
}
WinEDA_SelLayerPairFrame* frame =
new WinEDA_SelLayerPairFrame( this );
SELECT_LAYERS_PAIR_DIALOG* frame =
new SELECT_LAYERS_PAIR_DIALOG( this );
int result = frame->ShowModal();
frame->Destroy();
......@@ -248,7 +243,7 @@ void PCB_BASE_FRAME::SelectLayerPair()
}
WinEDA_SelLayerPairFrame::WinEDA_SelLayerPairFrame( PCB_BASE_FRAME* parent ) :
SELECT_LAYERS_PAIR_DIALOG::SELECT_LAYERS_PAIR_DIALOG( PCB_BASE_FRAME* parent ) :
wxDialog( parent, -1, _( "Select Layer Pair:" ), wxPoint( -1, -1 ),
wxSize( 470, 250 ), DIALOG_STYLE )
{
......@@ -325,7 +320,7 @@ WinEDA_SelLayerPairFrame::WinEDA_SelLayerPairFrame( PCB_BASE_FRAME* parent ) :
}
void WinEDA_SelLayerPairFrame::OnOkClick( wxCommandEvent& event )
void SELECT_LAYERS_PAIR_DIALOG::OnOkClick( wxCommandEvent& event )
{
// select the same layer for top and bottom is allowed (normal in some
// boards)
......@@ -343,7 +338,7 @@ void WinEDA_SelLayerPairFrame::OnOkClick( wxCommandEvent& event )
}
void WinEDA_SelLayerPairFrame::OnCancelClick( wxCommandEvent& event )
void SELECT_LAYERS_PAIR_DIALOG::OnCancelClick( wxCommandEvent& event )
{
EndModal( -1 );
}
release version:
2011 apr 17
2011 apr 24
files (.zip,.tgz):
kicad-2011-04-17
kicad-2011-04-24
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