Commit 7c86749c authored by Wayne Stambaugh's avatar Wayne Stambaugh

Add Pcbnew GEDA PCB module plugin support.

* Create new GEDA PCB plug in.
* Add support for opening GEDA PCB footprints with module editor.
* Make import footprint file dialog remember last selected footprint
  type during current session.
* Update module editor file import to use new GEDA PCB plug in.
* Let IO_MGR know about GEDA PCB plug in.
* Create a WHITESPACE_FILTER_READER to simplify parsing GEDA PCB footprint
  files.
parent d2126baf
...@@ -121,6 +121,7 @@ set(PCB_COMMON_SRCS ...@@ -121,6 +121,7 @@ set(PCB_COMMON_SRCS
../pcbnew/eagle_plugin.cpp ../pcbnew/eagle_plugin.cpp
../pcbnew/legacy_plugin.cpp ../pcbnew/legacy_plugin.cpp
../pcbnew/kicad_plugin.cpp ../pcbnew/kicad_plugin.cpp
../pcbnew/gpcb_plugin.cpp
pcb_plot_params_keywords.cpp pcb_plot_params_keywords.cpp
pcb_keywords.cpp pcb_keywords.cpp
../pcbnew/pcb_parser.cpp ../pcbnew/pcb_parser.cpp
......
...@@ -65,3 +65,43 @@ char* FILTER_READER::ReadLine() throw( IO_ERROR ) ...@@ -65,3 +65,43 @@ char* FILTER_READER::ReadLine() throw( IO_ERROR )
return length ? line : NULL; return length ? line : NULL;
} }
WHITESPACE_FILTER_READER::WHITESPACE_FILTER_READER( LINE_READER& aReader ) :
LINE_READER( 1 ),
reader( aReader )
{
// Not using our own line buffer, will be using aReader's. This changes
// the meaning of this->line to be merely a pointer to aReader's line, which of course
// is not owned here.
delete [] line;
line = 0;
}
WHITESPACE_FILTER_READER::~WHITESPACE_FILTER_READER()
{
// Our 'line' points to aReader's, and he will delete that buffer.
// Prevent subsequent call to ~LINE_READER() from deleting a buffer we do not own.
line = 0;
}
char* WHITESPACE_FILTER_READER::ReadLine() throw( IO_ERROR )
{
char* s;
while( ( s = reader.ReadLine() ) != NULL )
{
while( s != NULL && strchr( " \t", *s ) )
s++;
if( s != NULL && !strchr( "#\n\r", *s ) )
break;
}
line = s;
length = reader.Length();
return length ? line : NULL;
}
...@@ -57,6 +57,7 @@ const wxString FootprintPlaceFileExtension( wxT( "pos" ) ); ...@@ -57,6 +57,7 @@ const wxString FootprintPlaceFileExtension( wxT( "pos" ) );
const wxString KiCadFootprintLibPathExtension( wxT( "pretty" ) ); ///< KICAD PLUGIN libpath const wxString KiCadFootprintLibPathExtension( wxT( "pretty" ) ); ///< KICAD PLUGIN libpath
const wxString KiCadFootprintFileExtension( wxT( "kicad_mod" ) ); const wxString KiCadFootprintFileExtension( wxT( "kicad_mod" ) );
const wxString GedaPcbFootprintLibFileExtension( wxT( "fp" ) );
// These strings are wildcards for file selection dialogs. // These strings are wildcards for file selection dialogs.
// Because these are static, one should explicitly call wxGetTranslation // Because these are static, one should explicitly call wxGetTranslation
...@@ -73,6 +74,7 @@ const wxString PcbFileWildcard( _( "KiCad s-expr printed circuit board files (*. ...@@ -73,6 +74,7 @@ const wxString PcbFileWildcard( _( "KiCad s-expr printed circuit board files (*.
const wxString KiCadFootprintLibFileWildcard( _( "KiCad footprint s-expre library file (*.kicad_mod)|*.kicad_mod" ) ); const wxString KiCadFootprintLibFileWildcard( _( "KiCad footprint s-expre library file (*.kicad_mod)|*.kicad_mod" ) );
const wxString KiCadFootprintLibPathWildcard( _( "KiCad footprint s-expre library path (*.pretty)|*.pretty" ) ); const wxString KiCadFootprintLibPathWildcard( _( "KiCad footprint s-expre library path (*.pretty)|*.pretty" ) );
const wxString LegacyFootprintLibPathWildcard( _( "Legacy footprint library file (*.mod)|*.mod" ) ); const wxString LegacyFootprintLibPathWildcard( _( "Legacy footprint library file (*.mod)|*.mod" ) );
const wxString GedaPcbFootprintLibFileWildcard( _( "Geda PCB footprint library file (*.fp)|*.fp" ) );
const wxString MacrosFileWildcard( _( "KiCad recorded macros (*.mcr)|*.mcr" ) ); const wxString MacrosFileWildcard( _( "KiCad recorded macros (*.mcr)|*.mcr" ) );
// generic: // generic:
......
...@@ -62,4 +62,38 @@ public: ...@@ -62,4 +62,38 @@ public:
} }
}; };
/**
* Class WHITESPACE_FILTER_READER
* reads lines of text from another LINE_READER, but only returns non-comment
* lines and non-blank lines with leading whitespace characters (space and tab)
* removed from its ReadLine() function.
*/
class WHITESPACE_FILTER_READER : public LINE_READER
{
LINE_READER& reader;
public:
/**
* Constructor ( LINE_READER& )
* does not take ownership over @a aReader, so will not destroy it.
*/
WHITESPACE_FILTER_READER( LINE_READER& aReader );
~WHITESPACE_FILTER_READER();
char* ReadLine() throw( IO_ERROR );
const wxString& GetSource() const
{
return reader.GetSource();
}
unsigned LineNumber() const
{
return reader.LineNumber();
}
};
#endif // FILTER_READER_H_ #endif // FILTER_READER_H_
...@@ -66,6 +66,7 @@ extern const wxString ReportFileExtension; ...@@ -66,6 +66,7 @@ extern const wxString ReportFileExtension;
extern const wxString FootprintPlaceFileExtension; extern const wxString FootprintPlaceFileExtension;
extern const wxString KiCadFootprintFileExtension; extern const wxString KiCadFootprintFileExtension;
extern const wxString KiCadFootprintLibPathExtension; extern const wxString KiCadFootprintLibPathExtension;
extern const wxString GedaPcbFootprintLibFileExtension;
/// Proper wxFileDialog wild card definitions. /// Proper wxFileDialog wild card definitions.
extern const wxString SchematicSymbolFileWildcard; extern const wxString SchematicSymbolFileWildcard;
...@@ -92,5 +93,6 @@ extern const wxString DocModulesFileName; ...@@ -92,5 +93,6 @@ extern const wxString DocModulesFileName;
extern const wxString LegacyFootprintLibPathWildcard; extern const wxString LegacyFootprintLibPathWildcard;
extern const wxString KiCadFootprintLibFileWildcard; extern const wxString KiCadFootprintLibFileWildcard;
extern const wxString KiCadFootprintLibPathWildcard; extern const wxString KiCadFootprintLibPathWildcard;
extern const wxString GedaPcbFootprintLibFileWildcard;
#endif // INCLUDE_WILDCARDS_AND_FILES_EXT_H_ #endif // INCLUDE_WILDCARDS_AND_FILES_EXT_H_
...@@ -265,31 +265,34 @@ void DRAWSEGMENT::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE draw_mode, ...@@ -265,31 +265,34 @@ void DRAWSEGMENT::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE draw_mode,
radius, m_Width, color ); radius, m_Width, color );
} }
break; break;
case S_CURVE: case S_CURVE:
m_BezierPoints = Bezier2Poly(m_Start, m_BezierC1, m_BezierC2, m_End); m_BezierPoints = Bezier2Poly(m_Start, m_BezierC1, m_BezierC2, m_End);
for (unsigned int i=1; i < m_BezierPoints.size(); i++) { for (unsigned int i=1; i < m_BezierPoints.size(); i++) {
if( mode == LINE ) if( mode == LINE )
GRLine( panel->GetClipBox(), DC, GRLine( panel->GetClipBox(), DC,
m_BezierPoints[i].x, m_BezierPoints[i].y, m_BezierPoints[i].x, m_BezierPoints[i].y,
m_BezierPoints[i-1].x, m_BezierPoints[i-1].y, 0, m_BezierPoints[i-1].x, m_BezierPoints[i-1].y, 0,
color ); color );
else if( mode == SKETCH ) else if( mode == SKETCH )
{ {
GRCSegm( panel->GetClipBox(), DC, GRCSegm( panel->GetClipBox(), DC,
m_BezierPoints[i].x, m_BezierPoints[i].y,
m_BezierPoints[i-1].x, m_BezierPoints[i-1].y,
m_Width, color );
}
else
{
GRFillCSegm( panel->GetClipBox(), DC,
m_BezierPoints[i].x, m_BezierPoints[i].y, m_BezierPoints[i].x, m_BezierPoints[i].y,
m_BezierPoints[i-1].x, m_BezierPoints[i-1].y, m_BezierPoints[i-1].x, m_BezierPoints[i-1].y,
m_Width, color ); m_Width, color );
}
else
{
GRFillCSegm( panel->GetClipBox(), DC,
m_BezierPoints[i].x, m_BezierPoints[i].y,
m_BezierPoints[i-1].x, m_BezierPoints[i-1].y,
m_Width, color );
}
} }
break; }
break;
default: default:
if( mode == LINE ) if( mode == LINE )
{ {
......
This diff is collapsed.
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 1992-2012 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
*/
/**
* @file gpcb_plugin.cpp
* @brief Geda PCB file plugin definition file.
*/
#ifndef _GPCB_PLUGIN_H_
#define _GPCB_PLUGIN_H_
#include <io_mgr.h>
#include <string>
class GPCB_FPL_CACHE;
/**
* Class GPCB_PLUGIN
* is a PLUGIN derivation for saving and loading Geda PCB files.
*
* @note This class is not thread safe, but it is re-entrant multiple times in sequence.
* @note Currently only reading GPCB footprint files is implemented.
*/
class GPCB_PLUGIN : public PLUGIN
{
friend class GPCB_FPL_CACHE;
public:
//-----<PLUGIN API>---------------------------------------------------------
const wxString& PluginName() const
{
static const wxString name = wxT( "Geda PCB" );
return name;
}
const wxString& GetFileExtension() const
{
static const wxString extension = wxT( "fp" );
return extension;
}
wxArrayString FootprintEnumerate( const wxString& aLibraryPath, PROPERTIES* aProperties = NULL);
MODULE* FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName,
PROPERTIES* aProperties = NULL );
void FootprintDelete( const wxString& aLibraryPath, const wxString& aFootprintName );
bool FootprintLibDelete( const wxString& aLibraryPath, PROPERTIES* aProperties = NULL );
bool IsFootprintLibWritable( const wxString& aLibraryPath );
//-----</PLUGIN API>--------------------------------------------------------
GPCB_PLUGIN();
GPCB_PLUGIN( int aControlFlags );
~GPCB_PLUGIN();
protected:
wxString m_error; ///< for throwing exceptions
PROPERTIES* m_props; ///< passed via Save() or Load(), no ownership, may be NULL.
GPCB_FPL_CACHE* m_cache; ///< Footprint library cache.
int m_ctl;
LINE_READER* m_reader; ///< no ownership here.
wxString m_filename; ///< for saves only, name is in m_reader for loads
private:
/// we only cache one footprint library for now, this determines which one.
void cacheLib( const wxString& aLibraryPath );
void init( PROPERTIES* aProperties );
};
#endif // _GPCB_PLUGIN_H_
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <legacy_plugin.h> #include <legacy_plugin.h>
#include <kicad_plugin.h> #include <kicad_plugin.h>
#include <eagle_plugin.h> #include <eagle_plugin.h>
#include <gpcb_plugin.h>
#include <wildcards_and_files_ext.h> #include <wildcards_and_files_ext.h>
#define FMT_UNIMPLEMENTED _( "Plugin '%s' does not implement the '%s' function." ) #define FMT_UNIMPLEMENTED _( "Plugin '%s' does not implement the '%s' function." )
...@@ -64,6 +65,9 @@ PLUGIN* IO_MGR::PluginFind( PCB_FILE_T aFileType ) ...@@ -64,6 +65,9 @@ PLUGIN* IO_MGR::PluginFind( PCB_FILE_T aFileType )
case EAGLE: case EAGLE:
return new EAGLE_PLUGIN(); return new EAGLE_PLUGIN();
case GEDA_PCB:
return new GPCB_PLUGIN();
} }
return NULL; return NULL;
...@@ -99,6 +103,9 @@ const wxString IO_MGR::ShowType( PCB_FILE_T aType ) ...@@ -99,6 +103,9 @@ const wxString IO_MGR::ShowType( PCB_FILE_T aType )
case EAGLE: case EAGLE:
return wxString( wxT( "Eagle" ) ); return wxString( wxT( "Eagle" ) );
case GEDA_PCB:
return wxString( wxT( "Geda-PCB" ) );
} }
} }
...@@ -118,6 +125,9 @@ IO_MGR::PCB_FILE_T IO_MGR::EnumFromStr( const wxString& aType ) ...@@ -118,6 +125,9 @@ IO_MGR::PCB_FILE_T IO_MGR::EnumFromStr( const wxString& aType )
if( aType == wxT( "Eagle" ) ) if( aType == wxT( "Eagle" ) )
return EAGLE; return EAGLE;
if( aType == wxT( "Geda-PCB" ) )
return GEDA_PCB;
// wxASSERT( blow up here ) // wxASSERT( blow up here )
return PCB_FILE_T( -1 ); return PCB_FILE_T( -1 );
...@@ -145,7 +155,13 @@ IO_MGR::PCB_FILE_T IO_MGR::GuessPluginTypeFromLibPath( const wxString& aLibPath ...@@ -145,7 +155,13 @@ IO_MGR::PCB_FILE_T IO_MGR::GuessPluginTypeFromLibPath( const wxString& aLibPath
PCB_FILE_T ret; PCB_FILE_T ret;
if( fn.GetExt() == LegacyFootprintLibPathExtension ) if( fn.GetExt() == LegacyFootprintLibPathExtension )
{
ret = LEGACY; ret = LEGACY;
}
else if( fn.GetExt() == GedaPcbFootprintLibFileExtension )
{
ret = GEDA_PCB;
}
else else
{ {
// Although KICAD PLUGIN uses libpaths with fixed extension of // Although KICAD PLUGIN uses libpaths with fixed extension of
......
...@@ -51,7 +51,7 @@ public: ...@@ -51,7 +51,7 @@ public:
LEGACY, //< Legacy Pcbnew file formats prior to s-expression. LEGACY, //< Legacy Pcbnew file formats prior to s-expression.
KICAD, //< S-expression Pcbnew file format. KICAD, //< S-expression Pcbnew file format.
EAGLE, EAGLE,
GEDA_PCB, //< Geda PCB file formats.
// add your type here. // add your type here.
// ALTIUM, // ALTIUM,
...@@ -272,7 +272,8 @@ public: ...@@ -272,7 +272,8 @@ public:
* *
* @throw IO_ERROR if the library cannot be found, or footprint cannot be loaded. * @throw IO_ERROR if the library cannot be found, or footprint cannot be loaded.
*/ */
virtual wxArrayString FootprintEnumerate( const wxString& aLibraryPath, PROPERTIES* aProperties = NULL); virtual wxArrayString FootprintEnumerate( const wxString& aLibraryPath,
PROPERTIES* aProperties = NULL);
/** /**
* Function FootprintLoad * Function FootprintLoad
......
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 1992-2012 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
*/
/** /**
* @file librairi.cpp * @file librairi.cpp
* @brief Manage module (footprint) libraries. * @brief Manage module (footprint) libraries.
...@@ -69,8 +93,10 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module() ...@@ -69,8 +93,10 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module()
{ {
// use the clipboard for this in the future? // use the clipboard for this in the future?
wxString lastOpenedPathForLoading; // Some day it might be useful save the last library type selected aong with the path.
wxConfig* config = wxGetApp().GetSettings(); static int lastFilterIndex = 0;
wxString lastOpenedPathForLoading;
wxConfig* config = wxGetApp().GetSettings();
if( config ) if( config )
config->Read( EXPORT_IMPORT_LASTPATH_KEY, &lastOpenedPathForLoading ); config->Read( EXPORT_IMPORT_LASTPATH_KEY, &lastOpenedPathForLoading );
...@@ -78,17 +104,22 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module() ...@@ -78,17 +104,22 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module()
wxString wildCard; wxString wildCard;
wildCard << wxGetTranslation( KiCadFootprintLibFileWildcard ) << wxChar( '|' ) wildCard << wxGetTranslation( KiCadFootprintLibFileWildcard ) << wxChar( '|' )
<< wxGetTranslation( ModExportFileWildcard ) << wxChar( '|' ) << wxGetTranslation( ModExportFileWildcard ) << wxChar( '|' )
<< wxGetTranslation( ModImportFileWildcard ); << wxGetTranslation( ModImportFileWildcard ) << wxChar( '|' )
<< wxGetTranslation( GedaPcbFootprintLibFileWildcard );
wxFileDialog dlg( this, FMT_IMPORT_MODULE, wxFileDialog dlg( this, FMT_IMPORT_MODULE,
lastOpenedPathForLoading, wxEmptyString, lastOpenedPathForLoading, wxEmptyString,
wildCard, wxFD_OPEN | wxFD_FILE_MUST_EXIST ); wildCard, wxFD_OPEN | wxFD_FILE_MUST_EXIST );
dlg.SetFilterIndex( lastFilterIndex );
if( dlg.ShowModal() == wxID_CANCEL ) if( dlg.ShowModal() == wxID_CANCEL )
return NULL; return NULL;
lastFilterIndex = dlg.GetFilterIndex();
FILE* fp = wxFopen( dlg.GetPath(), wxT( "rt" ) ); FILE* fp = wxFopen( dlg.GetPath(), wxT( "rt" ) );
if( !fp ) if( !fp )
{ {
wxString msg = wxString::Format( FMT_FILE_NOT_FOUND, GetChars( dlg.GetPath() ) ); wxString msg = wxString::Format( FMT_FILE_NOT_FOUND, GetChars( dlg.GetPath() ) );
...@@ -104,12 +135,12 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module() ...@@ -104,12 +135,12 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module()
wxString moduleName; wxString moduleName;
bool isGeda = false; bool isGeda = false;
bool isLegacy = false; bool isLegacy = false;
{ {
FILE_LINE_READER freader( fp, dlg.GetPath() ); // I own fp, and will close it. FILE_LINE_READER freader( fp, dlg.GetPath() ); // I own fp, and will close it.
FILTER_READER reader( freader ); // skip blank lines WHITESPACE_FILTER_READER reader( freader ); // skip blank lines
reader.ReadLine(); reader.ReadLine();
char* line = reader.Line(); char* line = reader.Line();
...@@ -148,11 +179,28 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module() ...@@ -148,11 +179,28 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module()
if( isGeda ) if( isGeda )
{ {
LOCALE_IO toggle; try
{
wxFileName fn = dlg.GetPath();
PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::GEDA_PCB ) );
moduleName = fn.GetName();
module = pi->FootprintLoad( fn.GetPath(), moduleName );
if( !module )
{
wxString msg = wxString::Format(
FMT_MOD_NOT_FOUND, GetChars( moduleName ), GetChars( fn.GetPath() ) );
// @todo GEDA plugin DisplayError( this, msg );
module = new MODULE( GetBoard() ); return NULL;
module->Read_GPCB_Descr( dlg.GetPath() ); }
}
catch( IO_ERROR ioe )
{
DisplayError( this, ioe.errorText );
return NULL;
}
} }
else if( isLegacy ) else if( isLegacy )
{ {
......
/* /*
* 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.
* *
...@@ -76,7 +77,7 @@ void FOOTPRINT_EDIT_FRAME::ReCreateMenuBar() ...@@ -76,7 +77,7 @@ void FOOTPRINT_EDIT_FRAME::ReCreateMenuBar()
// from File // from File
AddMenuItem( openSubmenu, ID_MODEDIT_IMPORT_PART, AddMenuItem( openSubmenu, ID_MODEDIT_IMPORT_PART,
_( "Import Module from File (&Import)" ), _( "&Import Module from File" ),
_( "Import a footprint from an existing file" ), _( "Import a footprint from an existing file" ),
KiBitmap( import_module_xpm ) ); KiBitmap( import_module_xpm ) );
......
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