Commit 2515a806 authored by Dick Hollenbeck's avatar Dick Hollenbeck

initial work on PCBNew PLUGIN support, in preparation for nanometer board load and save

parent 5e3ca2e7
...@@ -4,6 +4,14 @@ KiCad ChangeLog 2010 ...@@ -4,6 +4,14 @@ KiCad ChangeLog 2010
Please add newer entries at the top, list the date and your name with Please add newer entries at the top, list the date and your name with
email address. email address.
2011-Nov-27 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
PCBNew
* Add PLUGIN and IO_MGR classes.
* Remove one argument from BOARD constructor,
* add BOARD::SetWindowFrame()
2011-sept-13 UPDATE Wayne Stambaugh <stambaughw@verizon.net> 2011-sept-13 UPDATE Wayne Stambaugh <stambaughw@verizon.net>
================================================================================ ================================================================================
PCBNew locate code refactoring. PCBNew locate code refactoring.
......
...@@ -33,14 +33,6 @@ in the BIU coordinate system. Points falling on the snap grid are evenly spaced ...@@ -33,14 +33,6 @@ in the BIU coordinate system. Points falling on the snap grid are evenly spaced
in X and Y directions and are some integer multiple apart in this 2D space, in X and Y directions and are some integer multiple apart in this 2D space,
greater than one BIU. greater than one BIU.
*) Metric Board. This is a pcb board that has a great number of coordinates and
distances that happen to be some multiple of the BIU that is also a multiple of
a metric engineering unit such as micrometers.
*) Imperial Board. This is a pcb board that has a great number of coordinates and
distances that happen to be some multiple of the BIU that is also a multiple of
an imperial engineering unit such as mils or inches.
Assumptions: Assumptions:
=========== ===========
...@@ -97,10 +89,10 @@ then FMT_ENG will be set to "%.6Lg". For example: ...@@ -97,10 +89,10 @@ then FMT_ENG will be set to "%.6Lg". For example:
#if USE_DOUBLE_BFU #if USE_DOUBLE_BFU
typedef double BFU; typedef double BFU;
#define FMT_ENG ".%6g" #define FMT_ENG ".%10g"
#else #else
typedef long double BFU; typedef long double BFU;
#define FMT_ENG ".%6Lg" #define FMT_ENG ".%10Lg"
#endif #endif
A format string can then be built up using compile time concatenation of A format string can then be built up using compile time concatenation of
...@@ -158,7 +150,7 @@ Here are the required immediate need BOARD load functions: ...@@ -158,7 +150,7 @@ Here are the required immediate need BOARD load functions:
of unity, since destination is a RAM BOARD using deci-mils as its BIU. of unity, since destination is a RAM BOARD using deci-mils as its BIU.
2) Legacy to nanometer loader. This loader uses a floating point scaling factor 2) Legacy to nanometer loader. This loader uses a floating point scaling factor
of ________, since destination is a RAM BOARD using nanometers as its BIU, and of 2540, since destination is a RAM BOARD using nanometers as its BIU, and
the source format is using deci-mils. the source format is using deci-mils.
3) mm to nanometer loader. This loader uses a floating point scaling factor 3) mm to nanometer loader. This loader uses a floating point scaling factor
......
...@@ -10,10 +10,10 @@ may choose to document this corresponding work in the CHANGELOG.txt file. ...@@ -10,10 +10,10 @@ may choose to document this corresponding work in the CHANGELOG.txt file.
/* /*
* This program source code file is part of KICAD, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 1992-2011 <author> * Copyright (C) 2011 <author>
* Copyright (C) 1992-2011 Kicad Developers, see change_log.txt for contributors. * Copyright (C) 2011 KiCad Developers, see change_log.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
......
...@@ -61,7 +61,7 @@ DISPLAY_FOOTPRINTS_FRAME::DISPLAY_FOOTPRINTS_FRAME( CVPCB_MAINFRAME* father, ...@@ -61,7 +61,7 @@ DISPLAY_FOOTPRINTS_FRAME::DISPLAY_FOOTPRINTS_FRAME( CVPCB_MAINFRAME* father,
icon.CopyFromBitmap( KiBitmap( icon_cvpcb_xpm ) ); icon.CopyFromBitmap( KiBitmap( icon_cvpcb_xpm ) );
SetIcon( icon ); SetIcon( icon );
SetBoard( new BOARD( NULL, this ) ); SetBoard( new BOARD( this ) );
SetScreen( new PCB_SCREEN() ); SetScreen( new PCB_SCREEN() );
LoadSettings(); LoadSettings();
......
...@@ -51,7 +51,7 @@ GBR_TO_PCB_EXPORTER::GBR_TO_PCB_EXPORTER( GERBVIEW_FRAME * aFrame, FILE * aFile ...@@ -51,7 +51,7 @@ GBR_TO_PCB_EXPORTER::GBR_TO_PCB_EXPORTER( GERBVIEW_FRAME * aFrame, FILE * aFile
{ {
m_gerbview_frame = aFrame; m_gerbview_frame = aFrame;
m_file = aFile; m_file = aFile;
m_pcb = new BOARD( NULL, m_gerbview_frame ); m_pcb = new BOARD( m_gerbview_frame );
} }
......
...@@ -61,7 +61,7 @@ GERBVIEW_FRAME::GERBVIEW_FRAME( wxWindow* father, ...@@ -61,7 +61,7 @@ GERBVIEW_FRAME::GERBVIEW_FRAME( wxWindow* father,
SetScreen( new PCB_SCREEN() ); SetScreen( new PCB_SCREEN() );
GetScreen()->m_CurrentSheetDesc = &g_Sheet_GERBER; GetScreen()->m_CurrentSheetDesc = &g_Sheet_GERBER;
SetBoard( new BOARD( NULL, this ) ); SetBoard( new BOARD( this ) );
GetBoard()->SetEnabledLayers( FULL_LAYERS ); // All 32 layers enabled at first. GetBoard()->SetEnabledLayers( FULL_LAYERS ); // All 32 layers enabled at first.
GetBoard()->SetVisibleLayers( FULL_LAYERS ); // All 32 layers visible. GetBoard()->SetVisibleLayers( FULL_LAYERS ); // All 32 layers visible.
......
...@@ -126,7 +126,9 @@ set(PCBNEW_SRCS ...@@ -126,7 +126,9 @@ set(PCBNEW_SRCS
hotkeys_board_editor.cpp hotkeys_board_editor.cpp
hotkeys_module_editor.cpp hotkeys_module_editor.cpp
initpcb.cpp initpcb.cpp
# io_mgr.cpp
ioascii.cpp ioascii.cpp
# kicad_plugin.cpp
layer_widget.cpp layer_widget.cpp
librairi.cpp librairi.cpp
loadcmp.cpp loadcmp.cpp
......
...@@ -32,14 +32,14 @@ BOARD_DESIGN_SETTINGS boardDesignSettings; ...@@ -32,14 +32,14 @@ BOARD_DESIGN_SETTINGS boardDesignSettings;
BOARD::BOARD( EDA_ITEM* parent, PCB_BASE_FRAME* frame ) : BOARD::BOARD( PCB_BASE_FRAME* frame ) :
BOARD_ITEM( (BOARD_ITEM*)parent, PCB_T ), BOARD_ITEM( (BOARD_ITEM*) NULL, PCB_T ),
m_NetClasses( this ) m_NetClasses( this )
{ {
m_PcbFrame = frame; m_PcbFrame = frame;
m_Status_Pcb = 0; // Status word: bit 1 = calculate. m_Status_Pcb = 0; // Status word: bit 1 = calculate.
SetBoardDesignSettings(&boardDesignSettings); SetBoardDesignSettings( &boardDesignSettings );
SetColorsSettings(&g_ColorsSettings); SetColorsSettings( &g_ColorsSettings );
m_NbNodes = 0; // Number of connected pads. m_NbNodes = 0; // Number of connected pads.
m_NbNoconnect = 0; // Number of unconnected nets. m_NbNoconnect = 0; // Number of unconnected nets.
......
...@@ -161,6 +161,12 @@ private: ...@@ -161,6 +161,12 @@ private:
public: public:
PCB_BASE_FRAME* m_PcbFrame; // Window of visualization PCB_BASE_FRAME* m_PcbFrame; // Window of visualization
void SetWindowFrame( PCB_BASE_FRAME* aFrame )
{
m_PcbFrame = aFrame;
}
EDA_RECT m_BoundaryBox; // Board size and position EDA_RECT m_BoundaryBox; // Board size and position
/// Flags used in ratsnest calculation and update. /// Flags used in ratsnest calculation and update.
...@@ -231,7 +237,7 @@ private: ...@@ -231,7 +237,7 @@ private:
void chainMarkedSegments( wxPoint aPosition, int aLayerMask, TRACK_PTRS* aList ); void chainMarkedSegments( wxPoint aPosition, int aLayerMask, TRACK_PTRS* aList );
public: public:
BOARD( EDA_ITEM* aParent, PCB_BASE_FRAME* frame ); BOARD( PCB_BASE_FRAME* frame );
~BOARD(); ~BOARD();
/** /**
......
...@@ -39,7 +39,7 @@ bool PCB_EDIT_FRAME::Clear_Pcb( bool aQuery ) ...@@ -39,7 +39,7 @@ bool PCB_EDIT_FRAME::Clear_Pcb( bool aQuery )
// delete the old BOARD and create a new BOARD so that the default // delete the old BOARD and create a new BOARD so that the default
// layer names are put into the BOARD. // layer names are put into the BOARD.
SetBoard( new BOARD( NULL, this ) ); SetBoard( new BOARD( this ) );
SetCurItem( NULL ); SetCurItem( NULL );
/* clear filename, to avoid overwriting an old file */ /* clear filename, to avoid overwriting an old file */
......
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2011 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2011 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <io_mgr.h>
#include <kicad_plugin.h>
// some day plugins could be in separate DLL/DSOs, until then, use the simplest method:
// This implementation is one of two which could be done.
// the other one would cater to DLL/DSO's. But since it would be nearly
// impossible to link a KICAD type DLL/DSO right now without pulling in all
// ::Draw() functions, I forgo that option.
// Some day it may be possible to have some built in AND some DLL/DSO, but
// only when we can keep things clean enough to link a DLL/DSO without
// pulling in the world.
static KICAD_PLUGIN kicad_plugin;
//static EAGLE_PLUGIN eagle_plugin;
PLUGIN* IO_MGR::PluginFind( PCB_FILE_T aFileType )
{
switch( aFileType )
{
case KICAD: return &kicad_plugin;
// case EAGLE: return &eagle_plugin;
}
return NULL;
}
void IO_MGR::PluginRelease( PLUGIN* aPlugin )
{
// This function is a place holder for a future point in time where
// the plugin is a DLL/DSO. It could do reference counting, and then
// unload the DLL/DSO when count goes to zero.
}
const wxString& IO_MGR::ShowType( PCB_FILE_T aFileType )
{
static const wxString kicad = wxT( "KiCad" );
static const wxString unknown = _( "Unknown" );
switch( aFileType )
{
case KICAD:
return kicad;
default:
return unknown; // could Printf() the numeric value of aFileType
}
}
BOARD* IO_MGR::Load( PCB_FILE_T aFileType, const wxString& aFileName,
BOARD* aAppendToMe, PROPERTIES* aProperties )
{
// release the PLUGIN even if an exception is thrown.
PLUGIN::RELEASER pi = PluginFind( aFileType );
if( (PLUGIN*) pi ) // test pi->plugin
{
return pi->Load( aFileName, aAppendToMe, aProperties ); // virtual
}
wxString msg;
msg.Printf( _( "Plugin type '%s' is not found.\n" ), ShowType( aFileType ).GetData() );
THROW_IO_ERROR( msg );
}
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.
wxString msg;
msg.Printf( _( "Plugin %s does not implement the BOARD Load() function.\n" ),
Name().GetData() );
THROW_IO_ERROR( msg );
}
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.
wxString msg;
msg.Printf( _( "Plugin %s does not implement the BOARD Save() function.\n" ),
Name().GetData() );
THROW_IO_ERROR( msg );
}
#ifndef IO_MGR_H_
#define IO_MGR_H_
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2011 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2011 Kicad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <wx/string.h>
#include <wx/hashmap.h>
#include <richio.h>
// http://docs.wxwidgets.org/trunk/classwx_hash_map.html
WX_DECLARE_STRING_HASH_MAP( wxString, PROPERTIES );
class BOARD;
class SCHEMATIC;
class PLUGIN;
/**
* Class IO_MGR
* is factory which returns an instance of a PLUGIN DSO/DLL.
*/
class IO_MGR
{
public:
/**
* Enum PCB_FILE_T
* is a set of file types that the IO_MGR knows about, and for which there
* has been a plugin written.
*/
enum PCB_FILE_T
{
KICAD,
// EAGLE,
// ALTIUM,
// etc.
};
/**
* Function PluginFind
* returns a PLUGIN which the caller can use to import, export, save, or load
* design documents. The returned PLUGIN, may be reference counted, so please
* call PluginRelease() when you are done using the returned PLUGIN.
*
* @param aFileType is from PCB_FILE_T and tells which plugin to find.
*
* @return PLUGIN* - the plugin corresponding to aFileType or NULL if not found.
* Caller owns the returned object, and must call PluginRelease when done using it.
*/
static PLUGIN* PluginFind( PCB_FILE_T aFileType );
/**
* Function PluginRelease
* releases a PLUGIN back to the system, and may cause it to be unloaded from memory.
*
* @param aPlugin is the one to be released, and which is no longer usable.
*/
static void PluginRelease( PLUGIN* aPlugin );
/**
* Function ShowType
* returns a brief name for a plugin, given aFileType enum.
*/
static const wxString& ShowType( PCB_FILE_T aFileType );
/**
* Function Load
* finds the requested plugin and loads a BOARD, or throws an exception trying.
*
* @param aFileType is the type of file to load.
*
* @param aFileName is the name of the file to load.
*
* @param aAppendToMe is an existing BOARD to append to, use NULL if fresh
* board load wanted.
*
* @param aProperties is an associative array that allows the caller to
* pass additional tuning parameters to the plugin.
*
* @return BOARD* - caller owns it, never NULL because exception thrown if error.
*
* @throw IO_ERROR if the pluging cannot be found, file cannot be found,
* or file cannot be loaded.
*/
static BOARD* Load( PCB_FILE_T aFileType, const wxString& aFileName,
BOARD* aAppendToMe = NULL, PROPERTIES* aProperties = NULL );
// etc.
};
/**
* Class PLUGIN
* 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, and also do the switching to stardard C locale
* and back, outside the region in which an exception can be thrown. This means
* the PLUGINs do not deal with the locale, the caller does.
*
* <pre>
*
* // Switch the locale to standard C (needed to read floating point numbers
* // like 1.3)
*
* SetLocaleTo_C_standard();
* try
* {
* pi->Load(...);
* }
* catch( IO_ERROR ioe )
* {
* // grab text from ioe, show in error window.
* }
* SetLocaleTo_Default(); // revert to the current locale
*
* </pre>
*/
class PLUGIN
{
public:
virtual ~PLUGIN() {}
/**
* Class RELEASER
* releases a PLUGIN in the context of a potential thrown exception, through
* its destructor.
*/
class RELEASER
{
PLUGIN* plugin;
public:
RELEASER( PLUGIN* aPlugin = NULL ) :
plugin( aPlugin )
{
}
~RELEASER()
{
if( plugin )
IO_MGR::PluginRelease( plugin );
}
operator PLUGIN* ()
{
return plugin;
}
PLUGIN* operator -> ()
{
return plugin;
}
};
virtual const wxString& Name() = 0;
//-----<BOARD STUFF>----------------------------------------------------
/**
* Function Load
* loads a board file from some input file format that this implementation
* knows about.
*
* @param aFileName is the name of the file to load and may be foreign in
* nature or native in nature.
*
* @param aAppendToMe is an existing BOARD to append to but is often NULL
* meaning do not append.
*
* @param aProperties is an associative array that can be used to tell the
* loader how to load the file, because it can take any number of
* additional named arguments that the plugin is known to support.
*
* @return BOARD* - the successfully loaded board, and caller owns it.
*
* @throw IO_ERROR if there is a problem loading, and its contents should
* say what went wrong.
*/
virtual BOARD* Load( const wxString& aFileName, BOARD* aAppendToMe,
PROPERTIES* aProperties = NULL );
/**
* Function Save
* will write a full aBoard to a storage file in a format that only this
* implementation knows about. Or it can be used to write a portion of
* aBoard to a special kind of export file.
*
* @param aFileName is the name of a file to save to on disk.
* @param aBoard is the BOARD document (data tree) to save or export to disk.
*
* @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 arguments that the plugin is known to support.
*
* @throw IO_ERROR if there is a problem loading.
*/
virtual void Save( const wxString* aFileName, BOARD* aBoard,
PROPERTIES* aProperties = NULL );
//-----</BOARD STUFF>---------------------------------------------------
#if 0
///--------- Should split into two PLUGIN base types here, rather than being combined like this
//-----<SCHEMATIC STUFF>------------------------------------------------
/**
* Function Load
* loads a file from some special input file format that
* only this implementation knows about.
* @param aFileName is the name of the file to load and may be foreign in nature or native in nature.
* @param aAppendToMe is an existing SCHEMATIC to append to but may be NULL.
*/
virtual SCHEMATIC* Load( const wxString& aFileName, SCHEMATIC* aAppendToMe,
PROPERTIES* aProperties = NULL )
{
// not pure virtual so that plugins only have to implement
// Load() or Save() but not both.
}
/**
* Function Save
* will write aBoard to a storage file in a format that only this
* implementation knows about.
*
* @param aFileName is the name of a file to save to on disk.
*
* @param aBoard is the SCHEMATIC document (ram data tree) to save or export to disk.
*/
virtual void Save( const wxString* aFileName, SCHEMATIC* aSchematic,
PROPERTIES* aProperties = NULL )
{
// not pure virtual so that plugins only have to implement
// Load() or Save() but not both.
}
//-----</SCHEMATIC STUFF>----------------------------------------------
#endif
};
#endif // IO_MGR_H_
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 1992-2011 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/* This implements loading and saving a BOARD, behind the PLUGIN interface.
*/
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <kicad_plugin.h> // I implement this
#include <auto_ptr.h>
#include <kicad_string.h>
//#include <fctsys.h>
//#include <confirm.h>
//#include <build_version.h>
//#include <wxPcbStruct.h">
//#include <macros.h>
//#include <pcbcommon.h>
#include <zones.h>
#ifdef CVPCB
//#include <cvpcb.h>
#endif
#include <class_board.h>
#include <class_module.h>
#include <class_track.h>
#include <class_pcb_text.h>
#include <class_zone.h>
#include <class_dimension.h>
#include <class_drawsegment.h>
#include <class_mire.h>
#include <3d_struct.h>
/*
#include <pcbnew.h>
#include <pcbnew_id.h>
#include <autorout.h>
#include <pcb_plot_params.h>
*/
/* ASCII format of structures:
*
* Structure PAD:
*
* $PAD
* Sh "name" form DIMVA dimH dV dH East: general form dV, dH = delta size
* Dr. diam dV dH: drill: diameter drilling offsets
* At Type S / N layers: standard, cms, conn, hole, meca.,
* Stack / Normal, 32-bit hexadecimal: occupation layers
* Nm net_code netname
* Po posrefX posrefy: reFX position, Y (0 = east position / anchor)
* $EndPAD
*
* Module Structure
*
* $MODULE namelib
* Po ax ay east layer masquelayer m_TimeCode
* ax ay ord = anchor (position module)
* east = east to 0.1 degree
* layer = layer number
* masquelayer = silkscreen layer for
* m_TimeCode internal use (groups)
* Li <namelib>
*
* Cd <text> description of the component (Component Doc)
* Kw <text> List of key words
*
* Sc schematic timestamp, reference schematic
*
* Op rot90 rot180 placement Options Auto (court rot 90, 180)
* rot90 is about 2x4-bit:
* lsb = cost rot 90, rot court msb = -90;
*
* Tn px py DIMVA dimh East thickness mirror visible "text"
* n = type (0 = ref, val = 1,> 1 = qcq
* Texts POS x, y / anchor and orient module 0
* DIMVA dimh East
* mirror thickness (Normal / Mirror)
* Visible V / I
* DS ox oy fx fy w
* Edge: coord segment ox, oy has fx, fy, on
* was the anchor and orient 0
* thickness w
* DC ox oy fx fy w descr circle (center, 1 point, thickness)
* $PAD
* $EndPAD section pads if available
* $Endmodule
*/
#define MM_PER_BIU 1e-6
#define UM_PER_BIU 1e-3
using namespace std;
BOARD* KICAD_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe, PROPERTIES* aProperties )
{
wxString msg;
BOARD* board = aAppendToMe ? aAppendToMe : new BOARD( NULL );
// delete on exception, iff I own it, according to aAppendToMe
auto_ptr<BOARD> deleter( aAppendToMe ? NULL : board );
FILE* fp = wxFopen( aFileName, wxT( "rt" ) );
if( !fp )
{
msg.Printf( _( "Unable to open file '%s'" ), aFileName.GetData() );
THROW_IO_ERROR( msg );
}
FILE_LINE_READER reader( fp, aFileName );
aReader = &reader;
init( board, aProperties );
// Put a dollar sign in front, and test for a specific length of characters
// The -1 is to omit the trailing \0 which is included in sizeof() on a
// string.
#define TESTLINE( x ) (strncmp( line, "$" x, sizeof("$" x) - 1 ) == 0)
while( aReader->ReadLine() )
{
char* line = aReader->Line();
// put the more frequent ones at the top
if( TESTLINE( "MODULE" ) )
{
MODULE* module = new MODULE( board );
board->Add( module, ADD_APPEND );
load( module );
continue;
}
if( TESTLINE( "DRAWSEGMENT" ) )
{
DRAWSEGMENT* dseg = new DRAWSEGMENT( board );
board->Add( dseg, ADD_APPEND );
load( dseg );
continue;
}
if( TESTLINE( "EQUIPOT" ) )
{
NETINFO_ITEM* net = new NETINFO_ITEM( board );
board->m_NetInfo->AppendNet( net );
load( net );
continue;
}
if( TESTLINE( "TEXTPCB" ) )
{
TEXTE_PCB* pcbtxt = new TEXTE_PCB( board );
board->Add( pcbtxt, ADD_APPEND );
load( pcbtxt );
continue;
}
if( TESTLINE( "TRACK" ) )
{
#if 0 && defined(PCBNEW)
TRACK* insertBeforeMe = Append ? NULL : board->m_Track.GetFirst();
ReadListeSegmentDescr( aReader, insertBeforeMe, PCB_TRACE_T, NbTrack );
#endif
continue;
}
if( TESTLINE( BRD_NETCLASS ) )
{
/*
// create an empty NETCLASS without a name.
NETCLASS* netclass = new NETCLASS( board, wxEmptyString );
// fill it from the *.brd file, and establish its name.
netclass->ReadDescr( aReader );
if( !board->m_NetClasses.Add( netclass ) )
{
// Must have been a name conflict, this is a bad board file.
// User may have done a hand edit to the file.
// Delete netclass if board could not take ownership of it.
delete netclass;
// @todo: throw an exception here, this is a bad board file.
}
*/
continue;
}
if( TESTLINE( "CZONE_OUTLINE" ) )
{
auto_ptr<ZONE_CONTAINER> zone_descr( new ZONE_CONTAINER( board ) );
load( zone_descr.get() );
if( zone_descr->GetNumCorners() > 2 ) // should always occur
board->Add( zone_descr.release() );
// else delete zone_descr; done by auto_ptr
continue;
}
if( TESTLINE( "COTATION" ) )
{
DIMENSION* dim = new DIMENSION( board );
board->Add( dim, ADD_APPEND );
load( dim );
continue;
}
if( TESTLINE( "PCB_TARGET" ) )
{
PCB_TARGET* t = new PCB_TARGET( board );
board->Add( t, ADD_APPEND );
load( t );
continue;
}
if( TESTLINE( "ZONE" ) )
{
#if 0 && defined(PCBNEW)
SEGZONE* insertBeforeMe = Append ? NULL : board->m_Zone.GetFirst();
ReadListeSegmentDescr( aReader, insertBeforeMe, PCB_ZONE_T, NbZone );
#endif
continue;
}
if( TESTLINE( "GENERAL" ) )
{
loadGeneral( board );
continue;
}
if( TESTLINE( "SHEETDESCR" ) )
{
loadSheet( board );
continue;
}
if( TESTLINE( "SETUP" ) )
{
if( !aAppendToMe )
{
loadSetup( board );
}
else
{
while( aReader->ReadLine() )
{
line = aReader->Line();
if( TESTLINE( "EndSETUP" ) )
break;
}
}
continue;
}
if( TESTLINE( "EndPCB" ) )
break;
}
deleter.release(); // no exceptions possible between here and return
return board;
}
void KICAD_PLUGIN::load( MODULE* me )
{
char* line = aReader->Line();
char* text = line + 3;
S3D_MASTER* t3D = me->m_3D_Drawings;
if( !t3D->m_Shape3DName.IsEmpty() )
{
S3D_MASTER* n3D = new S3D_MASTER( me );
me->m_3D_Drawings.PushBack( n3D );
t3D = n3D;
}
while( aReader->ReadLine() )
{
line = aReader->Line();
switch( line[0] )
{
case '$':
if( line[1] == 'E' )
{
return 0;
}
return 1;
case 'N': // Shape File Name
{
char buf[512];
ReadDelimitedText( buf, text, 512 );
t3D->m_Shape3DName = FROM_UTF8( buf );
break;
}
case 'S': // Scale
sscanf( text, "%lf %lf %lf\n",
&t3D->m_MatScale.x,
&t3D->m_MatScale.y,
&t3D->m_MatScale.z );
break;
case 'O': // Offset
sscanf( text, "%lf %lf %lf\n",
&t3D->m_MatPosition.x,
&t3D->m_MatPosition.y,
&t3D->m_MatPosition.z );
break;
case 'R': // Rotation
sscanf( text, "%lf %lf %lf\n",
&t3D->m_MatRotation.x,
&t3D->m_MatRotation.y,
&t3D->m_MatRotation.z );
break;
default:
break;
}
}
}
std::string KICAD_PLUGIN::biuFmt( BIU aValue )
{
BFU engUnits = biuToDiskUnits * aValue;
char temp[48];
if( engUnits != 0.0 && fabsl( engUnits ) <= 0.0001 )
{
// printf( "f: " );
sprintf( temp, "%.10f", engUnits );
int len = strlen( temp );
while( --len > 0 && temp[len] == '0' )
temp[len] = '\0';
}
else
{
// printf( "g: " );
sprintf( temp, "%.10g", engUnits );
}
return temp;
}
void KICAD_PLUGIN::init( BOARD* aBoard, PROPERTIES* aProperties )
{
NbDraw = NbTrack = NbZone = NbMod = NbNets = -1;
aBoard->m_Status_Pcb = 0;
aBoard->m_NetClasses.Clear();
}
void KICAD_PLUGIN::Save( const wxString* aFileName, BOARD* aBoard, PROPERTIES* aProperties )
{
}
#ifndef KICAD_PLUGIN_H_
#define KICAD_PLUGIN_H_
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 1992-2011 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <io_mgr.h>
#include <string>
typedef int BIU;
typedef double BFU;
class PCB_TARGET;
class MODULE;
class DRAWSEGMENT;
class NETINFO;
class TEXTE_PCB;
class TRACK;
class NETCLASS;
class ZONE_CONTAINER;
class DIMENSION;
class NETINFO_ITEM;
class KICAD_PLUGIN : public PLUGIN
{
public:
//-----<PLUGIN>---------------------------------------------------------------------
BOARD* Load( const wxString& aFileName, BOARD* aAppendToMe, PROPERTIES* aProperties = NULL );
void Save( const wxString* aFileName, BOARD* aBoard, PROPERTIES* aProperties = NULL );
const wxString& Name()
{
static const wxString name = wxT( "KiCad" );
return name;
}
//-----</PLUGIN>--------------------------------------------------------------------
protected:
wxString m_Error; ///< for throwing exceptions
LINE_READER* m_Reader; ///< no ownership here.
/// initialize PLUGIN like a constructor would, and futz with fresh BOARD if needed.
void init( BOARD* board, PROPERTIES* aProperties );
int NbDraw;
int NbTrack;
int NbZone;
int NbMod;
int NbNets;
BFU biuToDisk; ///< convert from BIUs to disk engineering units with this scale factor
BFU diskToBiu; ///< convert from disk engineering units to BIUs with this scale factor
/// convert a BIU to engineering units by scaling and formatting to ASCII.
std::string biuFmt( BIU aValue );
// load / parse functions
void loadGeneral( BOARD* me );
void loadSetup( BOARD* me );
void loadSheet( BOARD* me );
void load( PCB_TARGET* me );
void load( MODULE* me );
void load( DRAWSEGMENT* me );
void load( NETINFO* me );
void load( TEXTE_PCB* me );
void load( TRACK* me );
void load( NETCLASS* me );
void load( ZONE_CONTAINER* me );
void load( DIMENSION* me );
void load( NETINFO_ITEM* me );
// void load( SEGZONE* me );
};
#endif // KICAD_PLUGIN_H_
...@@ -155,7 +155,7 @@ FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( wxWindow* father, ...@@ -155,7 +155,7 @@ FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( wxWindow* father,
UpdateTitle(); UpdateTitle();
if( g_ModuleEditor_Pcb == NULL ) if( g_ModuleEditor_Pcb == NULL )
g_ModuleEditor_Pcb = new BOARD( NULL, this ); g_ModuleEditor_Pcb = new BOARD( this );
SetBoard( g_ModuleEditor_Pcb ); SetBoard( g_ModuleEditor_Pcb );
GetBoard()->m_PcbFrame = this; GetBoard()->m_PcbFrame = this;
......
...@@ -283,7 +283,7 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( wxWindow* parent, const wxString& title, ...@@ -283,7 +283,7 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( wxWindow* parent, const wxString& title,
for ( int i = 0; i < 10; i++ ) for ( int i = 0; i < 10; i++ )
m_Macros[i].m_Record.clear(); m_Macros[i].m_Record.clear();
SetBoard( new BOARD( NULL, this ) ); SetBoard( new BOARD( this ) );
// Create the PCB_LAYER_WIDGET *after* SetBoard(): // Create the PCB_LAYER_WIDGET *after* SetBoard():
......
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