diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 8828872179..c2ce304c3d 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -4,6 +4,14 @@ KiCad ChangeLog 2010 Please add newer entries at the top, list the date and your name with email address. + +2011-Nov-27 UPDATE Dick Hollenbeck +================================================================================ + PCBNew + * Add PLUGIN and IO_MGR classes. + * Remove one argument from BOARD constructor, + * add BOARD::SetWindowFrame() + 2011-sept-13 UPDATE Wayne Stambaugh ================================================================================ PCBNew locate code refactoring. diff --git a/Documentation/biu-plan.txt b/Documentation/biu-plan.txt index 3f7ad9f554..6fe9267840 100644 --- a/Documentation/biu-plan.txt +++ b/Documentation/biu-plan.txt @@ -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, 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: =========== @@ -97,10 +89,10 @@ then FMT_ENG will be set to "%.6Lg". For example: #if USE_DOUBLE_BFU typedef double BFU; -#define FMT_ENG ".%6g" +#define FMT_ENG ".%10g" #else typedef long double BFU; -#define FMT_ENG ".%6Lg" +#define FMT_ENG ".%10Lg" #endif 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: 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 -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. 3) mm to nanometer loader. This loader uses a floating point scaling factor diff --git a/copyright.h b/copyright.h index 68b8cfce73..525f06343d 100644 --- a/copyright.h +++ b/copyright.h @@ -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 - * Copyright (C) 1992-2011 Kicad Developers, see change_log.txt for contributors. + * Copyright (C) 2011 + * 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 diff --git a/cvpcb/class_DisplayFootprintsFrame.cpp b/cvpcb/class_DisplayFootprintsFrame.cpp index c2c5b58fd6..af18f7f812 100644 --- a/cvpcb/class_DisplayFootprintsFrame.cpp +++ b/cvpcb/class_DisplayFootprintsFrame.cpp @@ -61,7 +61,7 @@ DISPLAY_FOOTPRINTS_FRAME::DISPLAY_FOOTPRINTS_FRAME( CVPCB_MAINFRAME* father, icon.CopyFromBitmap( KiBitmap( icon_cvpcb_xpm ) ); SetIcon( icon ); - SetBoard( new BOARD( NULL, this ) ); + SetBoard( new BOARD( this ) ); SetScreen( new PCB_SCREEN() ); LoadSettings(); diff --git a/gerbview/export_to_pcbnew.cpp b/gerbview/export_to_pcbnew.cpp index 3e73aa9412..f86dd0d51a 100644 --- a/gerbview/export_to_pcbnew.cpp +++ b/gerbview/export_to_pcbnew.cpp @@ -51,7 +51,7 @@ GBR_TO_PCB_EXPORTER::GBR_TO_PCB_EXPORTER( GERBVIEW_FRAME * aFrame, FILE * aFile { m_gerbview_frame = aFrame; m_file = aFile; - m_pcb = new BOARD( NULL, m_gerbview_frame ); + m_pcb = new BOARD( m_gerbview_frame ); } diff --git a/gerbview/gerbview_frame.cpp b/gerbview/gerbview_frame.cpp index 69e55a4cb8..e1069b5e70 100644 --- a/gerbview/gerbview_frame.cpp +++ b/gerbview/gerbview_frame.cpp @@ -61,7 +61,7 @@ GERBVIEW_FRAME::GERBVIEW_FRAME( wxWindow* father, SetScreen( new PCB_SCREEN() ); 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()->SetVisibleLayers( FULL_LAYERS ); // All 32 layers visible. diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index ca05e4661f..3bc63971f7 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -126,7 +126,9 @@ set(PCBNEW_SRCS hotkeys_board_editor.cpp hotkeys_module_editor.cpp initpcb.cpp +# io_mgr.cpp ioascii.cpp +# kicad_plugin.cpp layer_widget.cpp librairi.cpp loadcmp.cpp diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index 1810ed99c2..99f631c919 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -32,14 +32,14 @@ BOARD_DESIGN_SETTINGS boardDesignSettings; -BOARD::BOARD( EDA_ITEM* parent, PCB_BASE_FRAME* frame ) : - BOARD_ITEM( (BOARD_ITEM*)parent, PCB_T ), +BOARD::BOARD( PCB_BASE_FRAME* frame ) : + BOARD_ITEM( (BOARD_ITEM*) NULL, PCB_T ), m_NetClasses( this ) { m_PcbFrame = frame; m_Status_Pcb = 0; // Status word: bit 1 = calculate. - SetBoardDesignSettings(&boardDesignSettings); - SetColorsSettings(&g_ColorsSettings); + SetBoardDesignSettings( &boardDesignSettings ); + SetColorsSettings( &g_ColorsSettings ); m_NbNodes = 0; // Number of connected pads. m_NbNoconnect = 0; // Number of unconnected nets. diff --git a/pcbnew/class_board.h b/pcbnew/class_board.h index 0baf68968e..6f760e3af8 100644 --- a/pcbnew/class_board.h +++ b/pcbnew/class_board.h @@ -161,6 +161,12 @@ private: public: 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 /// Flags used in ratsnest calculation and update. @@ -231,7 +237,7 @@ private: void chainMarkedSegments( wxPoint aPosition, int aLayerMask, TRACK_PTRS* aList ); public: - BOARD( EDA_ITEM* aParent, PCB_BASE_FRAME* frame ); + BOARD( PCB_BASE_FRAME* frame ); ~BOARD(); /** diff --git a/pcbnew/initpcb.cpp b/pcbnew/initpcb.cpp index e3b6bca0a2..46ada35de5 100644 --- a/pcbnew/initpcb.cpp +++ b/pcbnew/initpcb.cpp @@ -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 // layer names are put into the BOARD. - SetBoard( new BOARD( NULL, this ) ); + SetBoard( new BOARD( this ) ); SetCurItem( NULL ); /* clear filename, to avoid overwriting an old file */ diff --git a/pcbnew/io_mgr.cpp b/pcbnew/io_mgr.cpp new file mode 100644 index 0000000000..61e6c02f48 --- /dev/null +++ b/pcbnew/io_mgr.cpp @@ -0,0 +1,125 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2011 SoftPLC Corporation, Dick Hollenbeck + * 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 +#include + + +// 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 ); +} + diff --git a/pcbnew/io_mgr.h b/pcbnew/io_mgr.h new file mode 100644 index 0000000000..abe98cda55 --- /dev/null +++ b/pcbnew/io_mgr.h @@ -0,0 +1,267 @@ +#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 + * 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 +#include +#include + + +// 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. + * + *
+ *
+ *   // 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
+ *
+ * 
+ */ +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; + + //--------------------------------------------------------- + + /** + * 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 ); + + //-------------------------------------------------------- + +#if 0 + ///--------- Should split into two PLUGIN base types here, rather than being combined like this + + //----------------------------------------------------- + + /** + * 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. + } + + //--------------------------------------------------- +#endif +}; + +#endif // IO_MGR_H_ + diff --git a/pcbnew/kicad_plugin.cpp b/pcbnew/kicad_plugin.cpp new file mode 100644 index 0000000000..d66ef3d676 --- /dev/null +++ b/pcbnew/kicad_plugin.cpp @@ -0,0 +1,408 @@ + +/* + * 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 +#include +#include + +#include // I implement this + +#include +#include + + +//#include +//#include +//#include +//#include +//#include +//#include + +#include + +#ifdef CVPCB +//#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include <3d_struct.h> + + +/* +#include +#include +#include +#include +*/ + + +/* 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 + * + * Cd description of the component (Component Doc) + * Kw 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 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_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 ) +{ + + + +} + diff --git a/pcbnew/kicad_plugin.h b/pcbnew/kicad_plugin.h new file mode 100644 index 0000000000..f9bc0e7360 --- /dev/null +++ b/pcbnew/kicad_plugin.h @@ -0,0 +1,105 @@ +#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 +#include + +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: + + //-------------------------------------------------------------------------- + + 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; + } + + //------------------------------------------------------------------------- + +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_ diff --git a/pcbnew/moduleframe.cpp b/pcbnew/moduleframe.cpp index f4011f01ae..c650c10873 100644 --- a/pcbnew/moduleframe.cpp +++ b/pcbnew/moduleframe.cpp @@ -155,7 +155,7 @@ FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( wxWindow* father, UpdateTitle(); if( g_ModuleEditor_Pcb == NULL ) - g_ModuleEditor_Pcb = new BOARD( NULL, this ); + g_ModuleEditor_Pcb = new BOARD( this ); SetBoard( g_ModuleEditor_Pcb ); GetBoard()->m_PcbFrame = this; diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 8490e6c779..a2d986e6a1 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -283,7 +283,7 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( wxWindow* parent, const wxString& title, for ( int i = 0; i < 10; i++ ) m_Macros[i].m_Record.clear(); - SetBoard( new BOARD( NULL, this ) ); + SetBoard( new BOARD( this ) ); // Create the PCB_LAYER_WIDGET *after* SetBoard():