Commit e88bc8e5 authored by Dick Hollenbeck's avatar Dick Hollenbeck

LEGACY_PLUGIN is now in full use:

*) for footprint access into *.mod files and 
*) BOARD save/load

The item_io.cpp and ioascii.cpp have been set off to the side for reference
as *.notused, for awhile.

The CMake options USE_NEW_PCBNEW_LOAD and USE_NEW_PCBNEW_SAVE are gone,
this is now the mandatory usage of the LEGACY_PLUGIN.  This should reduce
code maintenance for awhile until the s-expression plugin comes into 
play.  But at least for legacy format, there is not two code bodies
to maintain any more.

A new LEGACY_PLUGIN footprint library caching scheme is in place which 
needs some testing.  It should not be any faster, but might give better 
results in a networked environment if there is *.mod files on the server.
parents bf5802f1 51a83a7a
......@@ -23,8 +23,6 @@ set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMakeModules)
option(USE_PCBNEW_SEXPR_FILE_FORMAT
"Use s-expression Pcbnew file format support (default OFF)." )
option(USE_NEW_PCBNEW_LOAD "use new plugin support for legacy file format" ON)
option(USE_NEW_PCBNEW_SAVE "use new plugin support for legacy file format" ON)
option(USE_PCBNEW_NANOMETRES
"Use nanometers for Pcbnew internal units instead of deci-mils (default OFF).")
......
......@@ -55,8 +55,6 @@
#cmakedefine USE_IMAGES_IN_MENUS 1
#cmakedefine USE_NEW_PCBNEW_LOAD
#cmakedefine USE_NEW_PCBNEW_SAVE
#cmakedefine USE_PCBNEW_NANOMETRES
#cmakedefine USE_PCBNEW_SEXPR_FILE_FORMAT
......
......@@ -116,21 +116,13 @@ set(PCB_COMMON_SRCS
../pcbnew/collectors.cpp
../pcbnew/sel_layer.cpp
../pcbnew/pcb_plot_params.cpp
../pcbnew/io_mgr.cpp
../pcbnew/legacy_plugin.cpp
../pcbnew/kicad_plugin.cpp
pcb_plot_params_keywords.cpp
dialogs/dialog_page_settings.cpp
)
if( USE_NEW_PCBNEW_LOAD OR USE_NEW_PCBNEW_SAVE )
set( PCB_COMMON_SRCS
${PCB_COMMON_SRCS}
../pcbnew/item_io.cpp
../pcbnew/io_mgr.cpp
../pcbnew/legacy_plugin.cpp
../pcbnew/kicad_plugin.cpp
)
else()
set( PCB_COMMON_SRCS ${PCB_COMMON_SRCS} ../pcbnew/item_io.cpp )
endif()
# add -DPCBNEW to compilation of these PCBNEW sources
set_source_files_properties( ${PCB_COMMON_SRCS} PROPERTIES
......
......@@ -111,15 +111,6 @@ void BASE_SCREEN::SetScalingFactor(double aScale )
}
void BASE_SCREEN::SetZoomList( const wxArrayDouble& zoomlist )
{
if( !m_ZoomList.IsEmpty() )
m_ZoomList.Empty();
m_ZoomList = zoomlist;
}
bool BASE_SCREEN::SetFirstZoom()
{
if( m_ZoomList.IsEmpty() )
......
......@@ -368,7 +368,7 @@ void EDA_DRAW_FRAME::OnSelectZoom( wxCommandEvent& event )
else
{
id--;
int selectedZoom = GetScreen()->m_ZoomList[id];
double selectedZoom = GetScreen()->m_ZoomList[id];
if( GetScreen()->GetZoom() == selectedZoom )
return;
......
......@@ -19,6 +19,7 @@
#include <richio.h>
#include <filter_reader.h>
#include <footprint_info.h>
#include <io_mgr.h>
#include <class_pad.h>
#include <class_module.h>
......@@ -39,9 +40,8 @@
* ...... other data (pads, outlines ..)
* $Endmodule
*/
bool FOOTPRINT_LIST::ReadFootprintFiles( wxArrayString & aFootprintsLibNames )
bool FOOTPRINT_LIST::ReadFootprintFiles( wxArrayString& aFootprintsLibNames )
{
FILE* file;
wxFileName filename;
wxString libname;
......@@ -50,7 +50,9 @@ bool FOOTPRINT_LIST::ReadFootprintFiles( wxArrayString & aFootprintsLibNames )
m_filesInvalid.Empty();
m_List.clear();
/* Parse Libraries Listed */
PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::LEGACY ) );
// Parse Libraries Listed
for( unsigned ii = 0; ii < aFootprintsLibNames.GetCount(); ii++ )
{
filename = aFootprintsLibNames[ii];
......@@ -64,82 +66,28 @@ bool FOOTPRINT_LIST::ReadFootprintFiles( wxArrayString & aFootprintsLibNames )
continue;
}
/* Open library file */
file = wxFopen( libname, wxT( "rt" ) );
if( file == NULL )
{
m_filesInvalid << libname << _(" (file cannot be opened)") << wxT("\n");
continue;
}
FILE_LINE_READER fileReader( file, libname );
FILTER_READER reader( fileReader );
/* Read header. */
reader.ReadLine();
char * line = reader.Line();
StrPurge( line );
if( strnicmp( line, FOOTPRINT_LIBRARY_HEADER, FOOTPRINT_LIBRARY_HEADER_CNT ) != 0 )
try
{
wxString msg;
msg.Printf( _( "<%s> is not a valid KiCad PCB footprint library." ),
GetChars( libname ) );
m_filesInvalid << msg << wxT("\n");
continue;
}
wxArrayString fpnames = pi->FootprintEnumerate( libname );
// Read library
bool end = false;
while( !end && reader.ReadLine() )
{
line = reader.Line();
StrPurge( line );
if( strnicmp( line, "$EndLIBRARY", 11 ) == 0 )
{
end = true;
break;
}
if( strnicmp( line, "$MODULE", 7 ) == 0 )
for( unsigned i=0; i<fpnames.GetCount(); ++i )
{
std::auto_ptr<MODULE> m( pi->FootprintLoad( libname, fpnames[i] ) );
line += 7;
FOOTPRINT_INFO* ItemLib = new FOOTPRINT_INFO();
ItemLib->m_Module = FROM_UTF8( StrPurge( line ) );
ItemLib->m_LibName = libname;
AddItem( ItemLib );
while( reader.ReadLine() )
{
line = reader.Line();
StrPurge( line );
if( strnicmp( line, "$EndMODULE", 10 ) == 0 )
break;
FOOTPRINT_INFO* fpinfo = new FOOTPRINT_INFO();
if( strnicmp( line, "$PAD", 4 ) == 0 )
ItemLib->m_padCount++;
fpinfo->m_Module = fpnames[i];
fpinfo->m_LibName = libname;
fpinfo->m_padCount = m->GetPadCount();
fpinfo->m_KeyWord = m->GetKeywords();
fpinfo->m_Doc = m->GetDescription();
int id = ((line[0] & 0xFF) << 8) + (line[1] & 0xFF);
switch( id )
{
/* KeyWords */
case (('K'<<8) + 'w'):
ItemLib->m_KeyWord = FROM_UTF8( StrPurge( line + 3 ) );
break;
/* Doc */
case (('C'<<8) + 'd'):
ItemLib->m_Doc = FROM_UTF8( StrPurge( line + 3 ) );
break;
}
}
AddItem( fpinfo );
}
}
if( !end )
catch( IO_ERROR ioe )
{
m_filesInvalid << libname << _(" (Unexpected end of file)") << wxT("\n");
m_filesInvalid << ioe.errorText << wxT("\n");
}
}
......@@ -147,3 +95,4 @@ bool FOOTPRINT_LIST::ReadFootprintFiles( wxArrayString & aFootprintsLibNames )
return true;
}
......@@ -17,8 +17,7 @@
#include <cvpcb.h>
#include <cvpcb_mainframe.h>
#include <class_DisplayFootprintsFrame.h>
#include <richio.h>
#include <filter_reader.h>
#include <io_mgr.h>
#include <wildcards_and_files_ext.h>
......@@ -29,122 +28,50 @@
* @param CmpName - Module name
* @return - a pointer to the loaded module or NULL.
*/
MODULE* DISPLAY_FOOTPRINTS_FRAME::Get_Module( const wxString& CmpName )
MODULE* DISPLAY_FOOTPRINTS_FRAME::Get_Module( const wxString& aFootprintName )
{
int Found = 0;
unsigned ii;
char* Line;
char Name[255];
wxString tmp, msg;
wxFileName fn;
MODULE* Module = NULL;
CVPCB_MAINFRAME* parent = ( CVPCB_MAINFRAME* ) GetParent();
for( ii = 0; ii < parent->m_ModuleLibNames.GetCount(); ii++ )
try
{
fn = parent->m_ModuleLibNames[ii];
fn.SetExt( FootprintLibFileExtension );
tmp = wxGetApp().FindLibraryPath( fn );
PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::LEGACY ) );
if( !tmp )
for( unsigned i = 0; i < parent->m_ModuleLibNames.GetCount(); ++i )
{
msg.Printf( _( "PCB foot print library file <%s> could not be \
found in the default search paths." ),
GetChars( fn.GetFullName() ) );
wxMessageBox( msg, titleLibLoadError, wxOK | wxICON_ERROR, this );
continue;
}
wxFileName fn = parent->m_ModuleLibNames[i];
FILE* file = wxFopen( tmp, wxT( "rt" ) );
fn.SetExt( FootprintLibFileExtension );
wxString libPath = wxGetApp().FindLibraryPath( fn );
if( file == NULL )
if( !libPath )
{
msg.Printf( _( "Could not open PCB foot print library file <%s>." ),
GetChars( tmp ) );
wxString msg = wxString::Format(
_("PCB foot print library file <%s> could not be found in the default search paths." ),
fn.GetFullName().GetData() );
// @todo we should not be using wxMessageBox directly.
wxMessageBox( msg, titleLibLoadError, wxOK | wxICON_ERROR, this );
continue;
}
FILE_LINE_READER fileReader( file, tmp );
FILTER_READER reader( fileReader );
/* Read header. */
reader.ReadLine();
Line = reader.Line();
StrPurge( Line );
MODULE* footprint = pi->FootprintLoad( libPath, aFootprintName );
if( strnicmp( Line, FOOTPRINT_LIBRARY_HEADER, FOOTPRINT_LIBRARY_HEADER_CNT ) != 0 )
if( footprint )
{
msg.Printf( _( "<%s> is not a valid KiCad PCB foot print library." ),
GetChars( tmp ) );
wxMessageBox( msg, titleLibLoadError, wxOK | wxICON_ERROR, this );
fclose( file );
return NULL;
}
Found = 0;
while( !Found && reader.ReadLine() )
{
Line = reader.Line();
if( strncmp( Line, "$MODULE", 6 ) == 0 )
break;
if( strnicmp( Line, "$INDEX", 6 ) == 0 )
{
while( reader.ReadLine() )
{
Line = reader.Line();
if( strnicmp( Line, "$EndINDEX", 9 ) == 0 )
break;
StrPurge( Line );
if( stricmp( Line, TO_UTF8( CmpName ) ) == 0 )
{
Found = 1;
break;
footprint->SetPosition( wxPoint( 0, 0 ) );
return footprint;
}
}
}
}
while( Found && reader.ReadLine() )
catch( IO_ERROR ioe )
{
Line = reader.Line();
if( Line[0] != '$' )
continue;
if( Line[1] != 'M' )
continue;
if( strnicmp( Line, "$MODULE", 7 ) != 0 )
continue;
/* Read component name. */
sscanf( Line + 7, " %s", Name );
if( stricmp( Name, TO_UTF8( CmpName ) ) == 0 )
{
Module = new MODULE( GetBoard() );
// Switch the locale to standard C (needed to print floating
// point numbers like 1.3)
SetLocaleTo_C_standard();
Module->ReadDescr( &reader );
SetLocaleTo_Default(); // revert to the current locale
Module->SetPosition( wxPoint( 0, 0 ) );
return Module;
}
}
file = NULL;
DisplayError( this, ioe.errorText );
return NULL;
}
msg.Printf( _( "Module %s not found" ), CmpName.GetData() );
wxString msg = wxString::Format( _( "Footprint '%s' not found" ), aFootprintName.GetData() );
DisplayError( this, msg );
return NULL;
}
......@@ -39,7 +39,6 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY::~DIALOG_EDIT_COMPONENT_IN_LIBRARY()
*/
void DIALOG_EDIT_COMPONENT_IN_LIBRARY::initDlg()
{
SetFocus();
m_AliasLocation = -1;
LIB_COMPONENT* component = m_Parent->GetComponent();
......
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Jun 30 2011)
// C++ code generated with wxFormBuilder (version Apr 11 2012)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
......@@ -9,7 +9,7 @@
///////////////////////////////////////////////////////////////////////////
DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
......@@ -50,6 +50,7 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( wx
m_OptionsBoxSizer->Add( m_PinsNameInsideButt, 0, wxALL, 5 );
bSizerBasicPanel->Add( m_OptionsBoxSizer, 0, 0, 5 );
m_staticline3 = new wxStaticLine( m_PanelBasic, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
......@@ -70,6 +71,7 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( wx
m_SelNumberOfUnits = new wxSpinCtrl( m_PanelBasic, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 1, 26, 1 );
bSizernbunits->Add( m_SelNumberOfUnits, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
bSizerMidBasicPanel->Add( bSizernbunits, 1, wxEXPAND, 5 );
wxBoxSizer* bSizer17;
......@@ -84,8 +86,10 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( wx
m_SetSkew = new wxSpinCtrl( m_PanelBasic, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 1, 100, 0 );
bSizer17->Add( m_SetSkew, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
bSizerMidBasicPanel->Add( bSizer17, 1, wxEXPAND, 5 );
bSizerBasicPanel->Add( bSizerMidBasicPanel, 0, wxEXPAND, 5 );
m_staticline1 = new wxStaticLine( m_PanelBasic, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
......@@ -101,6 +105,7 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( wx
bSizerBasicPanel->Add( m_OptionPartsLocked, 0, wxALL, 5 );
m_PanelBasic->SetSizer( bSizerBasicPanel );
m_PanelBasic->Layout();
bSizerBasicPanel->Fit( m_PanelBasic );
......@@ -145,8 +150,10 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( wx
m_buttonBrowseDocFiles = new wxButton( m_PanelDoc, ID_BROWSE_DOC_FILES, _("Browse DocFiles"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerPaneldocbutts->Add( m_buttonBrowseDocFiles, 0, wxALL, 5 );
m_PanelDocBoxSizer->Add( bSizerPaneldocbutts, 0, wxALIGN_CENTER_HORIZONTAL, 5 );
m_PanelDoc->SetSizer( m_PanelDocBoxSizer );
m_PanelDoc->Layout();
m_PanelDocBoxSizer->Fit( m_PanelDoc );
......@@ -167,6 +174,7 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( wx
m_PartAliasListCtrl = new wxListBox( m_PanelAlias, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
bLeftBoxSizerPanelAlias->Add( m_PartAliasListCtrl, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
bSizerMainPanelAlias->Add( bLeftBoxSizerPanelAlias, 1, wxEXPAND, 5 );
wxBoxSizer* bRightBoxSizerPanelAlias;
......@@ -181,8 +189,10 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( wx
m_ButtonDeleteAllAlias = new wxButton( m_PanelAlias, ID_DELETE_ALL_ALIAS, _("Delete All"), wxDefaultPosition, wxDefaultSize, 0 );
bRightBoxSizerPanelAlias->Add( m_ButtonDeleteAllAlias, 0, wxALL, 5 );
bSizerMainPanelAlias->Add( bRightBoxSizerPanelAlias, 0, wxALIGN_CENTER_VERTICAL, 5 );
m_PanelAlias->SetSizer( bSizerMainPanelAlias );
m_PanelAlias->Layout();
bSizerMainPanelAlias->Fit( m_PanelAlias );
......@@ -203,6 +213,7 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( wx
m_FootprintFilterListBox = new wxListBox( m_PanelFootprintFilter, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
bFpFilterLeftBoxSizer->Add( m_FootprintFilterListBox, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
bPanelFpFilterBoxSizer->Add( bFpFilterLeftBoxSizer, 1, wxEXPAND, 5 );
wxBoxSizer* bFpFilterRightBoxSizer;
......@@ -217,8 +228,10 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( wx
m_ButtonDeleteAllFootprintFilter = new wxButton( m_PanelFootprintFilter, ID_DELETE_ALL_FOOTPRINT_FILTER, _("Delete All"), wxDefaultPosition, wxDefaultSize, 0 );
bFpFilterRightBoxSizer->Add( m_ButtonDeleteAllFootprintFilter, 0, wxALL|wxEXPAND, 5 );
bPanelFpFilterBoxSizer->Add( bFpFilterRightBoxSizer, 0, wxALIGN_CENTER_VERTICAL, 5 );
m_PanelFootprintFilter->SetSizer( bPanelFpFilterBoxSizer );
m_PanelFootprintFilter->Layout();
bPanelFpFilterBoxSizer->Fit( m_PanelFootprintFilter );
......@@ -226,6 +239,7 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( wx
bUpperSizer->Add( m_NoteBook, 1, wxEXPAND, 5 );
bMainSizer->Add( bUpperSizer, 1, wxEXPAND, 5 );
m_stdSizerButton = new wxStdDialogButtonSizer();
......@@ -234,10 +248,13 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( wx
m_stdSizerButtonCancel = new wxButton( this, wxID_CANCEL );
m_stdSizerButton->AddButton( m_stdSizerButtonCancel );
m_stdSizerButton->Realize();
bMainSizer->Add( m_stdSizerButton, 0, wxEXPAND|wxALL, 5 );
this->SetSizer( bMainSizer );
this->Layout();
bMainSizer->Fit( this );
// Connect Events
m_ButtonCopyDoc->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::CopyDocToAlias ), NULL, this );
......
This source diff could not be displayed because it is too large. You can view the blob instead.
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Jun 30 2011)
// C++ code generated with wxFormBuilder (version Apr 11 2012)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
......@@ -11,6 +11,7 @@
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
#include "dialog_shim.h"
#include <wx/string.h>
#include <wx/checkbox.h>
#include <wx/gdicmn.h>
......@@ -47,7 +48,7 @@
///////////////////////////////////////////////////////////////////////////////
/// Class DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE
///////////////////////////////////////////////////////////////////////////////
class DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE : public wxDialog
class DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE : public DIALOG_SHIM
{
private:
......@@ -106,7 +107,7 @@ class DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE : public wxDialog
public:
DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( wxWindow* parent, wxWindowID id = ID_LIBEDIT_NOTEBOOK, const wxString& title = _("Lib Component Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 465,384 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( wxWindow* parent, wxWindowID id = ID_LIBEDIT_NOTEBOOK, const wxString& title = _("Lib Component Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE();
};
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Apr 16 2008)
// C++ code generated with wxFormBuilder (version Apr 11 2012)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
......@@ -9,7 +9,7 @@
///////////////////////////////////////////////////////////////////////////
DIALOG_LIB_NEW_COMPONENT_BASE::DIALOG_LIB_NEW_COMPONENT_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
DIALOG_LIB_NEW_COMPONENT_BASE::DIALOG_LIB_NEW_COMPONENT_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
......@@ -46,6 +46,7 @@ DIALOG_LIB_NEW_COMPONENT_BASE::DIALOG_LIB_NEW_COMPONENT_BASE( wxWindow* parent,
bSizer2->Add( 30, 0, 0, wxEXPAND, 3 );
bSizer5->Add( bSizer2, 0, wxALL|wxEXPAND, 0 );
wxBoxSizer* bSizer3;
......@@ -69,6 +70,7 @@ DIALOG_LIB_NEW_COMPONENT_BASE::DIALOG_LIB_NEW_COMPONENT_BASE( wxWindow* parent,
bSizer3->Add( 30, 0, 0, wxEXPAND, 5 );
bSizer5->Add( bSizer3, 0, wxALL|wxEXPAND, 0 );
wxBoxSizer* bSizer4;
......@@ -92,6 +94,7 @@ DIALOG_LIB_NEW_COMPONENT_BASE::DIALOG_LIB_NEW_COMPONENT_BASE( wxWindow* parent,
bSizer4->Add( 30, 0, 0, wxEXPAND, 3 );
bSizer5->Add( bSizer4, 0, wxALL|wxEXPAND, 0 );
wxBoxSizer* bSizer7;
......@@ -101,11 +104,11 @@ DIALOG_LIB_NEW_COMPONENT_BASE::DIALOG_LIB_NEW_COMPONENT_BASE( wxWindow* parent,
bSizer7->Add( 12, 0, 0, wxEXPAND, 3 );
m_checkHasConversion = new wxCheckBox( this, wxID_ANY, _("Create component with &alternate body style (DeMorgan)"), wxDefaultPosition, wxDefaultSize, 0 );
m_checkHasConversion->SetToolTip( _("Check this option for components that have a De Morgan representation.\nThis is usual for gates.") );
bSizer7->Add( m_checkHasConversion, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
bSizer5->Add( bSizer7, 0, wxALL|wxEXPAND, 0 );
wxBoxSizer* bSizer8;
......@@ -115,11 +118,11 @@ DIALOG_LIB_NEW_COMPONENT_BASE::DIALOG_LIB_NEW_COMPONENT_BASE( wxWindow* parent,
bSizer8->Add( 12, 0, 0, wxEXPAND, 3 );
m_checkIsPowerSymbol = new wxCheckBox( this, wxID_ANY, _("Create component as power &symbol"), wxDefaultPosition, wxDefaultSize, 0 );
m_checkIsPowerSymbol->SetToolTip( _("Check this option for power symbols.\nPower symbols have specific properties for Eeschema:\n- Value cannot be edited (to avoid mistakes) because this is the pin name that is important for a power symbol\n- Reference is updated automatically when a netlist is created (no need to run Annotate)") );
bSizer8->Add( m_checkIsPowerSymbol, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
bSizer5->Add( bSizer8, 0, wxALL|wxEXPAND, 0 );
wxBoxSizer* bSizer9;
......@@ -129,11 +132,11 @@ DIALOG_LIB_NEW_COMPONENT_BASE::DIALOG_LIB_NEW_COMPONENT_BASE( wxWindow* parent,
bSizer9->Add( 12, 0, 0, wxEXPAND, 3 );
m_checkLockItems = new wxCheckBox( this, wxID_ANY, _("Parts in package locked (cannot be swapped)"), wxDefaultPosition, wxDefaultSize, 0 );
m_checkLockItems->SetToolTip( _("Check this option if Eeschema cannot change parts selections inside a given package\nThis happens when parts are different in this package.\nWhen this option is not checked, Eeschema automatically choose the parts in packages to minimize packages count") );
bSizer9->Add( m_checkLockItems, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
bSizer5->Add( bSizer9, 0, wxALL|wxEXPAND, 0 );
......@@ -167,6 +170,7 @@ DIALOG_LIB_NEW_COMPONENT_BASE::DIALOG_LIB_NEW_COMPONENT_BASE( wxWindow* parent,
m_staticText5->Wrap( -1 );
bSizer6->Add( m_staticText5, 0, wxALIGN_CENTER_VERTICAL, 3 );
bSizer5->Add( bSizer6, 1, wxALL|wxEXPAND, 0 );
wxBoxSizer* bSizer10;
......@@ -177,9 +181,9 @@ DIALOG_LIB_NEW_COMPONENT_BASE::DIALOG_LIB_NEW_COMPONENT_BASE( wxWindow* parent,
m_checkShowPinNumber = new wxCheckBox( this, wxID_ANY, _("Show pin n&umber text"), wxDefaultPosition, wxDefaultSize, 0 );
m_checkShowPinNumber->SetValue(true);
bSizer10->Add( m_checkShowPinNumber, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
bSizer5->Add( bSizer10, 0, wxALL|wxEXPAND, 0 );
wxBoxSizer* bSizer12;
......@@ -190,9 +194,9 @@ DIALOG_LIB_NEW_COMPONENT_BASE::DIALOG_LIB_NEW_COMPONENT_BASE( wxWindow* parent,
m_checkShowPinName = new wxCheckBox( this, wxID_ANY, _("Show pin name te&xt"), wxDefaultPosition, wxDefaultSize, 0 );
m_checkShowPinName->SetValue(true);
bSizer12->Add( m_checkShowPinName, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
bSizer5->Add( bSizer12, 0, wxALL|wxEXPAND, 0 );
wxBoxSizer* bSizer121;
......@@ -203,9 +207,9 @@ DIALOG_LIB_NEW_COMPONENT_BASE::DIALOG_LIB_NEW_COMPONENT_BASE( wxWindow* parent,
m_checkShowPinNameInside = new wxCheckBox( this, wxID_ANY, _("Pin name &inside"), wxDefaultPosition, wxDefaultSize, 0 );
m_checkShowPinNameInside->SetValue(true);
bSizer121->Add( m_checkShowPinNameInside, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
bSizer5->Add( bSizer121, 1, wxEXPAND, 5 );
......@@ -217,10 +221,13 @@ DIALOG_LIB_NEW_COMPONENT_BASE::DIALOG_LIB_NEW_COMPONENT_BASE( wxWindow* parent,
m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
m_sdbSizer->AddButton( m_sdbSizerCancel );
m_sdbSizer->Realize();
bSizer5->Add( m_sdbSizer, 0, wxALL|wxEXPAND, 0 );
mainSizer->Add( bSizer5, 1, wxALL|wxEXPAND, 12 );
this->SetSizer( mainSizer );
this->Layout();
mainSizer->Fit( this );
......
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Apr 16 2008)
// C++ code generated with wxFormBuilder (version Apr 11 2012)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#ifndef __dialog_lib_new_component_base__
#define __dialog_lib_new_component_base__
#ifndef __DIALOG_LIB_NEW_COMPONENT_BASE_H__
#define __DIALOG_LIB_NEW_COMPONENT_BASE_H__
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
#include "dialog_shim.h"
#include <wx/string.h>
#include <wx/stattext.h>
#include <wx/gdicmn.h>
......@@ -28,55 +30,37 @@
///////////////////////////////////////////////////////////////////////////////
/// Class DIALOG_LIB_NEW_COMPONENT_BASE
///////////////////////////////////////////////////////////////////////////////
class DIALOG_LIB_NEW_COMPONENT_BASE : public wxDialog
class DIALOG_LIB_NEW_COMPONENT_BASE : public DIALOG_SHIM
{
private:
protected:
wxStaticText* m_staticText6;
wxStaticText* m_staticText2;
wxTextCtrl* m_textName;
wxStaticText* m_staticText3;
wxTextCtrl* m_textReference;
wxStaticText* m_staticText4;
wxSpinCtrl* m_spinPartCount;
wxCheckBox* m_checkHasConversion;
wxCheckBox* m_checkIsPowerSymbol;
wxCheckBox* m_checkLockItems;
wxStaticText* m_staticText7;
wxStaticText* m_staticText41;
wxSpinCtrl* m_spinPinTextPosition;
wxStaticText* m_staticText5;
wxCheckBox* m_checkShowPinNumber;
wxCheckBox* m_checkShowPinName;
wxCheckBox* m_checkShowPinNameInside;
wxStdDialogButtonSizer* m_sdbSizer;
wxButton* m_sdbSizerOK;
wxButton* m_sdbSizerCancel;
public:
DIALOG_LIB_NEW_COMPONENT_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Component Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_LIB_NEW_COMPONENT_BASE();
};
#endif //__dialog_lib_new_component_base__
#endif //__DIALOG_LIB_NEW_COMPONENT_BASE_H__
......@@ -50,7 +50,7 @@
#include <dialogs/dialog_edit_component_in_lib.h>
#include <dialogs/dialog_libedit_dimensions.h>
#include <dialog_helpers.h>
//#include <dialog_helpers.h>
#include <menus_helpers.h>
#include <boost/foreach.hpp>
......
......@@ -15,6 +15,7 @@
#include <../pcbnew/class_track.h>
#include <../pcbnew/class_drawsegment.h>
#include <io_mgr.h>
#include <gerbview.h>
#include <class_board_design_settings.h>
#include <class_gerber_draw_item.h>
......@@ -26,32 +27,35 @@
*/
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( GERBVIEW_FRAME* aFrame, const wxString& aFileName );
~GBR_TO_PCB_EXPORTER();
/**
* Function ExportPcb
* saves a board from a gerber load.
*/
bool ExportPcb( int* LayerLookUpTable );
BOARD* GetBoard() { return m_pcb; }
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();
GERBVIEW_FRAME* m_gerbview_frame; // the maint gerber frame
wxString m_file_name; // BOARD file to write to
BOARD* m_pcb; // the board to populate and export
};
GBR_TO_PCB_EXPORTER::GBR_TO_PCB_EXPORTER( GERBVIEW_FRAME * aFrame, FILE * aFile )
GBR_TO_PCB_EXPORTER::GBR_TO_PCB_EXPORTER( GERBVIEW_FRAME* aFrame, const wxString& aFileName )
{
m_gerbview_frame = aFrame;
m_file = aFile;
m_file_name = aFileName;
m_pcb = new BOARD();
}
......@@ -84,12 +88,12 @@ void GERBVIEW_FRAME::ExportDataInPcbnewFormat( wxCommandEvent& event )
return;
}
wxString FullFileName, msg;
wxString fileName, msg;
wxString PcbExt( wxT( ".brd" ) );
msg = wxT( "*" ) + PcbExt;
FullFileName = EDA_FileSelector( _( "Board file name:" ),
fileName = EDA_FileSelector( _( "Board file name:" ),
wxEmptyString,
wxEmptyString,
PcbExt,
......@@ -98,7 +102,7 @@ void GERBVIEW_FRAME::ExportDataInPcbnewFormat( wxCommandEvent& event )
wxFD_SAVE,
false
);
if( FullFileName == wxEmptyString )
if( fileName == wxEmptyString )
return;
/* Install a dialog frame to choose the mapping
......@@ -111,24 +115,15 @@ void GERBVIEW_FRAME::ExportDataInPcbnewFormat( wxCommandEvent& event )
if( ok != wxID_OK )
return;
if( wxFileExists( FullFileName ) )
if( wxFileExists( fileName ) )
{
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 );
return;
}
GBR_TO_PCB_EXPORTER gbr_exporter( this, fileName );
GBR_TO_PCB_EXPORTER gbr_exporter( this, file );
gbr_exporter.ExportPcb( dlg->GetLayersLookUpTable() );
fclose( file );
}
......@@ -162,54 +157,6 @@ void GBR_TO_PCB_EXPORTER::cleanBoard()
}
bool GBR_TO_PCB_EXPORTER::WriteSetup( )
{
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
EDA_RECT bbbox = m_pcb->ComputeBoundingBox();
fprintf( m_file, "Di %d %d %d %d\n",
bbbox.GetX(), bbbox.GetY(),
bbbox.GetRight(),
bbbox.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 )
{
BOARD* gerberPcb = m_gerbview_frame->GetBoard();
......@@ -235,22 +182,21 @@ bool GBR_TO_PCB_EXPORTER::ExportPcb( int* LayerLookUpTable )
cleanBoard();
m_pcb->SetCopperLayerCount( LayerLookUpTable[32] );
// Switch the locale to standard C (needed to print floating point numbers)
SetLocaleTo_C_standard();
// write PCB header
fprintf( m_file, "PCBNEW-BOARD Version %d date %s\n\n", LEGACY_BOARD_FILE_VERSION,
TO_UTF8( DateAndTime() ) );
WriteGeneralDescrPcb( );
WriteSetup( );
// write items on file
m_pcb->Save( m_file );
try
{
PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::LEGACY ) );
pi->Save( m_file_name, m_pcb );
}
catch( IO_ERROR ioe )
{
DisplayError( m_gerbview_frame, ioe.errorText );
return false;
}
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, PCB_LINE_T );
......
......@@ -296,13 +296,6 @@ public:
*/
bool SetZoom( double coeff );
/**
* Function SetZoomList
* sets the list of zoom factors.
* @param aZoomList An array of zoom factors in ascending order, zero terminated
*/
void SetZoomList( const wxArrayDouble& aZoomList );
bool SetNextZoom();
bool SetPreviousZoom();
bool SetFirstZoom();
......
......@@ -98,26 +98,6 @@ public:
BOARD_ITEM* Back() const { return (BOARD_ITEM*) Pback; }
BOARD_ITEM* GetParent() const { return (BOARD_ITEM*) m_Parent; }
#if 0
// DICK: there is no value in having a polymorphic {Get,Set}Position(). We never
// call GetPosition() using a generic pointer, and the virtual is slower and
// can never be inlined.
/**
* Function GetPosition
* returns the position of this object.
* @return const wxPoint - The position of this object
*/
virtual const wxPoint GetPosition() const = 0;
/**
* Function SetPosition
* sets the position of this object.
* @param aPos is the new position of this object
*/
virtual void SetPosition( const wxPoint& aPos ) = 0;
#endif
/**
* Function GetLayer
* returns the layer this item is on.
......@@ -173,7 +153,6 @@ public:
return false; // only MODULEs can be locked at this time.
}
/**
* Function UnLink
* detaches this object from its owner. This base class implementation
......@@ -191,21 +170,12 @@ public:
delete this;
}
/**
* Function ShowShape
* converts the enum STROKE_T integer value to a wxString.
*/
static wxString ShowShape( STROKE_T aShape );
/**
* Function Save
* writes the data structures for this object out to a FILE in "*.brd" format.
* @param aFile The FILE to write to.
* @return bool - true if success writing else false.
*/
virtual bool Save( FILE* aFile ) const = 0;
// Some geometric transforms, that must be rewritten for derived classes
/**
* Function Move
......
......@@ -172,72 +172,4 @@ public:
}
};
/**
* Template DIALOG_SHIM
* is a way to have a common way of handling KiCad dialog windows:
* <ul>
* <li>class specific: static s_LastPos and static s_LastSize for retentative
* dialog window positioning, per class.
* <li> invocation of SetFocus() to allow ESC key to work on Linux.
* <li> future others...
* </ul>
* by wedging in a class (a SHIM) between the wxFormbuilder coded base class and
* our derived dialog classes. Use it via the macro named DIALOG_EXTEND_WITH_SHIM
* and be sure to code your constructor to invoke *_SHIM() base class constructor,
* not the one from wxFormbuilder.
* @author Dick Hollenbeck
*/
template <class T>
class DIALOG_SHIM : public T
{
public:
DIALOG_SHIM( wxFrame* aParent ) :
T( aParent )
{
wxDialog::SetFocus();
}
// overload wxDialog::Show
bool Show( bool show )
{
bool ret;
if( show )
{
ret = wxDialog::Show( show );
if( s_LastPos.x != -1 )
wxDialog::SetSize( s_LastPos.x, s_LastPos.y, s_LastSize.x, s_LastSize.y, 0 );
}
else
{
// Save the dialog's position before hiding
s_LastPos = wxDialog::GetPosition();
s_LastSize = wxDialog::GetSize();
ret = wxDialog::Show( show );
}
return ret;
}
private:
static wxPoint s_LastPos;
static wxSize s_LastSize;
};
template<class T>
wxPoint DIALOG_SHIM<T>::s_LastPos( -1, -1 );
template<class T>
wxSize DIALOG_SHIM<T>::s_LastSize( 0, 0 );
/**
* Macro DIALOG_EXTEND_WITH_SHIM
* instantiates the template DIALOG_SHIM<> and thereby declares a shim class.
* @author Dick Hollenbeck
*/
#define DIALOG_EXTEND_WITH_SHIM( DERRIVED, BASE ) \
typedef DIALOG_SHIM<BASE> BASE##_SHIM; \
class DERRIVED : public BASE##_SHIM
#endif // DIALOG_HELPERS_H_
......@@ -32,6 +32,7 @@ public:
}
};
class FOOTPRINT_LIST
{
public:
......
......@@ -3,13 +3,8 @@
* @brief Classes and definitions used in Pcbnew.
*/
#ifndef PCBSTRUCT_H
#define PCBSTRUCT_H
// Definitions relatives aux libraries
#define FOOTPRINT_LIBRARY_HEADER "PCBNEW-LibModule-V1"
#define FOOTPRINT_LIBRARY_HEADER_CNT 18
#ifndef PCBSTRUCT_H_
#define PCBSTRUCT_H_
/// Values for m_DisplayViaMode member:
......@@ -83,4 +78,4 @@ public:
DISPLAY_OPTIONS();
};
#endif // PCBSTRUCT_H
#endif // PCBSTRUCT_H_
......@@ -373,20 +373,45 @@ public:
// loading footprints
/**
* Function GetModuleLibrary
* Function loadFootprintFromLibrary
* loads @a aFootprintName from @a aLibraryPath.
* If found add the module is also added to the BOARD, just for good measure.
*
* Read active libraries or one library to find and load a given module
* If found the module is linked to the tail of linked list of modules
* @param aLibraryFullFilename - the full filename of the library to read. If empty,
* all active libraries are read
* @param aModuleName = module name to load
* @param aDisplayMessageError = true to display an error message if any.
*
* @param aFootprintName is the footprint to load
*
* @param aDisplayError = true to display an error message if any.
*
* @return MODULE* - new module, or NULL
*/
MODULE* loadFootprintFromLibrary( const wxString& aLibraryPath,
const wxString& aFootprintName, bool aDisplayError );
MODULE* loadFootprintFromLibraries( const wxString& aFootprintName,
bool aDisplayError );
/**
* Function GetModuleLibrary
* scans active libraries to find and load @a aFootprintName.
* If found add the module is also added to the BOARD, just for good measure.
*
* @param aFootprintName is the footprint to load
*
* @param aDisplayError = true to display an error message if any.
*
* @return a pointer to the new module, or NULL
*
*/
MODULE* GetModuleLibrary( const wxString& aLibraryFullFilename,
const wxString& aModuleName,
bool aDisplayMessageError );
MODULE* GetModuleLibrary( const wxString& aLibraryPath, const wxString& aFootprintName,
bool aDisplayError )
{
if( !aLibraryPath )
return loadFootprintFromLibraries( aFootprintName, aDisplayError );
else
return loadFootprintFromLibrary( aLibraryPath, aFootprintName, aDisplayError );
}
/**
* Function Select_1_Module_From_List
......@@ -409,7 +434,8 @@ public:
/**
* Function Load_Module_From_Library
* Open a dialog to select a footprint, and load in in current board
* opens a dialog to select a footprint, and loads it into current board.
*
* @param aLibrary = the library name to use, or empty string to search
* in all loaded libraries
* @param aUseFootprintViewer = true to show the option
......
......@@ -96,7 +96,7 @@ set(PCBNEW_SRCS
block.cpp
block_module_editor.cpp
build_BOM_from_board.cpp
class_footprint_library.cpp
# class_footprint_library.cpp
class_pcb_layer_widget.cpp
clean.cpp
connect.cpp
......@@ -136,7 +136,6 @@ set(PCBNEW_SRCS
hotkeys_board_editor.cpp
hotkeys_module_editor.cpp
initpcb.cpp
ioascii.cpp
layer_widget.cpp
librairi.cpp
loadcmp.cpp
......
......@@ -848,7 +848,7 @@ public:
* ( using the default netclass value or a preset value )
* the default netclass is always in m_TrackWidthList[0]
*/
int GetCurrentTrackWidth()
int GetCurrentTrackWidth() const
{
return m_TrackWidthList[m_TrackWidthSelector];
}
......@@ -892,8 +892,6 @@ public:
/***************************************************************************/
bool Save( FILE* aFile ) const;
wxString GetClass() const
{
return wxT( "BOARD" );
......
......@@ -135,14 +135,8 @@ public:
*/
}
bool Save( FILE* aFile ) const
{
return true;
}
//-----</ satisfy some virtual functions >-----------------------------
/**
* Function GetCount
* returns the number of BOARD_ITEMs.
......
......@@ -88,10 +88,6 @@ public:
*/
void AdjustDimensionDetails( bool aDoNotChangeText = false );
bool ReadDimensionDescr( LINE_READER* aReader );
bool Save( FILE* aFile ) const;
void SetText( const wxString& NewText );
const wxString GetText() const;
......
......@@ -152,10 +152,6 @@ public:
m_PolyPoints = aPoints;
}
bool Save( FILE* aFile ) const;
bool ReadDrawSegmentDescr( LINE_READER* aReader );
void Copy( DRAWSEGMENT* source );
void Draw( EDA_DRAW_PANEL* panel, wxDC* DC,
......
......@@ -64,10 +64,6 @@ public:
void SetEnd0( const wxPoint& aPoint ) { m_End0 = aPoint; }
const wxPoint& GetEnd0() const { return m_End0; }
bool Save( FILE* aFile ) const;
int ReadDescr( LINE_READER* aReader );
void SetDrawCoord();
/* drawing functions */
......
......@@ -11,15 +11,16 @@ class FOOTPRINT_LIBRARY
public:
wxArrayString m_List; // list of footprints, used to read/write INDEX section
wxString m_LibraryName; // the full library name
int m_LineNum; // the line count
private:
FILTER_READER * m_reader; // FILTER_READER to read file. If NULL, use m_file
FILE * m_file; // footprint file to read/write.
int m_LineNum; // the line count
public:
/**
* ctor
* Constructor FOOTPRINT_LIBRARY
* @param aFile = a FILE * pointer used for write operations,
* and read operations when aReader = NULL
* @param aReader = a FILTER_READER pointer used for read operations
......@@ -27,7 +28,11 @@ public:
*/
FOOTPRINT_LIBRARY( FILE * aFile, FILTER_READER * aReader = NULL );
~FOOTPRINT_LIBRARY() { }
FOOTPRINT_LIBRARY() :
m_reader( 0 ),
m_file( 0 ),
m_LineNum( 0 )
{}
/**
* function IsLibrary
......
......@@ -70,13 +70,6 @@ public:
void DisplayInfo( EDA_DRAW_FRAME* frame );
bool Save( FILE* aFile ) const
{
// not implemented, this is here to satisfy BOARD_ITEM::Save()
// "pure" virtual-ness
return true;
}
wxString GetSelectMenuText() const;
BITMAP_DEF GetMenuImage() const { return drc_xpm; }
......
......@@ -86,10 +86,6 @@ public:
void Flip( const wxPoint& aCentre );
bool Save( FILE* aFile ) const;
bool ReadMirePcbDescr( LINE_READER* aReader );
void Copy( PCB_TARGET* source );
void Draw( EDA_DRAW_PANEL* panel, wxDC* DC, int aDrawMode,
......
......@@ -111,6 +111,7 @@ MODULE::MODULE( const MODULE& aModule ) :
// Copy reference and value.
m_Reference = new TEXTE_MODULE( *aModule.m_Reference );
m_Reference->SetParent( this );
m_Value = new TEXTE_MODULE( *aModule.m_Value );
m_Value->SetParent( this );
......
......@@ -108,16 +108,6 @@ public:
wxString m_Doc; // Module Description (info for users)
wxString m_KeyWord; // Keywords to select the module in lib
// Local tolerances. When zero, this means the corresponding netclass value
// is used. Usually theses local tolerances zero, in deference to the
// corresponding netclass values.
int m_LocalClearance;
int m_LocalSolderMaskMargin; ///< Solder mask margin
int m_LocalSolderPasteMargin; ///< Solder paste margin
///< absolute value
double m_LocalSolderPasteMarginRatio; ///< Solder mask margin ratio
///< value of pad size
// The final margin is the sum of these 2 values
ZoneConnection m_ZoneConnection;
......@@ -236,14 +226,6 @@ public:
void SetLastEditTime( long aTime ) { m_LastEdit_Time = aTime; }
long GetLastEditTime() const { return m_LastEdit_Time; }
/* Reading and writing data on files */
bool Save( FILE* aFile ) const;
int Write_3D_Descr( FILE* File ) const;
int ReadDescr( LINE_READER* aReader );
/**
* Function Read_GPCB_Descr
* reads a footprint description in GPCB format (newlib version)
......@@ -332,6 +314,12 @@ public:
*/
D_PAD* GetPad( const wxPoint& aPosition, int aLayerMask = ALL_LAYERS );
/**
* GetPadCount
* returns the number of pads.
*/
unsigned GetPadCount() const { return m_Pads.GetCount() ; }
SEARCH_RESULT Visit( INSPECTOR* inspector, const void* testData,
const KICAD_T scanTypes[] );
......@@ -352,7 +340,18 @@ public:
#if defined(DEBUG)
void Show( int nestLevel, std::ostream& os ) const; // overload
#endif
};
private:
// Local tolerances. When zero, this means the corresponding netclass value
// is used. Usually theses local tolerances zero, in deference to the
// corresponding netclass values.
int m_LocalClearance;
int m_LocalSolderMaskMargin; ///< Solder mask margin
int m_LocalSolderPasteMargin; ///< Solder paste margin
///< absolute value
double m_LocalSolderPasteMarginRatio; ///< Solder mask margin ratio
///< value of pad size
};
#endif // MODULE_H_
......@@ -198,22 +198,6 @@ public:
*/
void SetParams( const NETCLASS* defaults = NULL );
/**
* Function Save
* writes the data structures for this object out to a FILE in "*.brd" format.
* @param aFile The FILE to write to.
* @return bool - true if success writing else false.
*/
bool Save( FILE* aFile ) const;
/**
* Function ReadDescr
* reads the data structures for this object from a LINE_READER in "*.brd" format.
* @param aReader is a pointer to a LINE_READER to read from.
* @return bool - true if success reading else false.
*/
bool ReadDescr( LINE_READER* aReader );
/**
* Function Format
* outputs the net class to \a aFormatter in s-expression form.
......
......@@ -342,18 +342,6 @@ public:
#endif
/* Reading and writing data on files */
int ReadDescr( LINE_READER* aReader );
/**
* Function Save
* writes the data structures for this object out to a FILE in "*.brd"
* format.
* @param aFile The FILE to write to.
* @return bool - true if success writing else false.
*/
bool Save( FILE* aFile ) const;
/**
* Function Draw
* @todo we actually could show a NET, simply show all the tracks and
......
......@@ -332,9 +332,10 @@ int D_PAD::GetClearance( BOARD_CONNECTED_ITEM* aItem ) const
int clearance = m_LocalClearance;
if( clearance == 0 )
{ // If local clearance is 0, use the parent footprint clearance value
if( GetParent() && ( (MODULE*) GetParent() )->m_LocalClearance )
clearance = ( (MODULE*) GetParent() )->m_LocalClearance;
{
// If local clearance is 0, use the parent footprint clearance value
if( GetParent() && GetParent()->GetLocalClearance() )
clearance = GetParent()->GetLocalClearance();
}
if( clearance == 0 ) // If the parent footprint clearance value = 0, use NETCLASS value
......@@ -367,14 +368,14 @@ int D_PAD::GetClearance( BOARD_CONNECTED_ITEM* aItem ) const
int D_PAD::GetSolderMaskMargin()
{
int margin = m_LocalSolderMaskMargin;
MODULE* module = (MODULE*) GetParent();
MODULE* module = GetParent();
if( module )
{
if( margin == 0 )
{
if( module->m_LocalSolderMaskMargin )
margin = module->m_LocalSolderMaskMargin;
if( module->GetLocalSolderMaskMargin() )
margin = module->GetLocalSolderMaskMargin();
}
if( margin == 0 )
......@@ -410,12 +411,12 @@ wxSize D_PAD::GetSolderPasteMargin()
{
int margin = m_LocalSolderPasteMargin;
double mratio = m_LocalSolderPasteMarginRatio;
MODULE * module = (MODULE*) GetParent();
MODULE* module = GetParent();
if( module )
{
if( margin == 0 )
margin = module->m_LocalSolderPasteMargin;
margin = module->GetLocalSolderPasteMargin();
BOARD * brd = GetBoard();
......@@ -423,7 +424,7 @@ wxSize D_PAD::GetSolderPasteMargin()
margin = brd->GetDesignSettings().m_SolderPasteMargin;
if( mratio == 0.0 )
mratio = module->m_LocalSolderPasteMarginRatio;
mratio = module->GetLocalSolderPasteMarginRatio();
if( mratio == 0.0 )
{
......
......@@ -267,12 +267,6 @@ public:
void SetThermalGap( int aGap ) { m_ThermalGap = aGap; }
int GetThermalGap() const;
/* Reading and writing data on files */
int ReadDescr( LINE_READER* aReader );
bool Save( FILE* aFile ) const;
/* drawing functions */
void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
int aDrawMode, const wxPoint& aOffset = ZeroOffset );
......
......@@ -73,11 +73,6 @@ public:
void Draw( EDA_DRAW_PANEL* panel, wxDC* DC, int aDrawMode,
const wxPoint& offset = ZeroOffset );
// File Operations:
int ReadTextePcbDescr( LINE_READER* aReader );
bool Save( FILE* aFile ) const;
void DisplayInfo( EDA_DRAW_FRAME* frame );
bool HitTest( const wxPoint& aPosition )
......
......@@ -116,16 +116,6 @@ public:
void SetLocalCoord(); // Set relative coordinates.
bool Save( FILE* aFile ) const;
/**
* Function ReadDescr
* Read description from a given line in "*.brd" format.
* @param aReader is a pointer to a LINE_READER to read from.
* @return int - > 0 if success reading else 0.
*/
int ReadDescr( LINE_READER* aReader );
/* drawing functions */
void Draw( EDA_DRAW_PANEL* panel,
wxDC* DC,
......
......@@ -125,8 +125,6 @@ public:
EDA_RECT GetBoundingBox() const;
bool Save( FILE* aFile ) const;
/**
* Function GetBestInsertPoint
* searches the "best" insertion point within the track linked list.
......
......@@ -135,16 +135,6 @@ public:
~ZONE_CONTAINER();
bool Save( FILE* aFile ) const;
/**
* Function ReadDescr
* reads the data structures for this object from a LINE_READER in "*.brd" format.
* @param aReader is a pointer to a LINE_READER to read from.
* @return int - 1 if success, 0 if not.
*/
int ReadDescr( LINE_READER* aReader );
/**
* Function GetPosition
* @return a wxPoint, position of the first point of the outline
......
......@@ -30,18 +30,16 @@
#endif
/* Default Pcbnew zoom values.
* Limited to 19 values to keep a decent size to menus
* 15 it better but does not allow a sufficient number of values
* roughtly a 1.5 progression.
* The last 2 values is handy when somebody uses a library import of a module
* (or foreign data) which has a bad coordinate
* Also useful in GerbView for this reason.
* Zoom 5 and 10 can create artefacts when drawing (integer overflow in low level graphic
* functions )
*/
/**
Default Pcbnew zoom values.
Limited to 19 values to keep a decent size to menus.
Roughly a 1.5 progression.
The last 2 values are handy when somebody uses a library import of a module
(or foreign data) which has a bad coordinate.
Also useful in GerbView for this reason.
Zoom 5 and 10 can create artefacts when drawing (integer overflow in low level graphic
functions )
*/
static const double pcbZoomList[] =
{
ZOOM_FACTOR( 0.5 ),
......
......@@ -110,8 +110,8 @@ void DIALOG_MODULE_BOARD_EDITOR::InitBoardProperties()
m_SolderMaskMarginUnits->SetLabel( GetUnitsLabel( g_UserUnit ) );
m_SolderPasteMarginUnits->SetLabel( GetUnitsLabel( g_UserUnit ) );
PutValueInLocalUnits( *m_NetClearanceValueCtrl, m_CurrentModule->m_LocalClearance );
PutValueInLocalUnits( *m_SolderMaskMarginCtrl, m_CurrentModule->m_LocalSolderMaskMargin );
PutValueInLocalUnits( *m_NetClearanceValueCtrl, m_CurrentModule->GetLocalClearance() );
PutValueInLocalUnits( *m_SolderMaskMarginCtrl, m_CurrentModule->GetLocalSolderMaskMargin() );
// These 2 parameters are usually < 0, so prepare entering a negative
// value, if current is 0
......
......@@ -149,8 +149,9 @@ void DIALOG_MODULE_MODULE_EDITOR::InitModeditProperties()
m_SolderPasteMarginUnits->SetLabel( GetUnitsLabel( g_UserUnit ) );
wxString msg;
PutValueInLocalUnits( *m_NetClearanceValueCtrl, m_CurrentModule->m_LocalClearance );
PutValueInLocalUnits( *m_SolderMaskMarginCtrl, m_CurrentModule->m_LocalSolderMaskMargin );
PutValueInLocalUnits( *m_NetClearanceValueCtrl, m_CurrentModule->GetLocalClearance() );
PutValueInLocalUnits( *m_SolderMaskMarginCtrl, m_CurrentModule->GetLocalSolderMaskMargin() );
// These 2 parameters are usually < 0, so prepare entering a negative value, if current is 0
PutValueInLocalUnits( *m_SolderPasteMarginCtrl, m_CurrentModule->GetLocalSolderPasteMargin() );
......
......@@ -202,70 +202,6 @@ the changes?" ) ) )
GetScreen()->SetFileName( fileName.GetFullPath() );
#if !defined(USE_NEW_PCBNEW_LOAD)
// Start read PCB file
FILE* source = wxFopen( GetScreen()->GetFileName(), wxT( "rt" ) );
if( source == NULL )
{
msg.Printf( _( "File <%s> not found" ), GetChars( GetScreen()->GetFileName() ) );
DisplayError( this, msg );
return false;
}
FILE_LINE_READER fileReader( source, GetScreen()->GetFileName() );
FILTER_READER reader( fileReader );
// Read header and TEST if it is a PCB file format
reader.ReadLine();
if( strncmp( reader.Line(), "PCBNEW-BOARD", 12 ) != 0 )
{
DisplayError( this, wxT( "Unknown file type" ) );
return false;
}
int ver;
sscanf( reader.Line() , "PCBNEW-BOARD Version %d date", &ver );
if ( ver > LEGACY_BOARD_FILE_VERSION )
{
DisplayInfoMessage( this, _( "This file was created by a more recent \
version of Pcbnew and may not load correctly. Please consider updating!" ) );
}
else if ( ver < LEGACY_BOARD_FILE_VERSION )
{
DisplayInfoMessage( this, _( "This file was created by an older \
version of Pcbnew. It will be stored in the new file format when you save \
this file again." ) );
}
// Reload the corresponding configuration file:
wxSetWorkingDirectory( wxPathOnly( GetScreen()->GetFileName() ) );
if( aAppend )
{
ReadPcbFile( &reader, true );
}
else
{
// Update the option toolbar
m_DisplayPcbTrackFill = DisplayOpt.DisplayPcbTrackFill;
m_DisplayModText = DisplayOpt.DisplayModText;
m_DisplayModEdge = DisplayOpt.DisplayModEdge;
m_DisplayPadFill = DisplayOpt.DisplayPadFill;
m_DisplayViaFill = DisplayOpt.DisplayViaFill;
// load project settings before BOARD, in case BOARD file has overrides.
LoadProjectSettings( GetScreen()->GetFileName() );
ReadPcbFile( &reader, false );
}
#else
if( !aAppend )
{
// Update the option toolbar
......@@ -321,8 +257,6 @@ this file again." ) );
BestZoom();
}
#endif
GetScreen()->ClrModify();
// If append option: change the initial board name to <oldname>-append.brd
......@@ -456,10 +390,8 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool aCreateBackupF
pcbFileName = GetScreen()->GetFileName();
#if defined( USE_NEW_PCBNEW_LOAD ) || defined( USE_NEW_PCBNEW_SAVE )
if( pcbFileName.GetExt().IsEmpty() )
pcbFileName.SetExt( IO_MGR::GetFileExtension( (IO_MGR::PCB_FILE_T) wildcardIndex ) );
#endif
if( !IsWritable( pcbFileName ) )
return false;
......@@ -493,8 +425,6 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool aCreateBackupF
}
}
#if defined(USE_NEW_PCBNEW_SAVE)
GetBoard()->m_Status_Pcb &= ~CONNEXION_OK;
GetBoard()->SynchronizeNetsAndNetClasses();
......@@ -535,29 +465,6 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool aCreateBackupF
UpdateTitle();
}
#else
// Create the file
FILE* dest;
dest = wxFopen( pcbFileName.GetFullPath(), wxT( "wt" ) );
if( dest == 0 )
{
msg = _( "Unable to create " ) + pcbFileName.GetFullPath();
DisplayError( this, msg );
saveok = false;
}
if( dest )
{
GetScreen()->SetFileName( pcbFileName.GetFullPath() );
UpdateTitle();
SavePcbFormatAscii( dest );
fclose( dest );
}
#endif
// Display the file names:
m_messagePanel->EraseMsgBox();
......
......@@ -42,6 +42,7 @@
#include <class_board.h>
#include <class_module.h>
#include <class_drawsegment.h>
#include <legacy_plugin.h>
#include <pcbnew.h>
#include <pcb_plot_params.h>
......@@ -532,7 +533,6 @@ void PCB_EDIT_FRAME::GenFootprintsReport( wxCommandEvent& event )
*/
bool PCB_EDIT_FRAME::DoGenFootprintsReport( const wxString& aFullFilename, bool aUnitsMM )
{
MODULE* Module;
D_PAD* pad;
char line[1024];
wxString fnFront, msg;
......@@ -550,9 +550,7 @@ bool PCB_EDIT_FRAME::DoGenFootprintsReport( const wxString& aFullFilename, bool
double conv_unit = aUnitsMM ? conv_unit_mm : conv_unit_inch;
const char *unit_text = aUnitsMM ? unit_text_mm : unit_text_inch;
// Switch the locale to standard C (needed to print floating point
// numbers like 1.3)
SetLocaleTo_C_standard();
LOCALE_IO toggle;
// Generate header file comments.)
sprintf( line, "## Module report - date %s\n", TO_UTF8( DateAndTime() ) );
......@@ -584,9 +582,15 @@ bool PCB_EDIT_FRAME::DoGenFootprintsReport( const wxString& aFullFilename, bool
fputs( "$EndBOARD\n\n", rptfile );
Module = (MODULE*) GetBoard()->m_Modules;
try
{
PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::LEGACY ) );
LEGACY_PLUGIN* legacy = (LEGACY_PLUGIN*) (PLUGIN*) pi;
legacy->SetFilePtr( rptfile );
for( ; Module != NULL; Module = Module->Next() )
for( MODULE* Module = GetBoard()->m_Modules; Module; Module = Module->Next() )
{
sprintf( line, "$MODULE %s\n", EscapedUTF8( Module->m_Reference->m_Text ).c_str() );
fputs( line, rptfile );
......@@ -632,7 +636,7 @@ bool PCB_EDIT_FRAME::DoGenFootprintsReport( const wxString& aFullFilename, bool
fputs( line, rptfile );
Module->Write_3D_Descr( rptfile );
legacy->SaveModule3D( Module );
for( pad = Module->m_Pads; pad != NULL; pad = pad->Next() )
{
......@@ -682,6 +686,11 @@ bool PCB_EDIT_FRAME::DoGenFootprintsReport( const wxString& aFullFilename, bool
fprintf( rptfile, "$EndMODULE %s\n\n",
TO_UTF8(Module->m_Reference->m_Text ) );
}
}
catch( IO_ERROR ioe )
{
DisplayError( NULL, ioe.errorText );
}
// Write board Edges
EDA_ITEM* PtStruct;
......@@ -700,7 +709,6 @@ bool PCB_EDIT_FRAME::DoGenFootprintsReport( const wxString& aFullFilename, bool
// Generate EOF.
fputs( "$EndDESCRIPTION\n", rptfile );
fclose( rptfile );
SetLocaleTo_Default( ); // revert to the current locale
return true;
}
......
......@@ -28,6 +28,10 @@
#include <kicad_plugin.h>
#define FMT_UNIMPLEMENTED _( "Plugin '%s' does not implement the '%s' function." )
#define FMT_NOTFOUND _( "Plugin type '%s' is not found." )
// Some day plugins might be in separate DLL/DSOs, simply because of numbers of them
// and code size. Until then, use the simplest method:
......@@ -40,8 +44,8 @@
// plugins coexisting.
// static LEGACY_PLUGIN kicad_plugin; // a secret
//static EAGLE_PLUGIN eagle_plugin;
// static LEGACY_PLUGIN kicad_plugin;
// static EAGLE_PLUGIN eagle_plugin;
PLUGIN* IO_MGR::PluginFind( PCB_FILE_T aFileType )
{
......@@ -118,7 +122,7 @@ BOARD* IO_MGR::Load( PCB_FILE_T aFileType, const wxString& aFileName,
return pi->Load( aFileName, aAppendToMe, aProperties ); // virtual
}
THROW_IO_ERROR( wxString::Format( _( "Plugin type '%s' is not found." ), ShowType( aFileType ).GetData() ) );
THROW_IO_ERROR( wxString::Format( FMT_NOTFOUND, ShowType( aFileType ).GetData() ) );
}
......@@ -133,25 +137,70 @@ void IO_MGR::Save( PCB_FILE_T aFileType, const wxString& aFileName, BOARD* aBoar
return;
}
THROW_IO_ERROR( wxString::Format( _( "Plugin type '%s' is not found." ), ShowType( aFileType ).GetData() ) );
THROW_IO_ERROR( wxString::Format( FMT_NOTFOUND, ShowType( aFileType ).GetData() ) );
}
BOARD* PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe, PROPERTIES* aProperties )
{
// not pure virtual so that plugins only have to implement subset of the PLUGIN interface,
// e.g. Load() or Save() but not both.
THROW_IO_ERROR( wxString::Format(
_( "Plugin %s does not implement the BOARD Load() function." ), PluginName().GetData() ) );
// not pure virtual so that plugins only have to implement subset of the PLUGIN interface.
THROW_IO_ERROR( wxString::Format( FMT_UNIMPLEMENTED, PluginName().GetData(), __FUNCTION__ ) );
}
void PLUGIN::Save( const wxString& aFileName, BOARD* aBoard, PROPERTIES* aProperties )
{
// not pure virtual so that plugins only have to implement subset of the PLUGIN interface,
// e.g. Load() or Save() but not both.
// not pure virtual so that plugins only have to implement subset of the PLUGIN interface.
THROW_IO_ERROR( wxString::Format( FMT_UNIMPLEMENTED, PluginName().GetData(), __FUNCTION__ ) );
}
wxArrayString PLUGIN::FootprintEnumerate( const wxString& aLibraryPath, PROPERTIES* aProperties )
{
// not pure virtual so that plugins only have to implement subset of the PLUGIN interface.
THROW_IO_ERROR( wxString::Format( FMT_UNIMPLEMENTED, PluginName().GetData() , __FUNCTION__ ) );
}
MODULE* PLUGIN::FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName,
PROPERTIES* aProperties )
{
// not pure virtual so that plugins only have to implement subset of the PLUGIN interface.
THROW_IO_ERROR( wxString::Format( FMT_UNIMPLEMENTED, PluginName().GetData() , __FUNCTION__ ) );
}
THROW_IO_ERROR( wxString::Format(
_( "Plugin %s does not implement the BOARD Save() function." ), PluginName().GetData() ) );
void PLUGIN::FootprintSave( const wxString& aLibraryPath, const MODULE* aFootprint, PROPERTIES* aProperties )
{
// not pure virtual so that plugins only have to implement subset of the PLUGIN interface.
THROW_IO_ERROR( wxString::Format( FMT_UNIMPLEMENTED, PluginName().GetData() , __FUNCTION__ ) );
}
void PLUGIN::FootprintDelete( const wxString& aLibraryPath, const wxString& aFootprintName )
{
// not pure virtual so that plugins only have to implement subset of the PLUGIN interface.
THROW_IO_ERROR( wxString::Format( FMT_UNIMPLEMENTED, PluginName().GetData() , __FUNCTION__ ) );
}
void PLUGIN::FootprintLibCreate( const wxString& aLibraryPath, PROPERTIES* aProperties )
{
// not pure virtual so that plugins only have to implement subset of the PLUGIN interface.
THROW_IO_ERROR( wxString::Format( FMT_UNIMPLEMENTED, PluginName().GetData() , __FUNCTION__ ) );
}
void PLUGIN::FootprintLibDelete( const wxString& aLibraryPath, PROPERTIES* aProperties )
{
// not pure virtual so that plugins only have to implement subset of the PLUGIN interface.
THROW_IO_ERROR( wxString::Format( FMT_UNIMPLEMENTED, PluginName().GetData() , __FUNCTION__ ) );
}
bool PLUGIN::IsFootprintLibWritable( const wxString& aLibraryPath )
{
// not pure virtual so that plugins only have to implement subset of the PLUGIN interface.
THROW_IO_ERROR( wxString::Format( FMT_UNIMPLEMENTED, PluginName().GetData() , __FUNCTION__ ) );
}
......@@ -30,6 +30,7 @@
class BOARD;
class PLUGIN;
class MODULE;
/**
......@@ -152,7 +153,9 @@ public:
* is a base class that BOARD loading and saving plugins should derive from.
* Implementations can provide either Load() or Save() functions, or both.
* PLUGINs throw exceptions, so it is best that you wrap your calls to these
* functions in a try catch block.
* functions in a try catch block. Plugins throw exceptions because it is illegal
* for them to have any user interface calls in them whatsoever, i.e. no windowing
* or screen printing at all.
*
* <pre>
* try
......@@ -187,9 +190,9 @@ public:
/**
* Function Load
* loads a board file, or a portion of one, from some input file format
* that this PLUGIN implementation knows about. This may be used to load an
* entire new BOARD, or to augment an existing one if \a aAppendToMe is not NULL.
* loads information from some input file format that this PLUGIN implementation
* knows about, into either a new BOARD or an existing one. This may be used to load an
* entire new BOARD, or to augment an existing one if @a aAppendToMe is not NULL.
*
* @param aFileName is the name of the file to use as input and may be foreign in
* nature or native in nature.
......@@ -216,7 +219,7 @@ public:
/**
* Function Save
* will write a full aBoard to a storage file in a format that this
* will write @a aBoard to a storage file in a format that this
* PLUGIN implementation knows about, or it can be used to write a portion of
* aBoard to a special kind of export file.
*
......@@ -237,13 +240,138 @@ public:
virtual void Save( const wxString& aFileName, BOARD* aBoard,
PROPERTIES* aProperties = NULL );
/**
* Function FootprintEnumerate
* returns a list of footprint names contained within the library at @a aLibraryPath.
*
* @param aLibraryPath is a locator for the "library", usually a directory
* or file containing several footprints.
*
* @param aProperties is an associative array that can be used to tell the
* plugin how to access the library.
* The caller continues to own this object (plugin may not delete it), and
* plugins should expect it to be optionally NULL.
*
* @return wxArrayString - is the array of available footprint names inside
* a library
*
* @throw IO_ERROR if the library cannot be found, or footprint cannot be loaded.
*/
virtual wxArrayString FootprintEnumerate( const wxString& aLibraryPath, PROPERTIES* aProperties = NULL);
/**
* Function FootprintLoad
* loads a MODULE having @a aFootprintName from the @a aLibraryPath containing
* a library format that this PLUGIN knows about.
*
* @param aLibraryPath is a locator for the "library", usually a directory
* or file containing several footprints.
*
* @param aFootprintName is the name of the footprint to load.
*
* @param aProperties is an associative array that can be used to tell the
* saver how to save the file, because it can take any number of
* additional named tuning arguments that the plugin is known to support.
* The caller continues to own this object (plugin may not delete it), and
* plugins should expect it to be optionally NULL.
*
* @return MODULE* - if found caller owns it, else NULL if not found.
*
* @throw IO_ERROR if the library cannot be found or read. No exception
* is thrown in the case where aFootprintName cannot be found.
*/
virtual MODULE* FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName,
PROPERTIES* aProperties = NULL );
/**
* Function FootprintSave
* will write @a aModule to an existing library located at @a aLibraryPath.
* If a footprint by the same name already exists, it is replaced.
*
* @param aLibraryPath is a locator for the "library", usually a directory
* or file containing several footprints. This is where the footprint is
* to be stored.
*
* @param aFootprint is what to store in the library.
* The caller continues to own the footprint.
*
* @param aProperties is an associative array that can be used to tell the
* saver how to save the file, because it can take any number of
* additional named tuning arguments that the plugin is known to support.
* The caller continues to own this object (plugin may not delete it), and
* plugins should expect it to be optionally NULL.
*
* @throw IO_ERROR if there is a problem saving.
*/
virtual void FootprintSave( const wxString& aLibraryPath, const MODULE* aFootprint,
PROPERTIES* aProperties = NULL );
/**
* Function FootprintDelete
* deletes the @a aFootprintName from the library at @a aLibraryPath.
*
* @param aLibraryPath is a locator for the "library", usually a directory
* or file containing several footprints.
*
* @param aFootprintName is the name of a footprint to delete from the specificed library.
*
* @throw IO_ERROR if there is a problem finding the footprint or the library, or deleting it.
*/
virtual void FootprintDelete( const wxString& aLibraryPath, const wxString& aFootprintName );
/**
* Function FootprintLibCreate
* creates a new empty footprint library at @a aLibraryPath empty. It is an
* error to attempt to create an existing library or to attempt to create
* on a "read only" location.
*
* @param aLibraryPath is a locator for the "library", usually a directory
* or file which will contain footprints.
*
* @param aProperties is an associative array that can be used to tell the
* library create function anything special, because it can take any number of
* additional named tuning arguments that the plugin is known to support.
* The caller continues to own this object (plugin may not delete it), and
* plugins should expect it to be optionally NULL.
*
* @throw IO_ERROR if there is a problem finding the library, or creating it.
*/
virtual void FootprintLibCreate( const wxString& aLibraryPath, PROPERTIES* aProperties = NULL );
/**
* Function FootprintLibDelete
* deletes an existing footprint library, or complains if it cannot delete it or if it
* does not exist.
*
* @param aLibraryPath is a locator for the "library", usually a directory
* or file which will contain footprints.
*
* @param aProperties is an associative array that can be used to tell the
* library create function anything special, because it can take any number of
* additional named tuning arguments that the plugin is known to support.
* The caller continues to own this object (plugin may not delete it), and
* plugins should expect it to be optionally NULL.
*
* @throw IO_ERROR if there is a problem finding the library, or deleting it.
*/
virtual void FootprintLibDelete( const wxString& aLibraryPath, PROPERTIES* aProperties = NULL );
/**
* Function IsFootprintLibWritable
* returns true iff the library at @a aLibraryPath is writable. (Often
* system libraries are read only because of where they are installed.)
*/
virtual bool IsFootprintLibWritable( const wxString& aLibraryPath );
//-----</PUBLIC PLUGIN API>------------------------------------------------
/* The compiler writes the "zero argument" constructor for a PLUGIN
automatically if you do not provide one. If you decide you need to
provide a zero argument constructor of your own design, that is allowed.
It must be public, and it is what the IO_MGR uses. Parameters may be
passed into a PLUGIN via the PROPERTIES variable for either Save() and Load().
passed into a PLUGIN via the PROPERTIES variable for any of the public
API functions which take one.
*/
virtual ~PLUGIN() {}
......
......@@ -2,7 +2,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2007-2011 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2007-2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2004 Jean-Pierre Charras, jean-pierre.charras@gipsa-lab.inpg.fr
* Copyright (C) 1992-2011 KiCad Developers, see change_log.txt for contributors.
......@@ -98,6 +98,8 @@
#define SZ( x ) (sizeof(x)-1)
//-----<BOARD Load Functions>---------------------------------------------------
/// C string compare test for a specific length of characters.
#define TESTLINE( x ) ( !strnicmp( line, x, SZ( x ) ) && isspace( line[SZ( x )] ) )
......@@ -106,7 +108,7 @@
#if 1
#define READLINE() m_reader->ReadLine()
#define READLINE( rdr ) rdr->ReadLine()
#else
/// The function and macro which follow comprise a shim which can be a
......@@ -128,7 +130,7 @@ static inline unsigned ReadLine( LINE_READER* rdr, const char* caller )
return ret;
}
#define READLINE() ReadLine( m_reader, __FUNCTION__ )
#define READLINE( rdr ) ReadLine( rdr, __FUNCTION__ )
#endif
static const char delims[] = " \t\r\n";
......@@ -167,12 +169,14 @@ BOARD* LEGACY_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe, PROPE
{
LOCALE_IO toggle; // toggles on, then off, the C locale.
init( aProperties );
m_board = aAppendToMe ? aAppendToMe : new BOARD();
// delete on exception, iff I own m_board, according to aAppendToMe
auto_ptr<BOARD> deleter( aAppendToMe ? NULL : m_board );
FILE* fp = wxFopen( aFileName, wxT( "rt" ) );
FILE* fp = wxFopen( aFileName, wxT( "r" ) );
if( !fp )
{
m_error.Printf( _( "Unable to open file '%s'" ), aFileName.GetData() );
......@@ -184,8 +188,6 @@ BOARD* LEGACY_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe, PROPE
m_reader = &reader; // member function accessibility
init( aProperties );
checkVersion();
loadAllSections( bool( aAppendToMe ) );
......@@ -205,7 +207,7 @@ void LEGACY_PLUGIN::loadAllSections( bool doAppend )
// Then follows $EQUIPOT and all the rest
while( READLINE() )
while( READLINE( m_reader ) )
{
char* line = m_reader->Line();
......@@ -213,7 +215,8 @@ void LEGACY_PLUGIN::loadAllSections( bool doAppend )
if( TESTLINE( "$MODULE" ) )
{
loadMODULE();
MODULE* m = LoadMODULE();
m_board->Add( m, ADD_APPEND );
}
else if( TESTLINE( "$DRAWSEGMENT" ) )
......@@ -281,7 +284,7 @@ void LEGACY_PLUGIN::loadAllSections( bool doAppend )
}
else
{
while( READLINE() )
while( READLINE( m_reader ) )
{
line = m_reader->Line(); // gobble until $EndSetup
......@@ -332,7 +335,7 @@ void LEGACY_PLUGIN::checkVersion()
void LEGACY_PLUGIN::loadGENERAL()
{
while( READLINE() )
while( READLINE( m_reader ) )
{
char* line = m_reader->Line();
const char* data;
......@@ -344,7 +347,7 @@ void LEGACY_PLUGIN::loadGENERAL()
if( !strcmp( data, "mm" ) )
{
#if defined(USE_PCBNEW_NANOMETRES)
#if defined( USE_PCBNEW_NANOMETRES )
diskToBiu = 1000000.0;
#elif defined(DEBUG)
......@@ -460,7 +463,7 @@ void LEGACY_PLUGIN::loadSHEET()
char buf[260];
TITLE_BLOCK tb;
while( READLINE() )
while( READLINE( m_reader ) )
{
char* line = m_reader->Line();
......@@ -575,7 +578,7 @@ void LEGACY_PLUGIN::loadSETUP()
BOARD_DESIGN_SETTINGS bds = m_board->GetDesignSettings();
ZONE_SETTINGS zs = m_board->GetZoneSettings();
while( READLINE() )
while( READLINE( m_reader ) )
{
const char* data;
char* line = m_reader->Line();
......@@ -863,15 +866,16 @@ void LEGACY_PLUGIN::loadSETUP()
}
void LEGACY_PLUGIN::loadMODULE()
MODULE* LEGACY_PLUGIN::LoadMODULE()
{
auto_ptr<MODULE> module( new MODULE( m_board ) );
while( READLINE() )
while( READLINE( m_reader ) )
{
const char* data;
char* line = m_reader->Line();
const char* data;
// most frequently encountered ones at the top
if( TESTSUBSTR( "D" ) ) // read a drawing item, e.g. "DS"
......@@ -938,7 +942,7 @@ void LEGACY_PLUGIN::loadMODULE()
else if( TESTLINE( "Li" ) ) // Library name of footprint
{
module->m_LibRef = FROM_UTF8( StrPurge( line + SZ( "Li" ) ) );
module->SetLibRef( FROM_UTF8( StrPurge( line + SZ( "Li" ) ) ) );
}
else if( TESTLINE( "Sc" ) ) // timestamp
......@@ -1053,9 +1057,7 @@ void LEGACY_PLUGIN::loadMODULE()
{
module->CalculateBoundingBox();
m_board->Add( module.release(), ADD_APPEND );
return; // preferred exit
return module.release(); // preferred exit
}
}
......@@ -1067,7 +1069,7 @@ void LEGACY_PLUGIN::loadPAD( MODULE* aModule )
{
auto_ptr<D_PAD> pad( new D_PAD( aModule ) );
while( READLINE() )
while( READLINE( m_reader ) )
{
const char* data;
char* line = m_reader->Line();
......@@ -1371,7 +1373,7 @@ void LEGACY_PLUGIN::loadMODULE_EDGE( MODULE* aModule )
for( int ii = 0; ii<ptCount; ++ii )
{
if( !READLINE() )
if( !READLINE( m_reader ) )
{
THROW_IO_ERROR( "S_POLGON point count mismatch." );
}
......@@ -1542,7 +1544,7 @@ void LEGACY_PLUGIN::load3D( MODULE* aModule )
t3D = n3D;
}
while( READLINE() )
while( READLINE( m_reader ) )
{
char* line = m_reader->Line();
......@@ -1596,7 +1598,7 @@ void LEGACY_PLUGIN::loadPCB_LINE()
auto_ptr<DRAWSEGMENT> dseg( new DRAWSEGMENT( m_board ) );
while( READLINE() )
while( READLINE( m_reader ) )
{
const char* data;
char* line = m_reader->Line();
......@@ -1704,7 +1706,7 @@ void LEGACY_PLUGIN::loadNETINFO_ITEM()
NETINFO_ITEM* net = new NETINFO_ITEM( m_board );
m_board->AppendNet( net );
while( READLINE() )
while( READLINE( m_reader ) )
{
const char* data;
char* line = m_reader->Line();
......@@ -1756,7 +1758,7 @@ void LEGACY_PLUGIN::loadPCB_TEXT()
TEXTE_PCB* pcbtxt = new TEXTE_PCB( m_board );
m_board->Add( pcbtxt, ADD_APPEND );
while( READLINE() )
while( READLINE( m_reader ) )
{
const char* data;
char* line = m_reader->Line();
......@@ -1866,7 +1868,7 @@ void LEGACY_PLUGIN::loadPCB_TEXT()
void LEGACY_PLUGIN::loadTrackList( TRACK* aInsertBeforeMe, int aStructType )
{
while( READLINE() )
while( READLINE( m_reader ) )
{
// read two lines per loop iteration, each loop is one TRACK or VIA
// example first line:
......@@ -1899,7 +1901,7 @@ void LEGACY_PLUGIN::loadTrackList( TRACK* aInsertBeforeMe, int aStructType )
// differentiates between PCB_TRACE_T and PCB_VIA_T. With virtual
// functions in use, it is critical to instantiate the PCB_VIA_T
// exactly.
READLINE();
READLINE( m_reader );
line = m_reader->Line();
......@@ -1989,7 +1991,7 @@ void LEGACY_PLUGIN::loadNETCLASS()
// just before returning.
auto_ptr<NETCLASS> nc( new NETCLASS( m_board, wxEmptyString ) );
while( READLINE() )
while( READLINE( m_reader ) )
{
char* line = m_reader->Line();
......@@ -2082,7 +2084,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
bool sawCorner = false;
char buf[1024];
while( READLINE() )
while( READLINE( m_reader ) )
{
const char* data;
char* line = m_reader->Line();
......@@ -2233,7 +2235,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
{
// Read the PolysList (polygons used for fill areas in the zone)
while( READLINE() )
while( READLINE( m_reader ) )
{
line = m_reader->Line();
......@@ -2253,7 +2255,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
else if( TESTLINE( "$FILLSEGMENTS" ) )
{
while( READLINE() )
while( READLINE( m_reader ) )
{
line = m_reader->Line();
......@@ -2304,7 +2306,7 @@ void LEGACY_PLUGIN::loadDIMENSION()
{
auto_ptr<DIMENSION> dim( new DIMENSION( m_board ) );
while( READLINE() )
while( READLINE( m_reader ) )
{
const char* data;
char* line = m_reader->Line();
......@@ -2498,7 +2500,7 @@ void LEGACY_PLUGIN::loadDIMENSION()
void LEGACY_PLUGIN::loadPCB_TARGET()
{
while( READLINE() )
while( READLINE( m_reader ) )
{
const char* data;
char* line = m_reader->Line();
......@@ -2675,16 +2677,16 @@ double LEGACY_PLUGIN::degParse( const char* aValue, const char** nptrptr )
void LEGACY_PLUGIN::init( PROPERTIES* aProperties )
{
m_board = NULL;
m_props = aProperties;
// conversion factor for saving RAM BIUs to KICAD legacy file format.
#if defined(USE_PCBNEW_NANOMETRES)
#if defined( USE_PCBNEW_NANOMETRES )
biuToDisk = 1/1000000.0; // BIUs are nanometers & file is mm
#else
biuToDisk = 1.0; // BIUs are deci-mils
#endif
// conversion factor for loading KICAD legacy file format into BIUs in RAM
// Start by assuming the *.brd file is in deci-mils.
......@@ -2692,7 +2694,7 @@ void LEGACY_PLUGIN::init( PROPERTIES* aProperties )
// then, during the file loading process, to start a conversion from
// mm to nanometers.
#if defined(USE_PCBNEW_NANOMETRES)
#if defined( USE_PCBNEW_NANOMETRES )
diskToBiu = 2540.0; // BIUs are nanometers
#else
diskToBiu = 1.0; // BIUs are deci-mils
......@@ -2700,15 +2702,15 @@ void LEGACY_PLUGIN::init( PROPERTIES* aProperties )
}
//-----<Save() Functions>-------------------------------------------------------
//-----<BOARD Save Functions>---------------------------------------------------
void LEGACY_PLUGIN::Save( const wxString& aFileName, BOARD* aBoard, PROPERTIES* aProperties )
{
LOCALE_IO toggle; // toggles on, then off, the C locale.
m_board = aBoard;
init( aProperties );
FILE* fp = wxFopen( aFileName, wxT( "wt" ) );
FILE* fp = wxFopen( aFileName, wxT( "w" ) );
if( !fp )
{
m_error.Printf( _( "Unable to open file '%s'" ), aFileName.GetData() );
......@@ -2722,16 +2724,15 @@ void LEGACY_PLUGIN::Save( const wxString& aFileName, BOARD* aBoard, PROPERTIES*
m_fp = fp; // member function accessibility
init( aProperties );
if( m_props )
{
// @todo move the header production into this source file.
wxString header = (*m_props)["header"];
// save a file header, if caller provided one (with trailing \n hopefully).
fprintf( m_fp, "%s", TO_UTF8( header ) );
}
saveAllSections();
SaveBOARD( aBoard );
}
......@@ -2749,34 +2750,32 @@ do { \
} while(0)
void LEGACY_PLUGIN::saveAllSections() const
void LEGACY_PLUGIN::SaveBOARD( const BOARD* aBoard ) const
{
saveGENERAL( aBoard );
saveSHEET( aBoard );
saveGENERAL();
saveSETUP( aBoard );
saveSHEET();
saveSETUP();
saveBOARD();
saveBOARD_ITEMS( aBoard );
}
void LEGACY_PLUGIN::saveGENERAL() const
void LEGACY_PLUGIN::saveGENERAL( const BOARD* aBoard ) const
{
fprintf( m_fp, "$GENERAL\n" );
fprintf( m_fp, "encoding utf-8\n" );
// tell folks the units used within the file, as early as possible here.
#if defined(USE_PCBNEW_NANOMETRES)
#if defined( USE_PCBNEW_NANOMETRES )
fprintf( m_fp, "Units mm\n" );
#else
fprintf( m_fp, "Units deci-mils\n" );
#endif
// Write copper layer count
fprintf( m_fp, "LayerCount %d\n", m_board->GetCopperLayerCount() );
fprintf( m_fp, "LayerCount %d\n", aBoard->GetCopperLayerCount() );
/* No, EnabledLayers has this information, plus g_TabAllCopperLayerMask is
global and globals are not allowed in a plugin.
......@@ -2785,34 +2784,35 @@ void LEGACY_PLUGIN::saveGENERAL() const
g_TabAllCopperLayerMask[NbLayers - 1] | ALL_NO_CU_LAYERS );
*/
fprintf( m_fp, "EnabledLayers %08X\n", m_board->GetEnabledLayers() );
fprintf( m_fp, "EnabledLayers %08X\n", aBoard->GetEnabledLayers() );
if( m_board->GetEnabledLayers() != m_board->GetVisibleLayers() )
fprintf( m_fp, "VisibleLayers %08X\n", m_board->GetVisibleLayers() );
if( aBoard->GetEnabledLayers() != aBoard->GetVisibleLayers() )
fprintf( m_fp, "VisibleLayers %08X\n", aBoard->GetVisibleLayers() );
fprintf( m_fp, "Links %d\n", m_board->GetRatsnestsCount() );
fprintf( m_fp, "NoConn %d\n", m_board->m_NbNoconnect );
fprintf( m_fp, "Links %d\n", aBoard->GetRatsnestsCount() );
fprintf( m_fp, "NoConn %d\n", aBoard->m_NbNoconnect );
// Write Bounding box info
EDA_RECT bbbox = m_board->ComputeBoundingBox();
EDA_RECT bbbox = ((BOARD*)aBoard)->ComputeBoundingBox();
fprintf( m_fp, "Di %s %s\n",
fmtBIUPair( bbbox.GetX(), bbbox.GetY() ).c_str(),
fmtBIUPair( bbbox.GetRight(), bbbox.GetBottom() ).c_str() );
fprintf( m_fp, "Ndraw %d\n", m_board->m_Drawings.GetCount() );
fprintf( m_fp, "Ntrack %d\n", m_board->GetNumSegmTrack() );
fprintf( m_fp, "Nzone %d\n", m_board->GetNumSegmZone() );
fprintf( m_fp, "BoardThickness %s\n", fmtBIU( m_board->GetDesignSettings().m_BoardThickness ).c_str() );
fprintf( m_fp, "Nmodule %d\n", m_board->m_Modules.GetCount() );
fprintf( m_fp, "Nnets %d\n", m_board->GetNetCount() );
fprintf( m_fp, "Ndraw %d\n", aBoard->m_Drawings.GetCount() );
fprintf( m_fp, "Ntrack %d\n", aBoard->GetNumSegmTrack() );
fprintf( m_fp, "Nzone %d\n", aBoard->GetNumSegmZone() );
fprintf( m_fp, "BoardThickness %s\n", fmtBIU( aBoard->GetDesignSettings().m_BoardThickness ).c_str() );
fprintf( m_fp, "Nmodule %d\n", aBoard->m_Modules.GetCount() );
fprintf( m_fp, "Nnets %d\n", aBoard->GetNetCount() );
fprintf( m_fp, "$EndGENERAL\n\n" );
}
void LEGACY_PLUGIN::saveSHEET() const
void LEGACY_PLUGIN::saveSHEET( const BOARD* aBoard ) const
{
const PAGE_INFO& pageInfo = m_board->GetPageSettings();
const TITLE_BLOCK& tb = m_board->GetTitleBlock();
const PAGE_INFO& pageInfo = aBoard->GetPageSettings();
const TITLE_BLOCK& tb = ((BOARD*)aBoard)->GetTitleBlock();
fprintf( m_fp, "$SHEETDESCR\n" );
......@@ -2837,10 +2837,10 @@ void LEGACY_PLUGIN::saveSHEET() const
}
void LEGACY_PLUGIN::saveSETUP() const
void LEGACY_PLUGIN::saveSETUP( const BOARD* aBoard ) const
{
NETCLASS* netclass_default = m_board->m_NetClasses.GetDefault();
const BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
NETCLASS* netclass_default = aBoard->m_NetClasses.GetDefault();
const BOARD_DESIGN_SETTINGS& bds = aBoard->GetDesignSettings();
fprintf( m_fp, "$SETUP\n" );
......@@ -2849,32 +2849,32 @@ void LEGACY_PLUGIN::saveSETUP() const
fprintf( m_fp,, "InternalUnit %f INCH\n", 1.0 / PCB_INTERNAL_UNIT );
*/
fprintf( m_fp, "Layers %d\n", m_board->GetCopperLayerCount() );
fprintf( m_fp, "Layers %d\n", aBoard->GetCopperLayerCount() );
unsigned layerMask = ALL_CU_LAYERS & m_board->GetEnabledLayers();
unsigned layerMask = ALL_CU_LAYERS & aBoard->GetEnabledLayers();
for( int layer = 0; layerMask; ++layer, layerMask >>= 1 )
{
if( layerMask & 1 )
{
fprintf( m_fp, "Layer[%d] %s %s\n", layer,
TO_UTF8( m_board->GetLayerName( layer ) ),
LAYER::ShowType( m_board->GetLayerType( layer ) ) );
TO_UTF8( aBoard->GetLayerName( layer ) ),
LAYER::ShowType( aBoard->GetLayerType( layer ) ) );
}
}
// Save current default track width, for compatibility with older Pcbnew version;
fprintf( m_fp, "TrackWidth %s\n", fmtBIU( m_board->GetCurrentTrackWidth() ).c_str() );
fprintf( m_fp, "TrackWidth %s\n", fmtBIU( aBoard->GetCurrentTrackWidth() ).c_str() );
// Save custom tracks width list (the first is not saved here: this is the netclass value
for( unsigned ii = 1; ii < m_board->m_TrackWidthList.size(); ii++ )
fprintf( m_fp, "TrackWidthList %s\n", fmtBIU( m_board->m_TrackWidthList[ii] ).c_str() );
for( unsigned ii = 1; ii < aBoard->m_TrackWidthList.size(); ii++ )
fprintf( m_fp, "TrackWidthList %s\n", fmtBIU( aBoard->m_TrackWidthList[ii] ).c_str() );
fprintf( m_fp, "TrackClearence %s\n", fmtBIU( netclass_default->GetClearance() ).c_str() );
// ZONE_SETTINGS
fprintf( m_fp, "ZoneClearence %s\n", fmtBIU( m_board->GetZoneSettings().m_ZoneClearance ).c_str() );
fprintf( m_fp, "Zone_45_Only %d\n", m_board->GetZoneSettings().m_Zone_45_Only );
fprintf( m_fp, "ZoneClearence %s\n", fmtBIU( aBoard->GetZoneSettings().m_ZoneClearance ).c_str() );
fprintf( m_fp, "Zone_45_Only %d\n", aBoard->GetZoneSettings().m_Zone_45_Only );
fprintf( m_fp, "TrackMinWidth %s\n", fmtBIU( bds.m_TrackMinWidth ).c_str() );
......@@ -2889,10 +2889,10 @@ void LEGACY_PLUGIN::saveSETUP() const
// Save custom vias diameters list (the first is not saved here: this is
// the netclass value
for( unsigned ii = 1; ii < m_board->m_ViasDimensionsList.size(); ii++ )
for( unsigned ii = 1; ii < aBoard->m_ViasDimensionsList.size(); ii++ )
fprintf( m_fp, "ViaSizeList %s %s\n",
fmtBIU( m_board->m_ViasDimensionsList[ii].m_Diameter ).c_str(),
fmtBIU( m_board->m_ViasDimensionsList[ii].m_Drill ).c_str() );
fmtBIU( aBoard->m_ViasDimensionsList[ii].m_Diameter ).c_str(),
fmtBIU( aBoard->m_ViasDimensionsList[ii].m_Drill ).c_str() );
// for old versions compatibility:
fprintf( m_fp, "MicroViaSize %s\n", fmtBIU( netclass_default->GetuViaDiameter() ).c_str() );
......@@ -2926,14 +2926,14 @@ void LEGACY_PLUGIN::saveSETUP() const
}
*/
fprintf( m_fp, "AuxiliaryAxisOrg %s\n", fmtBIUPoint( m_board->GetOriginAxisPosition() ).c_str() );
fprintf( m_fp, "AuxiliaryAxisOrg %s\n", fmtBIUPoint( aBoard->GetOriginAxisPosition() ).c_str() );
fprintf( m_fp, "VisibleElements %X\n", bds.GetVisibleElements() );
{
STRING_FORMATTER sf;
m_board->GetPlotOptions().Format( &sf, 0 );
aBoard->GetPlotOptions().Format( &sf, 0 );
wxString record = FROM_UTF8( sf.GetString().c_str() );
......@@ -2947,22 +2947,22 @@ void LEGACY_PLUGIN::saveSETUP() const
}
void LEGACY_PLUGIN::saveBOARD() const
void LEGACY_PLUGIN::saveBOARD_ITEMS( const BOARD* aBoard ) const
{
// save the nets
int netcount = m_board->GetNetCount();
int netcount = aBoard->GetNetCount();
for( int i = 0; i < netcount; ++i )
saveNETINFO_ITEM( m_board->FindNet( i ) );
saveNETINFO_ITEM( aBoard->FindNet( i ) );
// Saved nets do not include netclass names, so save netclasses after nets.
saveNETCLASSES();
saveNETCLASSES( &aBoard->m_NetClasses );
// save the modules
for( MODULE* m = m_board->m_Modules; m; m = (MODULE*) m->Next() )
saveMODULE( m );
for( MODULE* m = aBoard->m_Modules; m; m = (MODULE*) m->Next() )
SaveMODULE( m );
// save the graphics owned by the board (not owned by a module)
for( BOARD_ITEM* gr = m_board->m_Drawings; gr; gr = gr->Next() )
for( BOARD_ITEM* gr = aBoard->m_Drawings; gr; gr = gr->Next() )
{
switch( gr->Type() )
{
......@@ -2987,19 +2987,19 @@ void LEGACY_PLUGIN::saveBOARD() const
// save the tracks & vias
fprintf( m_fp, "$TRACK\n" );
for( TRACK* track = m_board->m_Track; track; track = track->Next() )
for( TRACK* track = aBoard->m_Track; track; track = track->Next() )
saveTRACK( track );
fprintf( m_fp, "$EndTRACK\n" );
// save the old obsolete zones which were done by segments (tracks)
fprintf( m_fp, "$ZONE\n" );
for( SEGZONE* zone = m_board->m_Zone; zone; zone = zone->Next() )
for( SEGZONE* zone = aBoard->m_Zone; zone; zone = zone->Next() )
saveTRACK( zone );
fprintf( m_fp, "$EndZONE\n" );
// save the polygon (which are the newer technology) zones
for( int i=0; i < m_board->GetAreaCount(); ++i )
saveZONE_CONTAINER( m_board->GetArea( i ) );
for( int i=0; i < aBoard->GetAreaCount(); ++i )
saveZONE_CONTAINER( aBoard->GetArea( i ) );
fprintf( m_fp, "$EndBOARD\n" );
......@@ -3018,15 +3018,13 @@ void LEGACY_PLUGIN::saveNETINFO_ITEM( const NETINFO_ITEM* aNet ) const
}
void LEGACY_PLUGIN::saveNETCLASSES() const
void LEGACY_PLUGIN::saveNETCLASSES( const NETCLASSES* aNetClasses ) const
{
const NETCLASSES& nc = m_board->m_NetClasses;
// save the default first.
saveNETCLASS( nc.GetDefault() );
saveNETCLASS( aNetClasses->GetDefault() );
// the rest will be alphabetical in the *.brd file.
for( NETCLASSES::const_iterator it = nc.begin(); it != nc.end(); ++it )
for( NETCLASSES::const_iterator it = aNetClasses->begin(); it != aNetClasses->end(); ++it )
{
NETCLASS* netclass = it->second;
saveNETCLASS( netclass );
......@@ -3232,8 +3230,9 @@ void LEGACY_PLUGIN::savePAD( const D_PAD* me ) const
if( me->GetLocalSolderPasteMargin() != 0 )
fprintf( m_fp, ".SolderPaste %s\n", fmtBIU( me->GetLocalSolderPasteMargin() ).c_str() );
if( me->GetLocalSolderPasteMarginRatio() != 0 )
fprintf( m_fp, ".SolderPasteRatio %g\n", me->GetLocalSolderPasteMarginRatio() );
double ratio = me->GetLocalSolderPasteMarginRatio();
if( ratio != 0.0 )
fprintf( m_fp, ".SolderPasteRatio %g\n", ratio );
if( me->GetLocalClearance() != 0 )
fprintf( m_fp, ".LocalClearance %s\n", fmtBIU( me->GetLocalClearance( ) ).c_str() );
......@@ -3253,7 +3252,7 @@ void LEGACY_PLUGIN::savePAD( const D_PAD* me ) const
}
void LEGACY_PLUGIN::saveMODULE( const MODULE* me ) const
void LEGACY_PLUGIN::SaveMODULE( const MODULE* me ) const
{
char statusTxt[3];
double orient = me->GetOrientation();
......@@ -3294,8 +3293,9 @@ void LEGACY_PLUGIN::saveMODULE( const MODULE* me ) const
if( me->GetLocalSolderPasteMargin() != 0 )
fprintf( m_fp, ".SolderPaste %s\n", fmtBIU( me->GetLocalSolderPasteMargin() ).c_str() );
if( me->GetLocalSolderPasteMarginRatio() != 0 )
fprintf( m_fp, ".SolderPasteRatio %g\n", me->GetLocalSolderPasteMarginRatio() );
double ratio = me->GetLocalSolderPasteMarginRatio();
if( ratio != 0.0 )
fprintf( m_fp, ".SolderPasteRatio %g\n", ratio );
if( me->GetLocalClearance() != 0 )
fprintf( m_fp, ".LocalClearance %s\n", fmtBIU( me->GetLocalClearance( ) ).c_str() );
......@@ -3346,7 +3346,7 @@ void LEGACY_PLUGIN::saveMODULE( const MODULE* me ) const
for( D_PAD* pad = me->m_Pads; pad; pad = pad->Next() )
savePAD( pad );
save3D( me );
SaveModule3D( me );
fprintf( m_fp, "$EndMODULE %s\n", TO_UTF8( me->GetLibRef() ) );
......@@ -3354,7 +3354,7 @@ void LEGACY_PLUGIN::saveMODULE( const MODULE* me ) const
}
void LEGACY_PLUGIN::save3D( const MODULE* me ) const
void LEGACY_PLUGIN::SaveModule3D( const MODULE* me ) const
{
for( S3D_MASTER* t3D = me->m_3D_Drawings; t3D; t3D = t3D->Next() )
{
......@@ -3698,3 +3698,496 @@ void LEGACY_PLUGIN::savePCB_TEXT( const TEXTE_PCB* me ) const
fprintf( m_fp, "$EndTEXTPCB\n" );
}
//-----<FOOTPRINT LIBRARY FUNCTIONS>--------------------------------------------
/*
The legacy file format is being obsoleted and this code will have a short
lifetime, so it only needs to be good enough for a short duration of time.
Caching all the MODULEs is a bit memory intensive, but it is a considerably
faster way of fulfilling the API contract. Otherwise, without the cache, you
would have to re-read the file when searching for any MODULE, and this would
be very problematic filling a FOOTPRINT_LIST via this PLUGIN API. If memory
becomes a concern, consider the cache lifetime policy, which determines the
time that a FPL_CACHE is in RAM. Note PLUGIN lifetime also plays a role in
cache lifetime.
*/
#include <boost/ptr_container/ptr_map.hpp>
#include <wx/filename.h>
typedef boost::ptr_map< wxString, MODULE > MODULE_MAP;
typedef MODULE_MAP::iterator MODULE_ITER;
typedef MODULE_MAP::const_iterator MODULE_CITER;
/**
* Class FPL_CACHE
* assists only for the footprint portion of the PLUGIN API, and only for the
* LEGACY_PLUGIN, so therefore is private to this implementation file, i.e. not placed
* into a header.
*/
struct FPL_CACHE
{
LEGACY_PLUGIN* m_owner; // my owner, I need its LEGACY_PLUGIN::LoadMODULE()
wxString m_lib_name;
wxDateTime m_mod_time;
MODULE_MAP m_modules; // map or tuple of footprint_name vs. MODULE*
bool m_writable;
FPL_CACHE( LEGACY_PLUGIN* aOwner, const wxString& aLibraryPath );
// Most all functions in this class throw IO_ERROR exceptions. There are no
// error codes nor user interface calls from here, nor in any PLUGIN.
// Catch these exceptions higher up please.
/// save the entire legacy library to m_lib_name;
void Save();
void SaveHeader( FILE* aFile );
void SaveIndex( FILE* aFile );
void SaveModules( FILE* aFile );
void SaveEndOfFile( FILE* aFile )
{
fprintf( aFile, "$EndLIBRARY\n" );
}
void Load();
void ReadAndVerifyHeader( LINE_READER* aReader );
void SkipIndex( LINE_READER* aReader );
void LoadModules( LINE_READER* aReader );
wxDateTime GetLibModificationTime();
};
FPL_CACHE::FPL_CACHE( LEGACY_PLUGIN* aOwner, const wxString& aLibraryPath ) :
m_owner( aOwner ),
m_lib_name( aLibraryPath ),
m_writable( true )
{
}
wxDateTime FPL_CACHE::GetLibModificationTime()
{
wxFileName fn( m_lib_name );
// update the writable flag while we have a wxFileName, in a network this
// is possibly quite dynamic anyway.
m_writable = fn.IsFileWritable();
return fn.GetModificationTime();
}
void FPL_CACHE::Load()
{
FILE* fp = wxFopen( m_lib_name, wxT( "r" ) );
if( !fp )
{
THROW_IO_ERROR( wxString::Format(
_( "Unable to open legacy library file '%s'" ), m_lib_name.GetData() ) );
}
// reader now owns fp, will close on exception or return
FILE_LINE_READER reader( fp, m_lib_name );
ReadAndVerifyHeader( &reader );
SkipIndex( &reader );
LoadModules( &reader );
// Remember the file modification time of library file when the
// cache snapshot was made, so that in a networked environment we will
// reload the cache as needed.
m_mod_time = GetLibModificationTime();
}
void FPL_CACHE::ReadAndVerifyHeader( LINE_READER* aReader )
{
char* line;
if( !aReader->ReadLine() )
goto L_bad_library;
line = aReader->Line();
if( !TESTLINE( "PCBNEW-LibModule-V1" ) )
goto L_bad_library;
while( aReader->ReadLine() )
{
line = aReader->Line();
if( TESTLINE( "Units" ) )
{
const char* units = strtok( line + SZ( "Units" ), delims );
if( !strcmp( units, "mm" ) )
{
#if defined( USE_PCBNEW_NANOMETRES )
m_owner->diskToBiu = 1000000.0;
#elif defined(DEBUG)
// mm to deci-mils:
// advanced testing of round tripping only, not supported in non DEBUG build
m_owner->diskToBiu = 10000/25.4;
#else
THROW_IO_ERROR( _( "May not load millimeter legacy library file into 'PCBNew compiled for deci-mils'" ) );
#endif
}
}
else if( TESTLINE( "$INDEX" ) )
return;
}
L_bad_library:
THROW_IO_ERROR( wxString::Format( _( "File '%s' is empty or is not a legacy library" ),
m_lib_name.GetData() ) );
}
void FPL_CACHE::SkipIndex( LINE_READER* aReader )
{
// Some broken INDEX sections have more than one section, due to prior bugs.
// So we must read the next line after $EndINDEX tag,
// to see if this is not a new $INDEX tag.
bool exit = false;
do
{
char* line = aReader->Line();
if( TESTLINE( "$INDEX" ) )
{
exit = false;
while( aReader->ReadLine() )
{
line = aReader->Line();
if( TESTLINE( "$EndINDEX" ) )
{
exit = true;
break;
}
}
}
else if( exit )
break;
} while( aReader->ReadLine() );
}
void FPL_CACHE::LoadModules( LINE_READER* aReader )
{
m_owner->SetReader( aReader );
do
{
// test first for the $MODULE, even before reading because of INDEX bug.
char* line = aReader->Line();
if( TESTLINE( "$MODULE" ) )
{
MODULE* m = m_owner->LoadMODULE();
// wxString footprintName = m->GetReference();
wxString footprintName = m->GetLibRef();
std::pair<MODULE_ITER, bool> r = m_modules.insert( footprintName, m );
// m's module is gone here, both on success or failure of insertion.
// no memory leak, container deleted m on failure.
if( !r.second )
{
THROW_IO_ERROR( wxString::Format(
_( "library '%s' has a duplicate footprint named '%s'" ),
m_lib_name.GetData(), footprintName.GetData() ) );
}
}
} while( aReader->ReadLine() );
}
void FPL_CACHE::Save()
{
if( !m_writable )
{
THROW_IO_ERROR( wxString::Format(
_( "Legacy library file '%s' is read only" ), m_lib_name.GetData() ) );
}
wxString tempFileName = wxFileName::CreateTempFileName( m_lib_name );
wxLogDebug( "tempFileName:'%s'\n", TO_UTF8( tempFileName ) );
FILE* fp = wxFopen( tempFileName, wxT( "w" ) );
if( !fp )
{
THROW_IO_ERROR( wxString::Format(
_( "Unable to open or create legacy library file '%s'" ),
m_lib_name.GetData() ) );
}
// wxf now owns fp, will close on exception or return
wxFFile wxf( fp );
SaveHeader( fp );
SaveIndex( fp );
SaveModules( fp );
SaveEndOfFile( fp );
wxRemove( m_lib_name ); // it is not an error if this does not exist
if( wxRename( tempFileName, m_lib_name ) )
{
THROW_IO_ERROR( wxString::Format(
_( "Unable to rename tempfile '%s' to to library file '%s'" ),
tempFileName.GetData(),
m_lib_name.GetData() ) );
}
}
void FPL_CACHE::SaveHeader( FILE* aFile )
{
fprintf( aFile, "%s %s\n", FOOTPRINT_LIBRARY_HEADER, TO_UTF8( DateAndTime() ) );
fprintf( aFile, "# encoding utf-8\n" );
#if defined( USE_PCBNEW_NANOMETRES )
fprintf( aFile, "Units mm\n" );
#else
fprintf( aFile, "Units deci-mils\n" );
#endif
}
void FPL_CACHE::SaveIndex( FILE* aFile )
{
fprintf( aFile, "$INDEX\n" );
for( MODULE_CITER it = m_modules.begin(); it != m_modules.end(); ++it )
{
fprintf( aFile, "%s\n", TO_UTF8( it->first ) );
}
fprintf( aFile, "$EndINDEX\n" );
}
void FPL_CACHE::SaveModules( FILE* aFile )
{
m_owner->SetFilePtr( aFile );
for( MODULE_CITER it = m_modules.begin(); it != m_modules.end(); ++it )
{
m_owner->SaveMODULE( it->second );
}
}
void LEGACY_PLUGIN::cacheLib( const wxString& aLibraryPath )
{
if( !m_cache || m_cache->m_lib_name != aLibraryPath ||
// somebody else on a network touched the library:
m_cache->m_mod_time != m_cache->GetLibModificationTime() )
{
// a spectacular episode in memory management:
delete m_cache;
m_cache = new FPL_CACHE( this, aLibraryPath );
m_cache->Load();
}
}
wxArrayString LEGACY_PLUGIN::FootprintEnumerate( const wxString& aLibraryPath, PROPERTIES* aProperties )
{
LOCALE_IO toggle; // toggles on, then off, the C locale.
init( aProperties );
cacheLib( aLibraryPath );
const MODULE_MAP& mods = m_cache->m_modules;
wxArrayString ret;
for( MODULE_CITER it = mods.begin(); it != mods.end(); ++it )
{
ret.Add( it->first );
}
return ret;
}
MODULE* LEGACY_PLUGIN::FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName,
PROPERTIES* aProperties )
{
LOCALE_IO toggle; // toggles on, then off, the C locale.
init( aProperties );
cacheLib( aLibraryPath );
const MODULE_MAP& mods = m_cache->m_modules;
MODULE_CITER it = mods.find( aFootprintName );
if( it == mods.end() )
{
/*
THROW_IO_ERROR( wxString::Format( _( "No '%s' footprint in library '%s'" ),
aFootprintName.GetData(), aLibraryPath.GetData() ) );
*/
return NULL;
}
// copy constructor to clone the already loaded MODULE
return new MODULE( *it->second );
}
void LEGACY_PLUGIN::FootprintSave( const wxString& aLibraryPath, const MODULE* aFootprint, PROPERTIES* aProperties )
{
LOCALE_IO toggle; // toggles on, then off, the C locale.
init( aProperties );
cacheLib( aLibraryPath );
if( !m_cache->m_writable )
{
THROW_IO_ERROR( wxString::Format( _( "Library '%s' is read only" ), aLibraryPath.GetData() ) );
}
wxString footprintName = aFootprint->GetLibRef();
MODULE_MAP& mods = m_cache->m_modules;
// quietly overwrite any by same name.
MODULE_CITER it = mods.find( footprintName );
if( it != mods.end() )
{
mods.erase( footprintName );
}
// I need my own copy for the cache
MODULE* my_module = new MODULE( *aFootprint );
// and it's time stamp must be 0, it should have no parent, orientation should
// be zero, and it should be on the front layer.
my_module->SetTimeStamp( 0 );
my_module->SetParent( 0 );
my_module->SetOrientation( 0 );
if( my_module->GetLayer() != LAYER_N_FRONT )
my_module->Flip( my_module->GetPosition() );
mods.insert( footprintName, my_module );
m_cache->Save();
}
void LEGACY_PLUGIN::FootprintDelete( const wxString& aLibraryPath, const wxString& aFootprintName )
{
LOCALE_IO toggle; // toggles on, then off, the C locale.
init( NULL );
cacheLib( aLibraryPath );
if( !m_cache->m_writable )
{
THROW_IO_ERROR( wxString::Format( _( "Library '%s' is read only" ), aLibraryPath.GetData() ) );
}
size_t erasedCount = m_cache->m_modules.erase( aFootprintName );
if( erasedCount != 1 )
{
THROW_IO_ERROR( wxString::Format(
_( "library '%s' has no footprint '%s' to delete" ),
aLibraryPath.GetData(), aFootprintName.GetData() ) );
}
m_cache->Save();
}
void LEGACY_PLUGIN::FootprintLibCreate( const wxString& aLibraryPath, PROPERTIES* aProperties )
{
if( wxFileExists( aLibraryPath ) )
{
THROW_IO_ERROR( wxString::Format(
_( "library '%s' already exists, will not create anew" ),
aLibraryPath.GetData() ) );
}
LOCALE_IO toggle;
init( NULL );
delete m_cache;
m_cache = new FPL_CACHE( this, aLibraryPath );
m_cache->Save();
m_cache->Load(); // update m_writable and m_mod_time
}
void LEGACY_PLUGIN::FootprintLibDelete( const wxString& aLibraryPath, PROPERTIES* aProperties )
{
wxFileName fn = aLibraryPath;
if( !fn.FileExists() )
{
THROW_IO_ERROR( wxString::Format(
_( "library '%s' does not exist, cannot be deleted" ),
aLibraryPath.GetData() ) );
}
// Some of the more elaborate wxRemoveFile() crap puts up its own wxLog dialog
// we don't want that. we want bare metal portability with no UI here.
if( wxRemove( aLibraryPath ) )
{
THROW_IO_ERROR( wxString::Format(
_( "library '%s' cannot be deleted" ),
aLibraryPath.GetData() ) );
}
}
bool LEGACY_PLUGIN::IsFootprintLibWritable( const wxString& aLibraryPath )
{
LOCALE_IO toggle;
init( NULL );
cacheLib( aLibraryPath );
return m_cache->m_writable;
}
LEGACY_PLUGIN::~LEGACY_PLUGIN()
{
delete m_cache;
}
......@@ -27,6 +27,10 @@
#include <io_mgr.h>
#include <string>
#define FOOTPRINT_LIBRARY_HEADER "PCBNEW-LibModule-V1"
#define FOOTPRINT_LIBRARY_HEADER_CNT 18
typedef int BIU;
class PCB_TARGET;
......@@ -36,6 +40,7 @@ class NETINFO;
class TEXTE_PCB;
class TRACK;
class NETCLASS;
class NETCLASSES;
class ZONE_CONTAINER;
class DIMENSION;
class NETINFO_ITEM;
......@@ -44,6 +49,8 @@ class EDGE_MODULE;
class TRACK;
class SEGZONE;
class D_PAD;
struct FPL_CACHE;
/**
* Class LEGACY_PLUGIN
......@@ -52,10 +59,11 @@ class D_PAD;
*/
class LEGACY_PLUGIN : public PLUGIN
{
friend struct FPL_CACHE;
public:
//-----<PLUGIN>-------------------------------------------------------------
//-----<PLUGIN IMPLEMENTATION>----------------------------------------------
const wxString& PluginName() const
{
......@@ -73,7 +81,42 @@ public:
void Save( const wxString& aFileName, BOARD* aBoard, PROPERTIES* aProperties = NULL ); // overload
//-----</PLUGIN>------------------------------------------------------------
wxArrayString FootprintEnumerate( const wxString& aLibraryPath, PROPERTIES* aProperties = NULL);
MODULE* FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName,
PROPERTIES* aProperties = NULL );
void FootprintSave( const wxString& aLibraryPath, const MODULE* aFootprint,
PROPERTIES* aProperties = NULL );
void FootprintDelete( const wxString& aLibraryPath, const wxString& aFootprintName );
void FootprintLibCreate( const wxString& aLibraryPath, PROPERTIES* aProperties = NULL );
void FootprintLibDelete( const wxString& aLibraryPath, PROPERTIES* aProperties = NULL );
bool IsFootprintLibWritable( const wxString& aLibraryPath );
//-----</PLUGIN IMPLEMENTATION>---------------------------------------------
LEGACY_PLUGIN() :
m_board( 0 ),
m_props( 0 ),
m_reader( 0 ),
m_fp( 0 ),
m_cache( 0 )
{}
~LEGACY_PLUGIN();
void SetReader( LINE_READER* aReader ) { m_reader = aReader; }
void SetFilePtr( FILE* aFile ) { m_fp = aFile; }
MODULE* LoadMODULE();
void SaveMODULE( const MODULE* aModule ) const;
void SaveModule3D( const MODULE* aModule ) const;
void SaveBOARD( const BOARD* aBoard ) const;
protected:
......@@ -87,6 +130,8 @@ protected:
wxString m_field; ///< reused to stuff MODULE fields.
int m_loading_format_version; ///< which BOARD_FORMAT_VERSION am I Load()ing?
FPL_CACHE* m_cache;
/// initialize PLUGIN like a constructor would, and futz with fresh BOARD if needed.
void init( PROPERTIES* aProperties );
......@@ -131,11 +176,11 @@ protected:
void loadAllSections( bool doAppend );
void loadGENERAL();
void loadSETUP();
void loadSHEET();
void loadMODULE();
void load3D( MODULE* aModule );
void loadPAD( MODULE* aModule );
void loadMODULE_TEXT( TEXTE_MODULE* aText );
......@@ -205,20 +250,17 @@ protected:
*/
std::string fmtDEG( double aAngle ) const;
void saveAllSections() const;
void saveGENERAL() const;
void saveSHEET() const;
void saveSETUP() const;
void saveBOARD() const;
void saveGENERAL( const BOARD* aBoard ) const;
void saveSHEET( const BOARD* aBoard ) const;
void saveSETUP( const BOARD* aBoard ) const;
void saveBOARD_ITEMS( const BOARD* aBoard ) const;
void saveMODULE( const MODULE* aModule ) const;
void saveMODULE_TEXT( const TEXTE_MODULE* aText ) const;
void saveMODULE_EDGE( const EDGE_MODULE* aGraphic ) const;
void savePAD( const D_PAD* aPad ) const;
void save3D( const MODULE* aModule ) const;
void saveNETINFO_ITEM( const NETINFO_ITEM* aNet ) const;
void saveNETCLASSES() const;
void saveNETCLASSES( const NETCLASSES* aNetClasses ) const;
void saveNETCLASS( const NETCLASS* aNetclass ) const;
void savePCB_TEXT( const TEXTE_PCB* aText ) const;
......@@ -235,6 +277,8 @@ protected:
//-----</save functions>----------------------------------------------------
/// we only cache one footprint library for now, this determines which one.
void cacheLib( const wxString& aLibraryPath );
};
#endif // LEGACY_PLUGIN_H_
......@@ -20,9 +20,9 @@
#include <class_module.h>
#include <pcbnew.h>
#include <class_footprint_library.h>
#include <module_editor_frame.h>
#include <wildcards_and_files_ext.h>
#include <legacy_plugin.h> // temporarily, for LoadMODULE()
/*
......@@ -46,26 +46,24 @@ static const wxString ModImportFileWildcard( _( "GPcb foot print files (*)|*" )
MODULE* FOOTPRINT_EDIT_FRAME::Import_Module()
{
char* Line;
FILE* file;
MODULE* module = NULL;
bool Footprint_Is_GPCB_Format = false;
// use the clipboard for this in the future?
wxString LastOpenedPathForLoading;
wxConfig* Config = wxGetApp().GetSettings();
wxString lastOpenedPathForLoading;
wxConfig* config = wxGetApp().GetSettings();
if( Config )
Config->Read( EXPORT_IMPORT_LASTPATH_KEY, &LastOpenedPathForLoading );
if( config )
config->Read( EXPORT_IMPORT_LASTPATH_KEY, &lastOpenedPathForLoading );
wxString importWildCard = ModExportFileWildcard + wxT("|") + ModImportFileWildcard;
wxFileDialog dlg( this, _( "Import Footprint Module" ),
LastOpenedPathForLoading, wxEmptyString,
lastOpenedPathForLoading, wxEmptyString,
importWildCard, wxFD_OPEN | wxFD_FILE_MUST_EXIST );
if( dlg.ShowModal() == wxID_CANCEL )
return NULL;
file = wxFopen( dlg.GetPath(), wxT( "rt" ) );
FILE* file = wxFopen( dlg.GetPath(), wxT( "rt" ) );
if( file == NULL )
{
......@@ -75,28 +73,29 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module()
return NULL;
}
FILE_LINE_READER fileReader( file, dlg.GetPath() );
FILTER_READER reader( fileReader );
if( Config ) // Save file path
if( config ) // Save file path
{
LastOpenedPathForLoading = wxPathOnly( dlg.GetPath() );
Config->Write( EXPORT_IMPORT_LASTPATH_KEY, LastOpenedPathForLoading );
lastOpenedPathForLoading = wxPathOnly( dlg.GetPath() );
config->Write( EXPORT_IMPORT_LASTPATH_KEY, lastOpenedPathForLoading );
}
// Switch the locale to standard C (needed to print floating point numbers like 1.3)
SetLocaleTo_C_standard();
LOCALE_IO toggle;
FILE_LINE_READER fileReader( file, dlg.GetPath() );
FILTER_READER reader( fileReader );
// Read header and test file type
reader.ReadLine();
Line = reader.Line();
char* line = reader.Line();
if( strnicmp( Line, FOOTPRINT_LIBRARY_HEADER, FOOTPRINT_LIBRARY_HEADER_CNT ) != 0 )
bool footprint_Is_GPCB_Format = false;
if( strnicmp( line, FOOTPRINT_LIBRARY_HEADER, FOOTPRINT_LIBRARY_HEADER_CNT ) != 0 )
{
if( strnicmp( Line, "Element", 7 ) == 0 )
if( strnicmp( line, "Element", 7 ) == 0 )
{
Footprint_Is_GPCB_Format = true;
footprint_Is_GPCB_Format = true;
}
else
{
......@@ -106,27 +105,41 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module()
}
// Read file: Search the description starting line (skip lib header)
if( !Footprint_Is_GPCB_Format )
if( !footprint_Is_GPCB_Format )
{
while( reader.ReadLine() )
{
if( strnicmp( Line, "$MODULE", 7 ) == 0 )
if( strnicmp( line, "$MODULE", 7 ) == 0 )
break;
}
}
module = new MODULE( GetBoard() );
MODULE* module;
if( Footprint_Is_GPCB_Format )
if( footprint_Is_GPCB_Format )
{
// @todo GEDA plugin
module = new MODULE( GetBoard() );
module->Read_GPCB_Descr( dlg.GetPath() );
}
else
{
module->ReadDescr( &reader );
}
try
{
PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::LEGACY ) );
LEGACY_PLUGIN* lp = (LEGACY_PLUGIN*)(PLUGIN*)pi;
lp->SetReader( &reader );
SetLocaleTo_Default(); // revert to the current locale
module = lp->LoadMODULE();
}
catch( IO_ERROR ioe )
{
DisplayError( this, ioe.errorText );
return NULL;
}
}
// Insert footprint in list
GetBoard()->Add( module );
......@@ -144,9 +157,8 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module()
void FOOTPRINT_EDIT_FRAME::Export_Module( MODULE* aModule, bool aCreateSysLib )
{
wxFileName fn;
FILE* file;
wxString msg, path, title, wildcard;
wxConfig* Config = wxGetApp().GetSettings();
wxConfig* config = wxGetApp().GetSettings();
if( aModule == NULL )
return;
......@@ -156,12 +168,14 @@ void FOOTPRINT_EDIT_FRAME::Export_Module( MODULE* aModule, bool aCreateSysLib )
if( aCreateSysLib )
path = wxGetApp().ReturnLastVisitedLibraryPath();
else if( Config )
Config->Read( EXPORT_IMPORT_LASTPATH_KEY, &path );
else if( config )
config->Read( EXPORT_IMPORT_LASTPATH_KEY, &path );
fn.SetPath( path );
title = aCreateSysLib ? _( "Create New Library" ) : _( "Export Module" );
wildcard = aCreateSysLib ? FootprintLibFileWildcard : ModExportFileWildcard;
fn.SetPath( path );
wxFileDialog dlg( this, msg, fn.GetPath(), fn.GetFullName(),
wxGetTranslation( wildcard ),
wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
......@@ -172,180 +186,63 @@ void FOOTPRINT_EDIT_FRAME::Export_Module( MODULE* aModule, bool aCreateSysLib )
fn = dlg.GetPath();
wxGetApp().SaveLastVisitedLibraryPath( fn.GetPath() );
if( ( file = wxFopen( fn.GetFullPath(), wxT( "wt" ) ) ) == NULL )
if( !aCreateSysLib && config ) // Save file path
{
msg.Printf( _( "Unable to create <%s>" ), GetChars( fn.GetFullPath() ) );
DisplayError( this, msg );
return;
config->Write( EXPORT_IMPORT_LASTPATH_KEY, fn.GetPath() );
}
if( !aCreateSysLib && Config ) // Save file path
{
Config->Write( EXPORT_IMPORT_LASTPATH_KEY, fn.GetPath() );
}
// Switch the locale to standard C (needed to read/write floating point numbers like 1.3)
SetLocaleTo_C_standard();
FOOTPRINT_LIBRARY libexport( file );
libexport.WriteHeader();
libexport.m_List.Add(aModule->m_LibRef);
libexport.WriteSectionIndex();
GetBoard()->m_Modules->Save( file );
wxString libName = fn.GetFullPath();
libexport.WriteEndOfFile();
fclose( file );
try
{
// @todo : hard code this as IO_MGR::KICAD plugin, what would be the reason to "export"
// any other single footprint type, with clipboard support coming?
// Use IO_MGR::LEGACY for now, until the IO_MGR::KICAD plugin is ready.
PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::LEGACY ) );
SetLocaleTo_Default(); // revert to the current locale
pi->FootprintLibCreate( libName );
pi->FootprintSave( libName, aModule );
}
catch( IO_ERROR ioe )
{
DisplayError( this, ioe.errorText );
return;
}
msg.Printf( _( "Module exported in file <%s>" ), GetChars( fn.GetFullPath() ) );
msg.Printf( _( "Module exported in file <%s>" ), libName.GetData() );
DisplayInfoMessage( this, msg );
}
void FOOTPRINT_EDIT_FRAME::Delete_Module_In_Library( const wxString& aLibname )
void FOOTPRINT_EDIT_FRAME::Delete_Module_In_Library( const wxString& aLibName )
{
wxFileName newFileName;
wxFileName oldFileName;
int LineNum = 0;
char Line[1024], Name[256];
FILE* out_file, * lib_module;
wxString CmpName, msg;
wxString footprintName = Select_1_Module_From_List( this, aLibName, wxEmptyString, wxEmptyString );
CmpName = Select_1_Module_From_List( this, aLibname, wxEmptyString, wxEmptyString );
if( CmpName == wxEmptyString )
if( footprintName == wxEmptyString )
return;
// Confirmation
msg.Printf( _( "Ok to delete module %s in library %s" ),
GetChars( CmpName ), GetChars( aLibname ) );
wxString msg = wxString::Format( _( "Ok to delete module '%s' in library '%s'" ),
footprintName.GetData(), aLibName.GetData() );
if( !IsOK( this, msg ) )
return;
oldFileName = aLibname;
if( ( lib_module = wxFopen( oldFileName.GetFullPath(), wxT( "rt" ) ) ) == NULL )
{
wxString msg;
msg.Printf( _( "Library <%s> not found" ), GetChars(oldFileName.GetFullPath() ) );
DisplayError( NULL, msg );
return;
}
FOOTPRINT_LIBRARY input_lib( lib_module );
// Read header.
if( ! input_lib.IsLibrary() )
{
fclose( lib_module );
wxString msg;
msg.Printf( _( "<%s> is not a valid footprint library file" ),
GetChars( oldFileName.GetFullPath() ) );
DisplayError( NULL, msg );
return;
}
// Read module names.
input_lib.RebuildIndex();
bool found = input_lib.FindInList( CmpName );
if( !found )
{
fclose( lib_module );
msg.Printf( _( "Module [%s] not found" ), GetChars( CmpName ) );
DisplayError( NULL, msg );
return;
}
// Create new library.
newFileName = oldFileName;
newFileName.SetExt( FILETMP_EXT );
if( ( out_file = wxFopen( newFileName.GetFullPath(), wxT( "wt" ) ) ) == NULL )
{
fclose( lib_module );
msg.Printf( _( "Unable to create %s" ), GetChars( newFileName.GetFullPath() ) );
DisplayError( NULL, msg );
return;
}
wxBeginBusyCursor();
FOOTPRINT_LIBRARY output_lib( out_file );
output_lib.m_List = input_lib.m_List;
output_lib.WriteHeader();
output_lib.RemoveFromList( CmpName );
output_lib.SortList();
output_lib.WriteSectionIndex();
// Copy modules.
rewind( lib_module );
LineNum = input_lib.m_LineNum;
bool copylines = false;
while( GetLine( lib_module, Line, &LineNum ) )
{
StrPurge( Line );
if( strnicmp( Line, "$MODULE", 7 ) == 0 )
try
{
copylines = true;
sscanf( Line + 7, " %s", Name );
msg = FROM_UTF8( Name );
PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::LEGACY ) );
if( msg.CmpNoCase( CmpName ) == 0 )
{
// Delete old module (i.e. do not copy description to out_file).
while( GetLine( lib_module, Line, &LineNum ) )
{
if( strnicmp( Line, "$EndMODULE", 9 ) == 0 )
break;
}
continue;
pi->FootprintDelete( aLibName, footprintName );
}
}
if( copylines )
fprintf( out_file, "%s\n", Line );
}
fclose( lib_module );
fclose( out_file );
wxEndBusyCursor();
// The old library file is renamed .bak
wxFileName backupFileName = oldFileName;
backupFileName.SetExt( BACKUP_EXT );
if( backupFileName.FileExists() )
wxRemoveFile( backupFileName.GetFullPath() );
if( !wxRenameFile( oldFileName.GetFullPath(), backupFileName.GetFullPath() ) )
catch( IO_ERROR ioe )
{
msg.Printf( _( "Could not create library back up file <%s>." ),
GetChars( backupFileName.GetFullName() ) );
DisplayError( this, msg );
DisplayError( NULL, ioe.errorText );
return;
}
// The temporary file is renamed as the previous library.
if( !wxRenameFile( newFileName.GetFullPath(), oldFileName.GetFullPath() ) )
{
msg.Printf( _("Could not create temporary library file <%s>."),
GetChars( oldFileName.GetFullName() ) );
DisplayError( this, msg );
return;
}
msg.Printf( _( "Component '%s' deleted from library '%s'" ),
footprintName.GetData(), aLibName.GetData() );
msg.Printf( _( "Component %s deleted in library %s" ), GetChars( CmpName ),
GetChars( oldFileName.GetFullPath() ) );
SetStatusText( msg );
}
......@@ -368,7 +265,7 @@ void PCB_EDIT_FRAME::ArchiveModulesOnBoard( const wxString& aLibName, bool aNewM
path = wxGetApp().ReturnLastVisitedLibraryPath();
if( aLibName.IsEmpty() )
if( !aLibName )
{
wxFileDialog dlg( this, _( "Library" ), path,
wxEmptyString,
......@@ -383,12 +280,12 @@ void PCB_EDIT_FRAME::ArchiveModulesOnBoard( const wxString& aLibName, bool aNewM
wxFileName fn( fileName );
wxGetApp().SaveLastVisitedLibraryPath( fn.GetPath() );
bool file_exists = wxFileExists( fileName );
bool lib_exists = wxFileExists( fileName );
if( !aNewModulesOnly && file_exists )
if( !aNewModulesOnly && lib_exists )
{
wxString msg;
msg.Printf( _( "File %s exists, OK to replace ?" ), GetChars( fileName ) );
msg.Printf( _( "Library %s exists, OK to replace ?" ), GetChars( fileName ) );
if( !IsOK( this, msg ) )
return;
......@@ -396,52 +293,47 @@ void PCB_EDIT_FRAME::ArchiveModulesOnBoard( const wxString& aLibName, bool aNewM
m_canvas->SetAbortRequest( false );
// Create a new, empty library if no old lib, or if archive all modules
if( !aNewModulesOnly || !file_exists )
try
{
FILE* lib_module;
PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::LEGACY ) );
if( ( lib_module = wxFopen( fileName, wxT( "w+t" ) ) ) == NULL )
// Delete old library if we're replacing it entirely.
if( lib_exists && !aNewModulesOnly )
{
wxString msg;
msg.Printf( _( "Unable to create <%s>" ), GetChars(fileName) );
DisplayError( this, msg );
return;
pi->FootprintLibDelete( fileName );
lib_exists = false;
}
FOOTPRINT_LIBRARY new_lib( lib_module );
new_lib.WriteHeader();
new_lib.WriteSectionIndex();
new_lib.WriteEndOfFile();
fclose( lib_module );
if( !lib_exists )
{
pi->FootprintLibCreate( fileName );
}
MODULE* module = (MODULE*) GetBoard()->m_Modules;
for( int ii = 1; module != NULL; ii++, module = module->Next() )
if( !aNewModulesOnly )
{
// Save footprints in default orientation (0.0) and default layer (FRONT layer)
int orient = module->GetOrientation();
if ( orient != 0 )
module->SetOrientation( 0 );
int layer = module->GetLayer();
if(layer != LAYER_N_FRONT )
module->Flip( module->m_Pos );
bool success = Save_Module_In_Library( fileName, module,
aNewModulesOnly ? false : true, false );
// Restore previous orientation and/or side
if(layer != module->GetLayer() )
module->Flip( module->m_Pos );
if ( orient != 0 )
module->SetOrientation( orient );
if( !success )
for( MODULE* m = GetBoard()->m_Modules; m; m = m->Next() )
{
pi->FootprintSave( fileName, m );
}
}
else
{
for( MODULE* m = GetBoard()->m_Modules; m; m = m->Next() )
{
if( !Save_Module_In_Library( fileName, m, false, false ) )
break;
// Check for request to stop backup (ESCAPE key actuated)
if( m_canvas->GetAbortRequest() )
break;
}
}
}
catch( IO_ERROR ioe )
{
DisplayError( this, ioe.errorText );
return;
}
}
......@@ -450,202 +342,84 @@ bool PCB_BASE_FRAME::Save_Module_In_Library( const wxString& aLibName,
bool aOverwrite,
bool aDisplayDialog )
{
wxFileName oldFileName;
wxFileName newFileName;
int LineNum = 0, tmp;
char Name[256], Line[1024];
wxString Name_Cmp;
wxString msg;
FILE* lib_module, * dest;
if( aModule == NULL )
return false;
aModule->DisplayInfo( this );
newFileName = aLibName;
if( !newFileName.FileExists( aLibName ) )
if( !wxFileExists( aLibName ) )
{
msg.Printf( _( "Library <%s> not found." ), GetChars( aLibName ) );
wxString msg = wxString::Format( _( "Library <%s> not found." ),
aLibName.GetData() );
DisplayError( this, msg );
return false;
}
if( !IsWritable( newFileName ) )
if( !IsWritable( aLibName ) )
return false;
// Ask for the footprint name in lib
Name_Cmp = aModule->m_LibRef;
// Ask what to use as the footprint name in the library
wxString footprintName = aModule->GetLibRef();
if( aDisplayDialog )
{
wxTextEntryDialog dlg( this, _( "Name:" ), _( "Save module" ), Name_Cmp );
wxTextEntryDialog dlg( this, _( "Name:" ), _( "Save Module" ), footprintName );
if( dlg.ShowModal() != wxID_OK )
return false; // canceled by user
Name_Cmp = dlg.GetValue();
Name_Cmp.Trim( true );
Name_Cmp.Trim( false );
footprintName = dlg.GetValue();
footprintName.Trim( true );
footprintName.Trim( false );
if( Name_Cmp.IsEmpty() )
if( footprintName.IsEmpty() )
return false;
aModule->m_LibRef = Name_Cmp;
aModule->SetLibRef( footprintName );
}
// Ensure this footprint has a libname
if( Name_Cmp.IsEmpty() )
if( footprintName.IsEmpty() )
{
Name_Cmp = wxT("noname");
aModule->m_LibRef = Name_Cmp;
footprintName = wxT("noname");
aModule->SetLibRef( footprintName );
}
if( ( lib_module = wxFopen( aLibName, wxT( "rt" ) ) ) == NULL )
{
msg.Printf( _( "Unable to open <%s>" ), GetChars( aLibName ) );
DisplayError( this, msg );
return false;
}
// Read library file
FOOTPRINT_LIBRARY input_lib( lib_module );
MODULE* module_exists = NULL;
if( ! input_lib.IsLibrary() )
try
{
fclose( lib_module );
msg.Printf( _( "File <%s> is not an Eeschema library" ), GetChars( aLibName ) );
DisplayError( this, msg );
return false;
}
PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::LEGACY ) );
// Read footprints in lib: - search for an existing footprint
input_lib.RebuildIndex();
bool module_exists = input_lib.FindInList( Name_Cmp );
module_exists = pi->FootprintLoad( aLibName, footprintName );
if( module_exists )
{
delete module_exists;
// an existing footprint is found in current lib
if( aDisplayDialog )
{
msg = _( "Module exists\n Line: " );
msg << LineNum;
wxString msg = wxString::Format(
_( "Footprint '%s' already exists in library '%s'" ),
footprintName.GetData(), aLibName.GetData() );
SetStatusText( msg );
}
if( !aOverwrite ) // Do not save the given footprint: an old one exists
if( !aOverwrite )
{
fclose( lib_module );
// Do not save the given footprint: an old one exists
return true;
}
}
// Creates the new library
newFileName.SetExt( FILETMP_EXT );
if( ( dest = wxFopen( newFileName.GetFullPath(), wxT( "w+t" ) ) ) == NULL )
{
fclose( lib_module );
msg.Printf( _( "Unable to create <%s>" ), GetChars( newFileName.GetFullPath() ) );
DisplayError( this, msg );
return false;
}
wxBeginBusyCursor();
// Switch the locale to standard C (needed to print floating point numbers like 1.3)
SetLocaleTo_C_standard();
FOOTPRINT_LIBRARY output_lib( dest );
output_lib.m_List = input_lib.m_List;
if( ! module_exists )
output_lib.m_List.Add( Name_Cmp );
output_lib.SortList();
// Create the library header with a new date
output_lib.WriteHeader();
output_lib.WriteSectionIndex();
LineNum = 0;
rewind( lib_module);
// Copy footprints, until the old footprint to delete
bool skip_header = true;
while( GetLine( lib_module, Line, &LineNum ) )
{
StrPurge( Line );
if( strnicmp( Line, "$EndLIBRARY", 8 ) == 0 )
continue;
// Search for the beginning of module section:
if( skip_header )
{
if( strnicmp( Line, "$MODULE", 7 ) == 0 )
skip_header = false;
else
continue;
}
if( strnicmp( Line, "$MODULE", 7 ) == 0 )
{
sscanf( Line + 7, " %s", Name );
msg = FROM_UTF8( Name );
if( msg.CmpNoCase( Name_Cmp ) == 0 )
{
// skip old footprint descr (delete from the lib)
while( GetLine( lib_module, Line, &LineNum ) )
{
if( strnicmp( Line, "$EndMODULE", 9 ) == 0 )
break;
}
continue;
}
}
fprintf( dest, "%s\n", Line );
}
// Write the new footprint ( append it to the list of footprint )
tmp = aModule->GetTimeStamp();
aModule->SetTimeStamp( 0 );
aModule->Save( dest );
aModule->SetTimeStamp( tmp );
output_lib.WriteEndOfFile();
fclose( dest );
fclose( lib_module );
SetLocaleTo_Default(); // revert to the current locale
wxEndBusyCursor();
// The old library file is renamed .bak
oldFileName = aLibName;
oldFileName.SetExt( BACKUP_EXT );
if( oldFileName.FileExists() )
wxRemoveFile( oldFileName.GetFullPath() );
if( !wxRenameFile( aLibName, oldFileName.GetFullPath() ) )
{
msg.Printf( _( "Could not create library back up file <%s>." ),
GetChars( oldFileName.GetFullName() ) );
DisplayError( this, msg );
// this always overwrites any existing footprint
pi->FootprintSave( aLibName, aModule );
}
// The new library file is renamed
if( !wxRenameFile( newFileName.GetFullPath(), aLibName ) )
catch( IO_ERROR ioe )
{
msg.Printf( _( "Could not create temporary library file <%s>." ),
GetChars( aLibName ) );
DisplayError( this, msg );
DisplayError( this, ioe.errorText );
return false;
}
......@@ -654,7 +428,8 @@ bool PCB_BASE_FRAME::Save_Module_In_Library( const wxString& aLibName,
wxString fmt = module_exists ?
_( "Component [%s] replaced in <%s>" ) :
_( "Component [%s] added in <%s>" );
msg.Printf( fmt, GetChars( Name_Cmp ), GetChars( aLibName ) );
wxString msg = wxString::Format( fmt, footprintName.GetData(), aLibName.GetData() );
SetStatusText( msg );
}
......@@ -755,13 +530,14 @@ void FOOTPRINT_EDIT_FRAME::Select_Active_Library()
int FOOTPRINT_EDIT_FRAME::CreateLibrary( const wxString& aLibName )
{
FILE* lib_module;
wxString msg;
wxFileName fileName = aLibName;
if( fileName.FileExists() )
{
msg.Printf( _( "Library <%s> already exists." ), GetChars( fileName.GetFullPath() ) );
wxString msg = wxString::Format(
_( "Library <%s> already exists." ),
aLibName.GetData() );
DisplayError( this, msg );
return 0;
}
......@@ -769,18 +545,18 @@ int FOOTPRINT_EDIT_FRAME::CreateLibrary( const wxString& aLibName )
if( !IsWritable( fileName ) )
return 0;
if( ( lib_module = wxFopen( fileName.GetFullPath(), wxT( "wt" ) ) ) == NULL )
try
{
msg.Printf( _( "Unable to create library <%s>" ), GetChars( fileName.GetFullPath() ) );
DisplayError( this, msg );
return -1;
}
PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::LEGACY ) );
FOOTPRINT_LIBRARY new_lib( lib_module );
new_lib.WriteHeader();
new_lib.WriteSectionIndex();
new_lib.WriteEndOfFile();
fclose( lib_module );
pi->FootprintLibCreate( aLibName );
}
catch( IO_ERROR ioe )
{
DisplayError( this, ioe.errorText );
return 0;
}
return 1;
return 1; // remember how many times we succeeded
}
......@@ -42,11 +42,11 @@
#include <class_board.h>
#include <class_module.h>
#include <io_mgr.h>
#include <pcbnew.h>
#include <module_editor_frame.h>
#include <footprint_info.h>
#include <class_footprint_library.h>
#include <dialog_get_component.h>
#include <modview_frame.h>
#include <wildcards_and_files_ext.h>
......@@ -141,6 +141,7 @@ wxString PCB_BASE_FRAME::SelectFootprintFromLibBrowser( void )
return fpname;
}
MODULE* PCB_BASE_FRAME::Load_Module_From_Library( const wxString& aLibrary,
bool aUseFootprintViewer,
wxDC* aDC )
......@@ -148,12 +149,12 @@ MODULE* PCB_BASE_FRAME::Load_Module_From_Library( const wxString& aLibrary,
MODULE* module;
wxPoint curspos = GetScreen()->GetCrossHairPosition();
wxString moduleName, keys;
bool AllowWildSeach = true;
bool allowWildSeach = true;
static wxArrayString HistoryList;
static wxString lastComponentName;
/* Ask for a component name or key words */
// Ask for a component name or key words
DIALOG_GET_COMPONENT dlg( this, GetComponentDialogPosition(), HistoryList,
_( "Load Module" ), aUseFootprintViewer );
......@@ -171,7 +172,7 @@ MODULE* PCB_BASE_FRAME::Load_Module_From_Library( const wxString& aLibrary,
moduleName = dlg.GetComponentName();
}
if( moduleName.IsEmpty() ) /* Cancel command */
if( moduleName.IsEmpty() ) // Cancel command
{
m_canvas->MoveCursorToCrossHair();
return NULL;
......@@ -181,11 +182,11 @@ MODULE* PCB_BASE_FRAME::Load_Module_From_Library( const wxString& aLibrary,
if( dlg.IsKeyword() ) // Selection by keywords
{
AllowWildSeach = false;
allowWildSeach = false;
keys = moduleName;
moduleName = Select_1_Module_From_List( this, aLibrary, wxEmptyString, keys );
if( moduleName.IsEmpty() ) /* Cancel command */
if( moduleName.IsEmpty() ) // Cancel command
{
m_canvas->MoveCursorToCrossHair();
return NULL;
......@@ -194,29 +195,31 @@ MODULE* PCB_BASE_FRAME::Load_Module_From_Library( const wxString& aLibrary,
else if( ( moduleName.Contains( wxT( "?" ) ) )
|| ( moduleName.Contains( wxT( "*" ) ) ) ) // Selection wild card
{
AllowWildSeach = false;
allowWildSeach = false;
moduleName = Select_1_Module_From_List( this, aLibrary, moduleName, wxEmptyString );
if( moduleName.IsEmpty() )
{
m_canvas->MoveCursorToCrossHair();
return NULL; /* Cancel command. */
return NULL; // Cancel command.
}
}
module = GetModuleLibrary( aLibrary, moduleName, false );
if( ( module == NULL ) && AllowWildSeach ) /* Search with wild card */
if( !module && allowWildSeach ) // Search with wild card
{
AllowWildSeach = false;
allowWildSeach = false;
wxString wildname = wxChar( '*' ) + moduleName + wxChar( '*' );
moduleName = wildname;
moduleName = Select_1_Module_From_List( this, aLibrary, moduleName, wxEmptyString );
if( moduleName.IsEmpty() )
{
m_canvas->MoveCursorToCrossHair();
return NULL; /* Cancel command. */
return NULL; // Cancel command.
}
else
{
......@@ -234,13 +237,17 @@ MODULE* PCB_BASE_FRAME::Load_Module_From_Library( const wxString& aLibrary,
module->SetFlags( IS_NEW );
module->m_Link = 0;
module->SetTimeStamp( GetNewTimeStamp() );
GetBoard()->m_Status_Pcb = 0;
module->SetPosition( curspos );
// Put it on FRONT layer,
// (Can be stored on BACK layer if the lib is an archive built from a board)
if( module->GetLayer() != LAYER_N_FRONT )
module->Flip( module->m_Pos );
// Put in in orientation 0,
// even if it is not saved with with orientation 0 in lib
// (Can happen if the lib is an archive built from a board)
......@@ -256,117 +263,102 @@ MODULE* PCB_BASE_FRAME::Load_Module_From_Library( const wxString& aLibrary,
}
MODULE* PCB_BASE_FRAME::GetModuleLibrary( const wxString& aLibraryFullFilename,
const wxString& aModuleName,
bool aDisplayMessageError )
MODULE* PCB_BASE_FRAME::loadFootprintFromLibrary( const wxString& aLibraryPath,
const wxString& aFootprintName, bool aDisplayError )
{
wxFileName fn;
wxString msg, tmp;
MODULE* newModule;
FILE* file = NULL;
bool error_set = false;
bool one_lib = aLibraryFullFilename.IsEmpty() ? false : true;
for( unsigned ii = 0; ii < g_LibraryNames.GetCount(); ii++ )
try
{
if( one_lib )
fn = aLibraryFullFilename;
else
fn = wxFileName( wxEmptyString, g_LibraryNames[ii], FootprintLibFileExtension );
PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::LEGACY ) );
tmp = wxGetApp().FindLibraryPath( fn );
wxString libPath = wxGetApp().FindLibraryPath( aLibraryPath );
if( !tmp )
MODULE* footprint = pi->FootprintLoad( libPath, aFootprintName );
if( !footprint )
{
if( aDisplayMessageError && !error_set )
if( aDisplayError )
{
msg.Printf( _( "PCB footprint library file <%s> not found in search paths." ),
GetChars( fn.GetFullName() ) );
wxMessageBox( msg, _( "Library Load Error" ), wxOK | wxICON_ERROR, this );
error_set = true;
}
wxString msg = wxString::Format(
_( "Footprint '%s' not found in library '%s'" ),
aFootprintName.GetData(),
libPath.GetData() );
continue;
DisplayError( NULL, msg );
}
file = wxFopen( tmp, wxT( "rt" ) );
return NULL;
}
if( file == NULL )
GetBoard()->Add( footprint, ADD_APPEND );
SetStatusText( wxEmptyString );
return footprint;
}
catch( IO_ERROR ioe )
{
msg.Printf( _( "Could not open PCB footprint library file <%s>." ),
GetChars( tmp ) );
wxMessageBox( msg, _( "Library Load Error" ), wxOK | wxICON_ERROR, this );
continue;
DisplayError( this, ioe.errorText );
return NULL;
}
}
FILE_LINE_READER fileReader( file, tmp );
FILTER_READER reader( fileReader );
msg.Printf( _( "Scan Lib: %s" ), GetChars( tmp ) );
SetStatusText( msg );
FOOTPRINT_LIBRARY curr_lib( file, &reader );
MODULE* PCB_BASE_FRAME::loadFootprintFromLibraries(
const wxString& aFootprintName, bool aDisplayError )
{
bool showed_error = false;
MODULE* footprint = NULL;
if( !curr_lib.IsLibrary() )
try
{
msg.Printf( _( "<%s> is not a valid KiCad PCB footprint library file." ),
GetChars( tmp ) );
wxMessageBox( msg, _( "Library Load Error" ), wxOK | wxICON_ERROR, this );
return NULL;
}
// Reading the list of modules in the library.
curr_lib.ReadSectionIndex();
bool found = curr_lib.FindInList( aModuleName );
PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::LEGACY ) );
// Read library.
if( found )
for( unsigned ii = 0; ii < g_LibraryNames.GetCount(); ii++ )
{
wxString name;
wxFileName fn = wxFileName( wxEmptyString, g_LibraryNames[ii], FootprintLibFileExtension );
fileReader.Rewind();
wxString libPath = wxGetApp().FindLibraryPath( fn );
while( reader.ReadLine() )
if( !libPath )
{
char* line = reader.Line();
StrPurge( line + 8 );
if( aDisplayError && !showed_error )
{
wxString msg = wxString::Format(
_( "PCB footprint library file <%s> not found in search paths." ),
fn.GetFullName().GetData() );
if( strnicmp( line, "$MODULE", 7 ) != 0 )
DisplayError( this, msg );
showed_error = true;
}
continue;
}
// Read module name.
name = FROM_UTF8( line + 8 );
footprint = pi->FootprintLoad( libPath, aFootprintName );
if( name.CmpNoCase( aModuleName ) == 0 )
if( footprint )
{
newModule = new MODULE( GetBoard() );
// Temporarily switch the locale to standard C (needed to print
// floating point numbers like 1.3)
LOCALE_IO toggle;
newModule->ReadDescr( &reader );
GetBoard()->Add( newModule, ADD_APPEND );
GetBoard()->Add( footprint, ADD_APPEND );
SetStatusText( wxEmptyString );
return newModule;
}
}
return footprint;
}
if( one_lib )
break;
}
if( aDisplayMessageError )
if( !footprint )
{
if( aDisplayError )
{
msg.Printf( _( "Module <%s> not found" ), GetChars( aModuleName ) );
wxString msg = wxString::Format(
_( "Footprint '%s' not found in any library" ),
aFootprintName.GetData() );
DisplayError( NULL, msg );
}
return NULL;
}
}
catch( IO_ERROR ioe )
{
DisplayError( this, ioe.errorText );
}
return NULL;
}
......@@ -376,7 +368,7 @@ wxString PCB_BASE_FRAME::Select_1_Module_From_List( EDA_DRAW_FRAME* aWindow,
const wxString& aMask,
const wxString& aKeyWord )
{
static wxString OldName; /* Save the name of the last module loaded. */
static wxString OldName; // Save the name of the last module loaded.
wxString CmpName;
wxString msg;
wxArrayString libnames_list;
......@@ -386,7 +378,7 @@ wxString PCB_BASE_FRAME::Select_1_Module_From_List( EDA_DRAW_FRAME* aWindow,
else
libnames_list.Add( aLibraryFullFilename );
/* Find modules in libraries. */
// Find modules in libraries.
MList.ReadFootprintFiles( libnames_list );
wxArrayString footprint_names_list;
......@@ -461,7 +453,7 @@ static void DisplayCmpDoc( wxString& Name )
MODULE* FOOTPRINT_EDIT_FRAME::Select_1_Module_From_BOARD( BOARD* aPcb )
{
MODULE* module;
static wxString OldName; /* Save name of last module selected. */
static wxString OldName; // Save name of last module selected.
wxString CmpName, msg;
wxArrayString listnames;
......
......@@ -12,7 +12,6 @@
#include <class_board.h>
#include <class_module.h>
#include <class_footprint_library.h>
#include <pcbnew.h>
#include <pcbnew_id.h>
......
......@@ -35,7 +35,6 @@
class wxSashLayoutWindow;
class wxListBox;
class wxSemaphore;
class FOOTPRINT_LIBRARY;
/**
......
......@@ -543,7 +543,6 @@ PADSTACK* SPECCTRA_DB::makePADSTACK( BOARD* aBoard, D_PAD* aPad )
/// data type used to ensure unique-ness of pin names, holding (wxString and int)
//typedef std::map<wxString, int, wxString_less_than> PINMAP;
typedef std::map<wxString, int> PINMAP;
......
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