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
../pcbnew/eagle_plugin.cpp
../pcbnew/legacy_plugin.cpp
../pcbnew/kicad_plugin.cpp
../pcbnew/gpcb_plugin.cpp
pcb_plot_params_keywords.cpp
pcb_keywords.cpp
../pcbnew/pcb_parser.cpp
......
......@@ -65,3 +65,43 @@ char* FILTER_READER::ReadLine() throw( IO_ERROR )
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" ) );
const wxString KiCadFootprintLibPathExtension( wxT( "pretty" ) ); ///< KICAD PLUGIN libpath
const wxString KiCadFootprintFileExtension( wxT( "kicad_mod" ) );
const wxString GedaPcbFootprintLibFileExtension( wxT( "fp" ) );
// These strings are wildcards for file selection dialogs.
// Because these are static, one should explicitly call wxGetTranslation
......@@ -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 KiCadFootprintLibPathWildcard( _( "KiCad footprint s-expre library path (*.pretty)|*.pretty" ) );
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" ) );
// generic:
......
......@@ -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_
......@@ -66,6 +66,7 @@ extern const wxString ReportFileExtension;
extern const wxString FootprintPlaceFileExtension;
extern const wxString KiCadFootprintFileExtension;
extern const wxString KiCadFootprintLibPathExtension;
extern const wxString GedaPcbFootprintLibFileExtension;
/// Proper wxFileDialog wild card definitions.
extern const wxString SchematicSymbolFileWildcard;
......@@ -92,5 +93,6 @@ extern const wxString DocModulesFileName;
extern const wxString LegacyFootprintLibPathWildcard;
extern const wxString KiCadFootprintLibFileWildcard;
extern const wxString KiCadFootprintLibPathWildcard;
extern const wxString GedaPcbFootprintLibFileWildcard;
#endif // INCLUDE_WILDCARDS_AND_FILES_EXT_H_
......@@ -265,31 +265,34 @@ void DRAWSEGMENT::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE draw_mode,
radius, m_Width, color );
}
break;
case S_CURVE:
m_BezierPoints = Bezier2Poly(m_Start, m_BezierC1, m_BezierC2, m_End);
for (unsigned int i=1; i < m_BezierPoints.size(); i++) {
if( mode == LINE )
GRLine( panel->GetClipBox(), DC,
m_BezierPoints[i].x, m_BezierPoints[i].y,
m_BezierPoints[i-1].x, m_BezierPoints[i-1].y, 0,
color );
else if( mode == SKETCH )
{
GRCSegm( panel->GetClipBox(), DC,
m_BezierPoints = Bezier2Poly(m_Start, m_BezierC1, m_BezierC2, m_End);
for (unsigned int i=1; i < m_BezierPoints.size(); i++) {
if( mode == LINE )
GRLine( panel->GetClipBox(), DC,
m_BezierPoints[i].x, m_BezierPoints[i].y,
m_BezierPoints[i-1].x, m_BezierPoints[i-1].y, 0,
color );
else if( mode == SKETCH )
{
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-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-1].x, m_BezierPoints[i-1].y,
m_Width, color );
}
}
break;
}
break;
default:
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 @@
#include <legacy_plugin.h>
#include <kicad_plugin.h>
#include <eagle_plugin.h>
#include <gpcb_plugin.h>
#include <wildcards_and_files_ext.h>
#define FMT_UNIMPLEMENTED _( "Plugin '%s' does not implement the '%s' function." )
......@@ -64,6 +65,9 @@ PLUGIN* IO_MGR::PluginFind( PCB_FILE_T aFileType )
case EAGLE:
return new EAGLE_PLUGIN();
case GEDA_PCB:
return new GPCB_PLUGIN();
}
return NULL;
......@@ -99,6 +103,9 @@ const wxString IO_MGR::ShowType( PCB_FILE_T aType )
case 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 )
if( aType == wxT( "Eagle" ) )
return EAGLE;
if( aType == wxT( "Geda-PCB" ) )
return GEDA_PCB;
// wxASSERT( blow up here )
return PCB_FILE_T( -1 );
......@@ -145,7 +155,13 @@ IO_MGR::PCB_FILE_T IO_MGR::GuessPluginTypeFromLibPath( const wxString& aLibPath
PCB_FILE_T ret;
if( fn.GetExt() == LegacyFootprintLibPathExtension )
{
ret = LEGACY;
}
else if( fn.GetExt() == GedaPcbFootprintLibFileExtension )
{
ret = GEDA_PCB;
}
else
{
// Although KICAD PLUGIN uses libpaths with fixed extension of
......
......@@ -51,7 +51,7 @@ public:
LEGACY, //< Legacy Pcbnew file formats prior to s-expression.
KICAD, //< S-expression Pcbnew file format.
EAGLE,
GEDA_PCB, //< Geda PCB file formats.
// add your type here.
// ALTIUM,
......@@ -272,7 +272,8 @@ public:
*
* @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
......
/*
* 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
* @brief Manage module (footprint) libraries.
......@@ -69,8 +93,10 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module()
{
// use the clipboard for this in the future?
wxString lastOpenedPathForLoading;
wxConfig* config = wxGetApp().GetSettings();
// Some day it might be useful save the last library type selected aong with the path.
static int lastFilterIndex = 0;
wxString lastOpenedPathForLoading;
wxConfig* config = wxGetApp().GetSettings();
if( config )
config->Read( EXPORT_IMPORT_LASTPATH_KEY, &lastOpenedPathForLoading );
......@@ -78,17 +104,22 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module()
wxString wildCard;
wildCard << wxGetTranslation( KiCadFootprintLibFileWildcard ) << wxChar( '|' )
<< wxGetTranslation( ModExportFileWildcard ) << wxChar( '|' )
<< wxGetTranslation( ModImportFileWildcard );
<< wxGetTranslation( ModExportFileWildcard ) << wxChar( '|' )
<< wxGetTranslation( ModImportFileWildcard ) << wxChar( '|' )
<< wxGetTranslation( GedaPcbFootprintLibFileWildcard );
wxFileDialog dlg( this, FMT_IMPORT_MODULE,
lastOpenedPathForLoading, wxEmptyString,
wildCard, wxFD_OPEN | wxFD_FILE_MUST_EXIST );
dlg.SetFilterIndex( lastFilterIndex );
if( dlg.ShowModal() == wxID_CANCEL )
return NULL;
lastFilterIndex = dlg.GetFilterIndex();
FILE* fp = wxFopen( dlg.GetPath(), wxT( "rt" ) );
if( !fp )
{
wxString msg = wxString::Format( FMT_FILE_NOT_FOUND, GetChars( dlg.GetPath() ) );
......@@ -104,12 +135,12 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module()
wxString moduleName;
bool isGeda = false;
bool isLegacy = false;
bool isGeda = false;
bool isLegacy = false;
{
FILE_LINE_READER freader( fp, dlg.GetPath() ); // I own fp, and will close it.
FILTER_READER reader( freader ); // skip blank lines
FILE_LINE_READER freader( fp, dlg.GetPath() ); // I own fp, and will close it.
WHITESPACE_FILTER_READER reader( freader ); // skip blank lines
reader.ReadLine();
char* line = reader.Line();
......@@ -148,11 +179,28 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module()
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
module = new MODULE( GetBoard() );
module->Read_GPCB_Descr( dlg.GetPath() );
DisplayError( this, msg );
return NULL;
}
}
catch( IO_ERROR ioe )
{
DisplayError( this, ioe.errorText );
return NULL;
}
}
else if( isLegacy )
{
......
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
......@@ -76,7 +77,7 @@ void FOOTPRINT_EDIT_FRAME::ReCreateMenuBar()
// from File
AddMenuItem( openSubmenu, ID_MODEDIT_IMPORT_PART,
_( "Import Module from File (&Import)" ),
_( "&Import Module from File" ),
_( "Import a footprint from an existing file" ),
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