Pcbnew s-experssion footprint library implementation.
* Add footprint methods to PCB_IO. * Add FP_CACHE and FP_CACHE_ITEM for handling new footprint library design. * Add code to save legacy libraries in new format. * Change behavior of BOARD_ITEM::GetLayerName() to return the default layer name when the item does not have a BOARD as a parent. * Minor changes to the module output formatter when writing to module library files (no BOARD as parent). * Add new (and some that I forgot along the way) CMake flags to EDA_BASE_FRAME::CopyVersionInfoToClipboard(). * Add -Wno-narrowing to GCC flags to stop GCC 4.7 from complaining about a conversion from int to unsigned in the Boost polygon library. * Add INPUT_STREAM_READER to richio.cpp to allow using any object derived from wxInputStream as a LINE_READER (needs to be validated).
This commit is contained in:
parent
8031e512e6
commit
1468a4ae31
|
@ -21,11 +21,14 @@ set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMakeModules)
|
|||
#
|
||||
|
||||
option(USE_PCBNEW_SEXPR_FILE_FORMAT
|
||||
"Use s-expression Pcbnew file format support (default OFF)." )
|
||||
"Use Pcbnew s-expression file format support (default OFF)." )
|
||||
|
||||
option(USE_PCBNEW_NANOMETRES
|
||||
"Use nanometers for Pcbnew internal units instead of deci-mils (default OFF).")
|
||||
|
||||
option(USE_PCBNEW_SEXPR_FOOTPRINT_LIBS
|
||||
"Use Pcbnew s-expression footprint library format (default OFF).")
|
||||
|
||||
# Russian GOST patch
|
||||
option(wxUSE_UNICODE "enable/disable building unicode (default OFF)")
|
||||
option(KICAD_GOST "enable/disable building using GOST notation for multiple gates per package (default OFF)")
|
||||
|
@ -100,15 +103,20 @@ endif( USE_PCBNEW_SEXPR_FILE_FORMAT AND NOT USE_PCBNEW_NANOMETRES )
|
|||
#================================================
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
# Added -Wno-narrowing on 10/7/12 to prevent a huge number of warnings when
|
||||
# compiling with GCC 4.7. This appears to be caused by and int to unsigned
|
||||
# conversion in the Boost polygon library. At some point in the future when
|
||||
# Boost is updated to the next version, -Wno-narrowing should be removed to
|
||||
# see if the problem has been resolved. Wayne.
|
||||
if(WIN32) # under Windows/mingw, -fPIC option is enabled by default
|
||||
# Set default flags for Release build.
|
||||
set(CMAKE_C_FLAGS_RELEASE "-Wall -O2 -DNDEBUG")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-Wall -O2 -DNDEBUG")
|
||||
set(CMAKE_C_FLAGS_RELEASE "-Wall -Wno-narrowing -O2 -DNDEBUG")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-Wall -Wno-narrowing -O2 -DNDEBUG")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "-s")
|
||||
|
||||
# Set default flags for Debug build.
|
||||
set(CMAKE_C_FLAGS_DEBUG "-Wall -g3 -ggdb3 -DDEBUG")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-Wall -g3 -ggdb3 -DDEBUG")
|
||||
set(CMAKE_C_FLAGS_DEBUG "-Wall -Wno-narrowing -g3 -ggdb3 -DDEBUG")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-Wall -Wno-narrowing -g3 -ggdb3 -DDEBUG")
|
||||
else(WIN32)
|
||||
# Set default flags for Release build.
|
||||
set(CMAKE_C_FLAGS_RELEASE "-Wall -O2 -DNDEBUG -fPIC")
|
||||
|
@ -116,8 +124,8 @@ if(CMAKE_COMPILER_IS_GNUCXX)
|
|||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "-s")
|
||||
|
||||
# Set default flags for Debug build.
|
||||
set(CMAKE_C_FLAGS_DEBUG "-Wall -g3 -ggdb3 -DDEBUG -fPIC")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-Wall -g3 -ggdb3 -DDEBUG -fPIC")
|
||||
set(CMAKE_C_FLAGS_DEBUG "-Wall -Wno-narrowing -g3 -ggdb3 -DDEBUG -fPIC")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-Wall -Wno-narrowing -g3 -ggdb3 -DDEBUG -fPIC")
|
||||
endif(WIN32)
|
||||
|
||||
endif(CMAKE_COMPILER_IS_GNUCXX)
|
||||
|
|
|
@ -55,8 +55,10 @@
|
|||
|
||||
#cmakedefine USE_IMAGES_IN_MENUS 1
|
||||
|
||||
/// Definitions to enable the s-expression file formats and nanometer units.
|
||||
#cmakedefine USE_PCBNEW_NANOMETRES
|
||||
#cmakedefine USE_PCBNEW_SEXPR_FILE_FORMAT
|
||||
#cmakedefine USE_PCBNEW_SEXPR_FOOTPRINT_LIBS
|
||||
|
||||
/// The legacy file format revision of the *.brd file created by this build
|
||||
#if defined(USE_PCBNEW_NANOMETRES)
|
||||
|
|
|
@ -499,6 +499,27 @@ void EDA_BASE_FRAME::CopyVersionInfoToClipboard( wxCommandEvent& event )
|
|||
|
||||
tmp << wxT( "Options: " );
|
||||
|
||||
tmp << wxT( " USE_PCBNEW_SEXPR_FILE_FORMAT=" );
|
||||
#ifdef USE_PCBNEW_SEXPR_FILE_FORMAT
|
||||
tmp << wxT( "ON\n" );
|
||||
#else
|
||||
tmp << wxT( "OFF\n" );
|
||||
#endif
|
||||
|
||||
tmp << wxT( " USE_PCBNEW_NANOMETRES=" );
|
||||
#ifdef USE_PCBNEW_NANOMETRES
|
||||
tmp << wxT( "ON\n" );
|
||||
#else
|
||||
tmp << wxT( "OFF\n" );
|
||||
#endif
|
||||
|
||||
tmp << wxT( " USE_PCBNEW_SEXPR_FOOTPRINT_LIBS=" );
|
||||
#ifdef USE_PCBNEW_SEXPR_FOOTPRINT_LIBS
|
||||
tmp << wxT( "ON\n" );
|
||||
#else
|
||||
tmp << wxT( "OFF\n" );
|
||||
#endif
|
||||
|
||||
tmp << wxT( " KICAD_GOST=" );
|
||||
#ifdef KICAD_GOST
|
||||
tmp << wxT( "ON\n" );
|
||||
|
|
|
@ -185,6 +185,44 @@ unsigned STRING_LINE_READER::ReadLine() throw( IO_ERROR )
|
|||
}
|
||||
|
||||
|
||||
INPUTSTREAM_LINE_READER::INPUTSTREAM_LINE_READER( wxInputStream* aStream ) :
|
||||
LINE_READER( LINE_READER_LINE_DEFAULT_MAX ),
|
||||
m_stream( aStream )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
unsigned INPUTSTREAM_LINE_READER::ReadLine() throw( IO_ERROR )
|
||||
{
|
||||
length = 0;
|
||||
line[0] = 0;
|
||||
|
||||
while( !m_stream->Eof() )
|
||||
{
|
||||
if( length >= maxLineLength )
|
||||
THROW_IO_ERROR( _( "Maximum line length exceeded" ) );
|
||||
|
||||
if( length + 1 > capacity )
|
||||
expandCapacity( capacity * 2 );
|
||||
|
||||
line[ length ] = m_stream->GetC();
|
||||
length++;
|
||||
|
||||
if( line[ length - 1 ] == '\n' )
|
||||
break;
|
||||
}
|
||||
|
||||
line[ length ] = 0;
|
||||
length -= 1;
|
||||
|
||||
// lineNum is incremented even if there was no line read, because this
|
||||
// leads to better error reporting when we hit an end of file.
|
||||
++lineNum;
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
//-----<OUTPUTFORMATTER>----------------------------------------------------
|
||||
|
||||
// factor out a common GetQuoteChar
|
||||
|
|
|
@ -51,6 +51,7 @@ const wxString DrillFileExtension( wxT( "drl" ) );
|
|||
const wxString SVGFileExtension( wxT( "svg" ) );
|
||||
const wxString ReportFileExtension( wxT( "rpt" ) );
|
||||
const wxString FootprintPlaceFileExtension( wxT( "pos" ) );
|
||||
const wxString FootprintFileExtension( wxT( "kicad_mod" ) );
|
||||
|
||||
// These strings are wildcards for file selection dialogs.
|
||||
// Because thes are static, one should explicitely call wxGetTranslation
|
||||
|
@ -64,7 +65,8 @@ const wxString GerberFileWildcard( _( "Gerber files (*.pho)|*.pho" ) );
|
|||
const wxString LegacyPcbFileWildcard( _( "KiCad printed circuit board files (*.brd)|*.brd" ) );
|
||||
const wxString EaglePcbFileWildcard( _( "Eagle ver. 6.x XML PCB files (*.brd)|*.brd" ) );
|
||||
const wxString PcbFileWildcard( _( "KiCad s-expr printed circuit board files (*.kicad_pcb)|*.kicad_pcb" ) );
|
||||
const wxString FootprintLibFileWildcard( _( "KiCad footprint library file (*.mod)|*.mod" ) );
|
||||
const wxString FootprintLibFileWildcard( _( "KiCad footprint s-expre library file (*.kicad_mod)|*.kicad_mod" ) );
|
||||
const wxString LegacyFootprintLibFileWildcard( _( "KiCad footprint library file (*.mod)|*.mod" ) );
|
||||
const wxString PdfFileWildcard( _( "Portable document format files (*.pdf)|*.pdf" ) );
|
||||
const wxString MacrosFileWildcard( _( "KiCad recorded macros (*.mcr)|*.mcr" ) );
|
||||
const wxString AllFilesWildcard( _( "All files (*)|*" ) );
|
||||
|
|
|
@ -384,6 +384,28 @@ public:
|
|||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class INPUTSTREAM_LINE_READER
|
||||
* is a LINE_READER that reads from a wxInputStream object.
|
||||
*/
|
||||
class INPUTSTREAM_LINE_READER : public LINE_READER
|
||||
{
|
||||
protected:
|
||||
wxInputStream* m_stream; //< The input stream to read. No ownership of this pointer.
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor WXINPUTSTREAM_LINE_READER
|
||||
*
|
||||
* @param aStream A pointer to a wxInputStream object to read.
|
||||
*/
|
||||
INPUTSTREAM_LINE_READER( wxInputStream* aStream );
|
||||
|
||||
unsigned ReadLine() throw( IO_ERROR ); // see LINE_READER::ReadLine() description
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class OUTPUTFORMATTER
|
||||
* is an important interface (abstract) class used to output UTF8 text in
|
||||
|
|
|
@ -60,6 +60,7 @@ extern const wxString DrillFileExtension;
|
|||
extern const wxString SVGFileExtension;
|
||||
extern const wxString ReportFileExtension;
|
||||
extern const wxString FootprintPlaceFileExtension;
|
||||
extern const wxString FootprintFileExtension;
|
||||
|
||||
/// Proper wxFileDialog wild card definitions.
|
||||
extern const wxString SchematicSymbolFileWildcard;
|
||||
|
@ -82,6 +83,7 @@ extern const wxString ReportFileWildcard;
|
|||
extern const wxString FootprintPlaceFileWildcard;
|
||||
extern const wxString VrmlFileWildcard;
|
||||
extern const wxString DocModulesFileName;
|
||||
extern const wxString LegacyFootprintLibFileWildcard;
|
||||
extern const wxString FootprintLibFileWildcard;
|
||||
|
||||
#endif // INCLUDE_WILDCARDS_AND_FILES_EXT_H_
|
||||
|
|
|
@ -369,24 +369,25 @@ public:
|
|||
bool aPadShapeFilter,
|
||||
bool aPadOrientFilter,
|
||||
bool aPadLayerFilter,
|
||||
bool aRedraw, bool aSaveForUndo );
|
||||
bool aRedraw,
|
||||
bool aSaveForUndo );
|
||||
|
||||
// loading footprints
|
||||
|
||||
/**
|
||||
* Function loadFootprintFromLibrary
|
||||
* loads @a aFootprintName from @a aLibraryPath.
|
||||
* If found add the module is also added to the BOARD, just for good measure.
|
||||
*
|
||||
* @param aLibraryPath - the full filename or the short name of the library to read.
|
||||
* if it is a short name, the file is searched in all library valid paths
|
||||
* @param aFootprintName is the footprint to load
|
||||
* @param aDisplayError = true to display an error message if any.
|
||||
* @param aAddToBoard Set to true to add the footprint to the board if found.
|
||||
*
|
||||
* @return MODULE* - new module, or NULL
|
||||
*/
|
||||
MODULE* loadFootprintFromLibrary( const wxString& aLibraryPath,
|
||||
const wxString& aFootprintName, bool aDisplayError );
|
||||
MODULE* loadFootprintFromLibrary( const wxString& aLibraryPath, const wxString& aFootprintName,
|
||||
bool aDisplayError, bool aAddToBoard = true );
|
||||
|
||||
/**
|
||||
* Function loadFootprintFromLibraries
|
||||
|
|
|
@ -82,10 +82,8 @@ wxString BOARD_ITEM::GetLayerName() const
|
|||
if( board != NULL )
|
||||
return board->GetLayerName( m_Layer ).Trim();
|
||||
|
||||
wxFAIL_MSG( wxT( "No board found for board item type " ) + GetClass() );
|
||||
layerName = _( "** undefined layer **" );
|
||||
|
||||
return layerName;
|
||||
// If no parent, return the default layer for the object.
|
||||
return BOARD::GetDefaultLayerName( m_Layer, true );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <build_version.h> // LEGACY_BOARD_FILE_VERSION
|
||||
#include <macros.h>
|
||||
#include <3d_struct.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
|
||||
#include <class_board.h>
|
||||
#include <class_module.h>
|
||||
|
@ -44,11 +45,258 @@
|
|||
#include <kicad_plugin.h>
|
||||
#include <pcb_parser.h>
|
||||
|
||||
#include <wx/dir.h>
|
||||
#include <wx/filename.h>
|
||||
#include <wx/wfstream.h>
|
||||
#include <boost/ptr_container/ptr_map.hpp>
|
||||
#include <memory.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
#define FMTIU BOARD_ITEM::FormatInternalUnits
|
||||
|
||||
|
||||
/**
|
||||
* Class FP_CACHE_ITEM
|
||||
* is helper class for creating a footprint library cache.
|
||||
*
|
||||
* The new footprint library design is a file path of individual module files
|
||||
* that contain a single module per file. This class is a helper only for the
|
||||
* footprint portion of the PLUGIN API, and only for the #PCB_IO plugin. It is
|
||||
* private to this implementation file so it is not placed into a header.
|
||||
*/
|
||||
class FP_CACHE_ITEM
|
||||
{
|
||||
wxFileName m_file_name; /// The the full file name and path of the footprint to cache.
|
||||
bool m_writable; /// Writability status of the footprint file.
|
||||
wxDateTime m_mod_time; /// The last file modified time stamp.
|
||||
auto_ptr< MODULE > m_module;
|
||||
|
||||
public:
|
||||
FP_CACHE_ITEM( MODULE* aModule, const wxFileName& aFileName );
|
||||
|
||||
wxString GetName() const { return m_file_name.GetDirs().Last(); }
|
||||
wxFileName GetFileName() const { return m_file_name; }
|
||||
bool IsModified() const;
|
||||
MODULE* GetModule() const { return m_module.get(); }
|
||||
void UpdateModificationTime() { m_mod_time = m_file_name.GetModificationTime(); }
|
||||
};
|
||||
|
||||
|
||||
FP_CACHE_ITEM::FP_CACHE_ITEM( MODULE* aModule, const wxFileName& aFileName )
|
||||
{
|
||||
m_file_name = aFileName;
|
||||
auto_ptr< MODULE > tmp( aModule );
|
||||
m_module = tmp;
|
||||
m_mod_time.Now();
|
||||
}
|
||||
|
||||
|
||||
bool FP_CACHE_ITEM::IsModified() const
|
||||
{
|
||||
return m_file_name.GetModificationTime() != m_mod_time;
|
||||
}
|
||||
|
||||
|
||||
typedef boost::ptr_map< std::string, FP_CACHE_ITEM > MODULE_MAP;
|
||||
typedef MODULE_MAP::iterator MODULE_ITER;
|
||||
typedef MODULE_MAP::const_iterator MODULE_CITER;
|
||||
|
||||
|
||||
class FP_CACHE
|
||||
{
|
||||
PCB_IO* m_owner; /// Plugin object that owns the cache.
|
||||
wxFileName m_lib_path; /// The path of the library.
|
||||
wxDateTime m_mod_time; /// Footprint library path modified time stamp.
|
||||
MODULE_MAP m_modules; /// Map of footprint file name per MODULE*.
|
||||
|
||||
public:
|
||||
FP_CACHE( PCB_IO* aOwner, const wxString& aLibraryPath );
|
||||
|
||||
wxString GetPath() const { return m_lib_path.GetPath(); }
|
||||
wxDateTime GetLastModificationTime() const { return m_mod_time; }
|
||||
bool IsWritable() const { return m_lib_path.IsOk() && m_lib_path.IsDirWritable(); }
|
||||
MODULE_MAP& GetModules() { return m_modules; }
|
||||
|
||||
// Most all functions in this class throw IO_ERROR exceptions. There are no
|
||||
// error codes nor user interface calls from here, nor in any PLUGIN.
|
||||
// Catch these exceptions higher up please.
|
||||
|
||||
/// save the entire legacy library to m_lib_name;
|
||||
void Save();
|
||||
|
||||
void Load();
|
||||
|
||||
void Remove( const wxString& aFootprintName );
|
||||
|
||||
wxDateTime GetLibModificationTime();
|
||||
|
||||
bool IsModified();
|
||||
};
|
||||
|
||||
|
||||
FP_CACHE::FP_CACHE( PCB_IO* aOwner, const wxString& aLibraryPath )
|
||||
{
|
||||
m_owner = aOwner;
|
||||
m_lib_path.SetPath( aLibraryPath );
|
||||
}
|
||||
|
||||
|
||||
wxDateTime FP_CACHE::GetLibModificationTime()
|
||||
{
|
||||
return m_lib_path.GetModificationTime();
|
||||
}
|
||||
|
||||
|
||||
void FP_CACHE::Save()
|
||||
{
|
||||
if( !m_lib_path.DirExists() && !m_lib_path.Mkdir() )
|
||||
{
|
||||
THROW_IO_ERROR( wxString::Format( _( "Cannot create footprint library path '%s'." ),
|
||||
m_lib_path.GetPath().GetData() ) );
|
||||
}
|
||||
|
||||
if( !m_lib_path.IsDirWritable() )
|
||||
{
|
||||
THROW_IO_ERROR( wxString::Format( _( "Footprint library path '%s' is read only" ),
|
||||
GetChars( m_lib_path.GetPath() ) ) );
|
||||
}
|
||||
|
||||
for( MODULE_ITER it = m_modules.begin(); it != m_modules.end(); ++it )
|
||||
{
|
||||
wxFileName fn = it->second->GetFileName();
|
||||
|
||||
if( fn.FileExists() && !it->second->IsModified() )
|
||||
continue;
|
||||
|
||||
wxString tempFileName = fn.CreateTempFileName( fn.GetPath() );
|
||||
|
||||
// Allow file output stream to go out of scope to close the file stream before
|
||||
// renaming the file.
|
||||
{
|
||||
wxLogDebug( wxT( "Creating temporary library file %s" ), GetChars( tempFileName ) );
|
||||
|
||||
wxFFileOutputStream os( tempFileName );
|
||||
|
||||
if( !os.IsOk() )
|
||||
{
|
||||
THROW_IO_ERROR( wxString::Format( _( "cannot save footprint library file '%s'" ),
|
||||
tempFileName.GetData() ) );
|
||||
}
|
||||
|
||||
STREAM_OUTPUTFORMATTER formatter( os );
|
||||
|
||||
m_owner->SetOutputFormatter( &formatter );
|
||||
m_owner->Format( (BOARD_ITEM*) it->second->GetModule() );
|
||||
}
|
||||
|
||||
wxRemove( fn.GetFullPath() ); // it is not an error if this does not exist
|
||||
|
||||
if( wxRename( tempFileName, fn.GetFullPath() ) )
|
||||
{
|
||||
THROW_IO_ERROR( wxString::Format( _( "cannot rename temporary file '%s' to footprint library file '%s'" ),
|
||||
tempFileName.GetData(),
|
||||
fn.GetFullPath().GetData() ) );
|
||||
}
|
||||
|
||||
it->second->UpdateModificationTime();
|
||||
m_mod_time = GetLibModificationTime();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FP_CACHE::Load()
|
||||
{
|
||||
wxDir dir( m_lib_path.GetPath() );
|
||||
|
||||
if( !dir.IsOpened() )
|
||||
{
|
||||
THROW_IO_ERROR( wxString::Format( _( "footprint library path '%s' does not exist" ),
|
||||
m_lib_path.GetPath().GetData() ) );
|
||||
}
|
||||
|
||||
wxString fpFileName;
|
||||
wxString wildcard = wxT( "*." ) + FootprintFileExtension;
|
||||
|
||||
if( !dir.GetFirst( &fpFileName, wildcard, wxDIR_FILES ) )
|
||||
return;
|
||||
|
||||
do
|
||||
{
|
||||
FILE* fp = wxFopen( fpFileName, wxT( "r" ) );
|
||||
|
||||
if( !fp )
|
||||
{
|
||||
THROW_IO_ERROR( wxString::Format( _( "cannot open footprint library file '%s'" ),
|
||||
fpFileName.GetData() ) );
|
||||
}
|
||||
|
||||
// reader now owns fp, will close on exception or return
|
||||
PCB_PARSER parser( new FILE_LINE_READER( fp, fpFileName ) );
|
||||
|
||||
std::string name = TO_UTF8( fpFileName );
|
||||
|
||||
m_modules.insert( name, new FP_CACHE_ITEM( (MODULE*) parser.Parse(), fpFileName ) );
|
||||
|
||||
} while( dir.GetNext( &fpFileName ) );
|
||||
|
||||
// Remember the file modification time of library file when the
|
||||
// cache snapshot was made, so that in a networked environment we will
|
||||
// reload the cache as needed.
|
||||
m_mod_time = GetLibModificationTime();
|
||||
}
|
||||
|
||||
|
||||
void FP_CACHE::Remove( const wxString& aFootprintName )
|
||||
{
|
||||
|
||||
std::string footprintName = TO_UTF8( aFootprintName );
|
||||
|
||||
MODULE_CITER it = m_modules.find( footprintName );
|
||||
|
||||
if( it == m_modules.end() )
|
||||
{
|
||||
THROW_IO_ERROR( wxString::Format( _( "library '%s' has no footprint '%s' to delete" ),
|
||||
m_lib_path.GetPath().GetData(),
|
||||
aFootprintName.GetData() ) );
|
||||
}
|
||||
|
||||
// Remove the module from the cache and delete the module file from the library.
|
||||
wxString fullPath = it->second->GetFileName().GetFullPath();
|
||||
m_modules.erase( footprintName );
|
||||
wxRemoveFile( fullPath );
|
||||
}
|
||||
|
||||
|
||||
bool FP_CACHE::IsModified()
|
||||
{
|
||||
if( !m_lib_path.DirExists() )
|
||||
return true;
|
||||
|
||||
for( MODULE_ITER it = m_modules.begin(); it != m_modules.end(); ++it )
|
||||
{
|
||||
wxFileName fn = it->second->GetFileName();
|
||||
|
||||
if( !fn.FileExists() )
|
||||
{
|
||||
wxLogDebug( wxT( "Footprint cache file '%s' does not exist." ),
|
||||
fn.GetFullPath().GetData() );
|
||||
return true;
|
||||
}
|
||||
|
||||
if( it->second->IsModified() )
|
||||
{
|
||||
wxLogDebug( wxT( "Footprint cache file '%s' has been modified." ),
|
||||
fn.GetFullPath().GetData() );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void PCB_IO::Save( const wxString& aFileName, BOARD* aBoard, PROPERTIES* aProperties )
|
||||
{
|
||||
LOCALE_IO toggle; // toggles on, then off, the C locale.
|
||||
|
@ -779,13 +1027,23 @@ void PCB_IO::format( D_PAD* aPad, int aNestLevel ) const
|
|||
|
||||
m_out->Print( aNestLevel+1, "(layers" );
|
||||
|
||||
unsigned layerMask = aPad->GetLayerMask() & m_board->GetEnabledLayers();
|
||||
unsigned layerMask = aPad->GetLayerMask();
|
||||
|
||||
if( m_board )
|
||||
layerMask &= m_board->GetEnabledLayers();
|
||||
|
||||
for( int layer = 0; layerMask; ++layer, layerMask >>= 1 )
|
||||
{
|
||||
if( layerMask & 1 )
|
||||
{
|
||||
m_out->Print( 0, " %s", m_out->Quotew( m_board->GetLayerName( layer ) ).c_str() );
|
||||
wxString layerName;
|
||||
|
||||
if( m_board )
|
||||
layerName = m_board->GetLayerName( layer );
|
||||
else
|
||||
layerName = BOARD::GetDefaultLayerName( layer, true );
|
||||
|
||||
m_out->Print( 0, " %s", m_out->Quotew(layerName ).c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1185,12 +1443,19 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const
|
|||
}
|
||||
|
||||
|
||||
PCB_IO::PCB_IO()
|
||||
PCB_IO::PCB_IO() :
|
||||
m_cache( 0 )
|
||||
{
|
||||
m_out = &m_sf;
|
||||
}
|
||||
|
||||
|
||||
PCB_IO::~PCB_IO()
|
||||
{
|
||||
delete m_cache;
|
||||
}
|
||||
|
||||
|
||||
BOARD* PCB_IO::Load( const wxString& aFileName, BOARD* aAppendToMe, PROPERTIES* aProperties )
|
||||
{
|
||||
wxFFile file( aFileName, wxT("r") );
|
||||
|
@ -1210,5 +1475,252 @@ BOARD* PCB_IO::Load( const wxString& aFileName, BOARD* aAppendToMe, PROPERTIES*
|
|||
// Give the filename to the board if it's new
|
||||
if( !aAppendToMe )
|
||||
board->SetFileName( aFileName );
|
||||
|
||||
return board;
|
||||
}
|
||||
|
||||
|
||||
void PCB_IO::init( PROPERTIES* aProperties )
|
||||
{
|
||||
m_board = NULL;
|
||||
m_props = aProperties;
|
||||
}
|
||||
|
||||
|
||||
void PCB_IO::cacheLib( const wxString& aLibraryPath )
|
||||
{
|
||||
if( !m_cache || m_cache->GetPath() != aLibraryPath || m_cache->IsModified() )
|
||||
{
|
||||
// a spectacular episode in memory management:
|
||||
delete m_cache;
|
||||
m_cache = new FP_CACHE( this, aLibraryPath );
|
||||
m_cache->Load();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
wxArrayString PCB_IO::FootprintEnumerate( const wxString& aLibraryPath, PROPERTIES* aProperties )
|
||||
{
|
||||
LOCALE_IO toggle; // toggles on, then off, the C locale.
|
||||
|
||||
init( aProperties );
|
||||
|
||||
cacheLib( aLibraryPath );
|
||||
|
||||
const MODULE_MAP& mods = m_cache->GetModules();
|
||||
|
||||
wxArrayString ret;
|
||||
|
||||
for( MODULE_CITER it = mods.begin(); it != mods.end(); ++it )
|
||||
{
|
||||
ret.Add( FROM_UTF8( it->first.c_str() ) );
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
MODULE* PCB_IO::FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName,
|
||||
PROPERTIES* aProperties )
|
||||
{
|
||||
LOCALE_IO toggle; // toggles on, then off, the C locale.
|
||||
|
||||
init( aProperties );
|
||||
|
||||
cacheLib( aLibraryPath );
|
||||
|
||||
const MODULE_MAP& mods = m_cache->GetModules();
|
||||
|
||||
MODULE_CITER it = mods.find( TO_UTF8( aFootprintName ) );
|
||||
|
||||
if( it == mods.end() )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// copy constructor to clone the already loaded MODULE
|
||||
return new MODULE( *it->second->GetModule() );
|
||||
}
|
||||
|
||||
|
||||
void PCB_IO::FootprintSave( const wxString& aLibraryPath, const MODULE* aFootprint,
|
||||
PROPERTIES* aProperties )
|
||||
{
|
||||
LOCALE_IO toggle; // toggles on, then off, the C locale.
|
||||
|
||||
init( aProperties );
|
||||
|
||||
cacheLib( aLibraryPath );
|
||||
|
||||
if( !m_cache->IsWritable() )
|
||||
{
|
||||
THROW_IO_ERROR( wxString::Format( _( "Library '%s' is read only" ),
|
||||
aLibraryPath.GetData() ) );
|
||||
}
|
||||
|
||||
std::string footprintName = TO_UTF8( aFootprint->GetLibRef() );
|
||||
|
||||
MODULE_MAP& mods = m_cache->GetModules();
|
||||
|
||||
// Quietly overwrite module and delete module file from path for any by same name.
|
||||
wxFileName fn( aLibraryPath, aFootprint->GetLibRef(), FootprintFileExtension );
|
||||
|
||||
if( !fn.IsOk() )
|
||||
{
|
||||
THROW_IO_ERROR( wxString::Format( _( "Footprint file name '%s' is not valid." ),
|
||||
GetChars( fn.GetFullPath() ) ) );
|
||||
}
|
||||
|
||||
if( fn.FileExists() && !fn.IsFileWritable() )
|
||||
{
|
||||
THROW_IO_ERROR( wxString::Format( _( "user does not have write permission to delete file '%s' " ),
|
||||
GetChars( fn.GetFullPath() ) ) );
|
||||
}
|
||||
|
||||
MODULE_CITER it = mods.find( footprintName );
|
||||
|
||||
if( it != mods.end() )
|
||||
{
|
||||
wxLogDebug( wxT( "Removing footprint library file '%s'." ), fn.GetFullPath().GetData() );
|
||||
mods.erase( footprintName );
|
||||
wxRemoveFile( fn.GetFullPath() );
|
||||
}
|
||||
|
||||
// I need my own copy for the cache
|
||||
MODULE* module = new MODULE( *aFootprint );
|
||||
|
||||
// and it's time stamp must be 0, it should have no parent, orientation should
|
||||
// be zero, and it should be on the front layer.
|
||||
module->SetTimeStamp( 0 );
|
||||
module->SetParent( 0 );
|
||||
module->SetOrientation( 0 );
|
||||
|
||||
if( module->GetLayer() != LAYER_N_FRONT )
|
||||
module->Flip( module->GetPosition() );
|
||||
|
||||
wxLogDebug( wxT( "Creating s-expression footprint file: %s." ), fn.GetFullPath().GetData() );
|
||||
mods.insert( footprintName, new FP_CACHE_ITEM( module, fn ) );
|
||||
m_cache->Save();
|
||||
}
|
||||
|
||||
|
||||
void PCB_IO::FootprintDelete( const wxString& aLibraryPath, const wxString& aFootprintName )
|
||||
{
|
||||
LOCALE_IO toggle; // toggles on, then off, the C locale.
|
||||
|
||||
init( NULL );
|
||||
|
||||
cacheLib( aLibraryPath );
|
||||
|
||||
if( !m_cache->IsWritable() )
|
||||
{
|
||||
THROW_IO_ERROR( wxString::Format( _( "Library '%s' is read only" ),
|
||||
aLibraryPath.GetData() ) );
|
||||
}
|
||||
|
||||
m_cache->Remove( aFootprintName );
|
||||
}
|
||||
|
||||
|
||||
void PCB_IO::FootprintLibCreate( const wxString& aLibraryPath, PROPERTIES* aProperties )
|
||||
{
|
||||
if( wxDir::Exists( aLibraryPath ) )
|
||||
{
|
||||
THROW_IO_ERROR( wxString::Format( _( "cannot overwrite library path '%s'" ),
|
||||
aLibraryPath.GetData() ) );
|
||||
}
|
||||
|
||||
LOCALE_IO toggle;
|
||||
|
||||
init( aProperties );
|
||||
|
||||
delete m_cache;
|
||||
m_cache = new FP_CACHE( this, aLibraryPath );
|
||||
m_cache->Save();
|
||||
}
|
||||
|
||||
|
||||
void PCB_IO::FootprintLibDelete( const wxString& aLibraryPath, PROPERTIES* aProperties )
|
||||
{
|
||||
wxFileName fn;
|
||||
fn.SetPath( aLibraryPath );
|
||||
|
||||
// Return if there is no library path to delete.
|
||||
if( !fn.DirExists() )
|
||||
return;
|
||||
|
||||
if( !fn.IsDirWritable() )
|
||||
{
|
||||
THROW_IO_ERROR( wxString::Format( _( "user does not have permission to delete directory '%s'" ),
|
||||
aLibraryPath.GetData() ) );
|
||||
}
|
||||
|
||||
wxDir dir( aLibraryPath );
|
||||
|
||||
if( dir.HasSubDirs() )
|
||||
{
|
||||
THROW_IO_ERROR( wxString::Format( _( "library directory '%s' has unexpected sub-directories" ),
|
||||
aLibraryPath.GetData() ) );
|
||||
}
|
||||
|
||||
// All the footprint files must be deleted before the directory can be deleted.
|
||||
if( dir.HasFiles() )
|
||||
{
|
||||
unsigned i;
|
||||
wxFileName tmp;
|
||||
wxArrayString files;
|
||||
|
||||
wxDir::GetAllFiles( aLibraryPath, &files );
|
||||
|
||||
for( i = 0; i < files.GetCount(); i++ )
|
||||
{
|
||||
tmp = files[i];
|
||||
|
||||
if( tmp.GetExt() != FootprintFileExtension )
|
||||
{
|
||||
THROW_IO_ERROR( wxString::Format( _( "unexpected file '%s' has found in library path '%'" ),
|
||||
files[i].GetData(), aLibraryPath.GetData() ) );
|
||||
}
|
||||
}
|
||||
|
||||
for( i = 0; i < files.GetCount(); i++ )
|
||||
{
|
||||
wxRemoveFile( files[i] );
|
||||
}
|
||||
}
|
||||
|
||||
wxLogDebug( wxT( "Removing footprint library '%s'" ), aLibraryPath.GetData() );
|
||||
|
||||
// Some of the more elaborate wxRemoveFile() crap puts up its own wxLog dialog
|
||||
// we don't want that. we want bare metal portability with no UI here.
|
||||
if( !wxRmdir( aLibraryPath ) )
|
||||
{
|
||||
THROW_IO_ERROR( wxString::Format( _( "footprint library '%s' cannot be deleted" ),
|
||||
aLibraryPath.GetData() ) );
|
||||
}
|
||||
|
||||
// For some reason removing a directory in Windows is not immediately updated. This delay
|
||||
// prevents an error when attempting to immediately recreate the same directory when over
|
||||
// writing an existing library.
|
||||
#ifdef __WINDOWS__
|
||||
wxMilliSleep( 250L );
|
||||
#endif
|
||||
|
||||
if( m_cache && m_cache->GetPath() == aLibraryPath )
|
||||
{
|
||||
delete m_cache;
|
||||
m_cache = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool PCB_IO::IsFootprintLibWritable( const wxString& aLibraryPath )
|
||||
{
|
||||
LOCALE_IO toggle;
|
||||
|
||||
init( NULL );
|
||||
|
||||
cacheLib( aLibraryPath );
|
||||
|
||||
return m_cache->IsWritable();
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
class BOARD;
|
||||
class BOARD_ITEM;
|
||||
class FP_CACHE;
|
||||
|
||||
|
||||
/** Current s-expression file format version. 2 was the last legacy format version. */
|
||||
|
@ -68,10 +69,28 @@ public:
|
|||
|
||||
BOARD* Load( const wxString& aFileName, BOARD* aAppendToMe, PROPERTIES* aProperties = NULL );
|
||||
|
||||
wxArrayString FootprintEnumerate( const wxString& aLibraryPath, PROPERTIES* aProperties = NULL);
|
||||
|
||||
MODULE* FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName,
|
||||
PROPERTIES* aProperties = NULL );
|
||||
|
||||
void FootprintSave( const wxString& aLibraryPath, const MODULE* aFootprint,
|
||||
PROPERTIES* aProperties = NULL );
|
||||
|
||||
void FootprintDelete( const wxString& aLibraryPath, const wxString& aFootprintName );
|
||||
|
||||
void FootprintLibCreate( const wxString& aLibraryPath, PROPERTIES* aProperties = NULL);
|
||||
|
||||
void FootprintLibDelete( const wxString& aLibraryPath, PROPERTIES* aProperties = NULL );
|
||||
|
||||
bool IsFootprintLibWritable( const wxString& aLibraryPath );
|
||||
|
||||
//-----</PLUGIN API>--------------------------------------------------------
|
||||
|
||||
PCB_IO();
|
||||
|
||||
~PCB_IO();
|
||||
|
||||
/**
|
||||
* Function Format
|
||||
* outputs \a aItem to \a aFormatter in s-expression format.
|
||||
|
@ -92,17 +111,19 @@ public:
|
|||
return ret;
|
||||
}
|
||||
|
||||
void SetOutputFormatter( OUTPUTFORMATTER* aFormatter ) { m_out = aFormatter; }
|
||||
|
||||
protected:
|
||||
|
||||
wxString m_error; ///< for throwing exceptions
|
||||
BOARD* m_board; ///< which BOARD, no ownership here
|
||||
PROPERTIES* m_props; ///< passed via Save() or Load(), no ownership, may be NULL.
|
||||
FP_CACHE* m_cache; ///< Footprint library cache.
|
||||
|
||||
LINE_READER* m_reader; ///< no ownership here.
|
||||
wxString m_filename; ///< for saves only, name is in m_reader for loads
|
||||
|
||||
int m_loading_format_version; ///< which BOARD_FORMAT_VERSION am I Load()ing?
|
||||
int m_loading_format_version; ///< which #BOARD_FORMAT_VERSION should be Load()ed?
|
||||
|
||||
STRING_FORMATTER m_sf;
|
||||
OUTPUTFORMATTER* m_out; ///< output any Format()s to this, no ownership
|
||||
|
@ -144,6 +165,11 @@ private:
|
|||
throw( IO_ERROR );
|
||||
|
||||
void formatLayer( const BOARD_ITEM* aItem ) const;
|
||||
|
||||
/// we only cache one footprint library for now, this determines which one.
|
||||
void cacheLib( const wxString& aLibraryPath );
|
||||
|
||||
void init( PROPERTIES* aProperties );
|
||||
};
|
||||
|
||||
#endif // KICAD_PLUGIN_H_
|
||||
|
|
|
@ -4387,4 +4387,3 @@ LEGACY_PLUGIN::~LEGACY_PLUGIN()
|
|||
{
|
||||
delete m_cache;
|
||||
}
|
||||
|
||||
|
|
|
@ -163,7 +163,7 @@ void FOOTPRINT_EDIT_FRAME::Export_Module( MODULE* aModule, bool aCreateSysLib )
|
|||
config->Read( EXPORT_IMPORT_LASTPATH_KEY, &path );
|
||||
|
||||
title = aCreateSysLib ? _( "Create New Library" ) : _( "Export Module" );
|
||||
wildcard = aCreateSysLib ? FootprintLibFileWildcard : ModExportFileWildcard;
|
||||
wildcard = aCreateSysLib ? LegacyFootprintLibFileWildcard : ModExportFileWildcard;
|
||||
|
||||
fn.SetPath( path );
|
||||
|
||||
|
@ -272,7 +272,7 @@ void PCB_EDIT_FRAME::ArchiveModulesOnBoard( const wxString& aLibName, bool aNewM
|
|||
{
|
||||
wxFileDialog dlg( this, _( "Library" ), path,
|
||||
wxEmptyString,
|
||||
wxGetTranslation( FootprintLibFileWildcard ),
|
||||
wxGetTranslation( LegacyFootprintLibFileWildcard ),
|
||||
wxFD_SAVE );
|
||||
|
||||
if( dlg.ShowModal() == wxID_CANCEL )
|
||||
|
@ -562,4 +562,3 @@ int FOOTPRINT_EDIT_FRAME::CreateLibrary( const wxString& aLibName )
|
|||
|
||||
return 1; // remember how many times we succeeded
|
||||
}
|
||||
|
||||
|
|
|
@ -284,7 +284,9 @@ MODULE* PCB_BASE_FRAME::GetModuleLibrary( const wxString& aLibraryPath,
|
|||
* if it is a short name, the file is searched in all library valid paths
|
||||
*/
|
||||
MODULE* PCB_BASE_FRAME::loadFootprintFromLibrary( const wxString& aLibraryPath,
|
||||
const wxString& aFootprintName, bool aDisplayError )
|
||||
const wxString& aFootprintName,
|
||||
bool aDisplayError,
|
||||
bool aAddToBoard )
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -309,7 +311,9 @@ MODULE* PCB_BASE_FRAME::loadFootprintFromLibrary( const wxString& aLibraryPath,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if( aAddToBoard )
|
||||
GetBoard()->Add( footprint, ADD_APPEND );
|
||||
|
||||
SetStatusText( wxEmptyString );
|
||||
return footprint;
|
||||
}
|
||||
|
@ -509,3 +513,86 @@ MODULE* FOOTPRINT_EDIT_FRAME::Select_1_Module_From_BOARD( BOARD* aPcb )
|
|||
|
||||
return module;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void FOOTPRINT_EDIT_FRAME::OnSaveLibraryAs( wxCommandEvent& aEvent )
|
||||
{
|
||||
wxFileName fn;
|
||||
wxString msg, path, title;
|
||||
FOOTPRINT_LIST fpInfoList;
|
||||
|
||||
title = _( "Save Footprint Library As" );
|
||||
|
||||
fn = wxFileName( wxEmptyString, GetCurrentLib(), FootprintLibFileExtension );
|
||||
path = wxGetApp().FindLibraryPath( fn );
|
||||
fn.SetPath( path );
|
||||
|
||||
wxDirDialog dlg( this, msg, fn.GetPath() );
|
||||
|
||||
if( dlg.ShowModal() == wxID_CANCEL )
|
||||
return;
|
||||
|
||||
fn.SetPath( dlg.GetPath() );
|
||||
fn.AppendDir( GetCurrentLib() );
|
||||
|
||||
path = fn.GetPath();
|
||||
|
||||
try
|
||||
{
|
||||
// @todo : hard code this as IO_MGR::KICAD plugin, what would be the reason to "export"
|
||||
// any other single footprint type, with clipboard support coming?
|
||||
// Use IO_MGR::LEGACY for now, until the IO_MGR::KICAD plugin is ready.
|
||||
PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::KICAD ) );
|
||||
|
||||
try
|
||||
{
|
||||
// try to delete the library whether it exists or not, quietly.
|
||||
pi->FootprintLibDelete( fn.GetPath() );
|
||||
}
|
||||
catch( IO_ERROR ioe )
|
||||
{
|
||||
// Ignore this, it will often happen and is not an error because
|
||||
// the library may not exist. If library was in a read only directory,
|
||||
// it will still exist as we get to the FootprintLibCreate() below.
|
||||
}
|
||||
|
||||
pi->FootprintLibCreate( fn.GetPath() );
|
||||
|
||||
wxArrayString libNameList;
|
||||
|
||||
wxLogDebug( wxT( "Loading legacy footprint library '%s'." ), m_CurrentLib.GetData() );
|
||||
|
||||
wxFileName libFileName = m_CurrentLib;
|
||||
|
||||
libFileName.SetExt( FootprintLibFileExtension );
|
||||
|
||||
wxString libPath = wxGetApp().FindLibraryPath( libFileName );
|
||||
|
||||
libNameList.Add( m_CurrentLib );
|
||||
fpInfoList.ReadFootprintFiles( libNameList );
|
||||
|
||||
for( unsigned i = 0; i < fpInfoList.GetCount(); i++ )
|
||||
{
|
||||
MODULE* module = loadFootprintFromLibrary( libFileName.GetFullPath(),
|
||||
fpInfoList.GetItem( i ).m_Module,
|
||||
true, false );
|
||||
|
||||
wxLogDebug( wxT( "Saving footprint %s as s-expression to path %s" ),
|
||||
module->GetLibRef().GetData(), path.GetData() );
|
||||
|
||||
pi->FootprintSave( path, module );
|
||||
}
|
||||
}
|
||||
catch( IO_ERROR ioe )
|
||||
{
|
||||
DisplayError( this, ioe.errorText );
|
||||
return;
|
||||
}
|
||||
|
||||
msg.Printf( _( "Footprint library type '%s' saved to <%s> as s-expression" ),
|
||||
GetCurrentLib().GetData(), path.GetData() );
|
||||
|
||||
DisplayInfoMessage( this, msg );
|
||||
}
|
||||
|
|
|
@ -76,19 +76,19 @@ void FOOTPRINT_EDIT_FRAME::ReCreateMenuBar()
|
|||
|
||||
// from File
|
||||
AddMenuItem( openSubmenu, ID_MODEDIT_IMPORT_PART,
|
||||
_( "Load from File (&Import)" ),
|
||||
_( "Import Module from File (&Import)" ),
|
||||
_( "Import a footprint from an existing file" ),
|
||||
KiBitmap( import_module_xpm ) );
|
||||
|
||||
// from Library
|
||||
AddMenuItem( openSubmenu, ID_MODEDIT_LOAD_MODULE,
|
||||
_( "Load from Li&brary" ),
|
||||
_( "Load Module from Current Li&brary" ),
|
||||
_( "Open a footprint module from a Library" ),
|
||||
KiBitmap( module_xpm ) );
|
||||
|
||||
// from current Board
|
||||
AddMenuItem( openSubmenu, ID_MODEDIT_LOAD_MODULE_FROM_BOARD,
|
||||
_( "Load from &Current Board" ),
|
||||
_( "Load Module from &Current Board" ),
|
||||
_( "Load a footprint module from the current loaded board" ),
|
||||
KiBitmap( load_module_board_xpm ) );
|
||||
|
||||
|
@ -99,6 +99,13 @@ void FOOTPRINT_EDIT_FRAME::ReCreateMenuBar()
|
|||
KiBitmap( open_document_xpm ) );
|
||||
fileMenu->AppendSeparator();
|
||||
|
||||
#ifdef USE_PCBNEW_SEXPR_FOOTPRINT_LIBS
|
||||
// Save the currently loaded legacy library as an s-expression library.
|
||||
AddMenuItem( fileMenu, ID_MODEDIT_SAVE_LIBRARY_AS, _( "Save Library In S-Expression Format" ),
|
||||
_( "Save currently loaded legacy library as an s-expression library." ),
|
||||
wxNullBitmap );
|
||||
#endif
|
||||
|
||||
// Save module
|
||||
text = AddHotkeyName( _( "&Save Module in Active Library" ),
|
||||
g_Module_Editor_Hokeys_Descr, HK_SAVE_MODULE );
|
||||
|
@ -108,7 +115,7 @@ void FOOTPRINT_EDIT_FRAME::ReCreateMenuBar()
|
|||
|
||||
// Save module in new lib
|
||||
AddMenuItem( fileMenu, ID_MODEDIT_CREATE_NEW_LIB_AND_SAVE_CURRENT_PART,
|
||||
_( "S&ave Module in a New Lib" ),
|
||||
_( "S&ave Module in a New Library" ),
|
||||
_( "Create new library and save current module" ),
|
||||
KiBitmap( new_library_xpm ) );
|
||||
|
||||
|
|
|
@ -85,6 +85,15 @@ public:
|
|||
void ToolOnRightClick( wxCommandEvent& event );
|
||||
void OnSelectOptionToolbar( wxCommandEvent& event );
|
||||
|
||||
/**
|
||||
* Function OnSaveLibraryAs
|
||||
* saves the current library to a new name and/or library type.
|
||||
*
|
||||
* @note Saving as a new library type requires the plug-in to support saving libraris.
|
||||
* @see PLUGIN::FootprintSave and PLUGIN::FootprintLibCreate
|
||||
*/
|
||||
void OnSaveLibraryAs( wxCommandEvent& aEvent );
|
||||
|
||||
/**
|
||||
* Function OnHotKey
|
||||
* handle hot key events.
|
||||
|
|
|
@ -67,6 +67,11 @@ BEGIN_EVENT_TABLE( FOOTPRINT_EDIT_FRAME, PCB_BASE_FRAME )
|
|||
EVT_COMBOBOX( ID_ON_GRID_SELECT, FOOTPRINT_EDIT_FRAME::OnSelectGrid )
|
||||
|
||||
EVT_TOOL( ID_MODEDIT_SELECT_CURRENT_LIB, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
|
||||
|
||||
#ifdef USE_PCBNEW_SEXPR_FOOTPRINT_LIBS
|
||||
EVT_TOOL( ID_MODEDIT_SAVE_LIBRARY_AS, FOOTPRINT_EDIT_FRAME::OnSaveLibraryAs )
|
||||
#endif
|
||||
|
||||
EVT_TOOL( ID_MODEDIT_SAVE_LIBMODULE, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
|
||||
EVT_TOOL( ID_OPEN_MODULE_VIEWER, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
|
||||
|
||||
|
@ -109,9 +114,12 @@ BEGIN_EVENT_TABLE( FOOTPRINT_EDIT_FRAME, PCB_BASE_FRAME )
|
|||
FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
|
||||
|
||||
EVT_MENU( ID_POPUP_MODEDIT_EDIT_BODY_ITEM, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
|
||||
EVT_MENU( ID_POPUP_MODEDIT_EDIT_WIDTH_ALL_EDGE, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
|
||||
EVT_MENU( ID_POPUP_MODEDIT_EDIT_LAYER_CURRENT_EDGE, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
|
||||
EVT_MENU( ID_POPUP_MODEDIT_EDIT_LAYER_ALL_EDGE, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
|
||||
EVT_MENU( ID_POPUP_MODEDIT_EDIT_WIDTH_ALL_EDGE,
|
||||
FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
|
||||
EVT_MENU( ID_POPUP_MODEDIT_EDIT_LAYER_CURRENT_EDGE,
|
||||
FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
|
||||
EVT_MENU( ID_POPUP_MODEDIT_EDIT_LAYER_ALL_EDGE,
|
||||
FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
|
||||
EVT_MENU( ID_POPUP_MODEDIT_ENTER_EDGE_WIDTH, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
|
||||
|
||||
// Module transformations
|
||||
|
@ -126,6 +134,7 @@ BEGIN_EVENT_TABLE( FOOTPRINT_EDIT_FRAME, PCB_BASE_FRAME )
|
|||
EVT_MENU( ID_MENU_PCB_SHOW_3D_FRAME, FOOTPRINT_EDIT_FRAME::Show3D_Frame )
|
||||
|
||||
EVT_UPDATE_UI( ID_MODEDIT_DELETE_PART, FOOTPRINT_EDIT_FRAME::OnUpdateLibSelected )
|
||||
EVT_UPDATE_UI( ID_MODEDIT_SAVE_LIBRARY_AS, FOOTPRINT_EDIT_FRAME::OnUpdateLibSelected )
|
||||
EVT_UPDATE_UI( ID_MODEDIT_EXPORT_PART, FOOTPRINT_EDIT_FRAME::OnUpdateModuleSelected )
|
||||
EVT_UPDATE_UI( ID_MODEDIT_CREATE_NEW_LIB_AND_SAVE_CURRENT_PART,
|
||||
FOOTPRINT_EDIT_FRAME::OnUpdateModuleSelected )
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <trigo.h>
|
||||
#include <3d_struct.h>
|
||||
#include <class_title_block.h>
|
||||
|
||||
#include <class_board.h>
|
||||
#include <class_dimension.h>
|
||||
#include <class_drawsegment.h>
|
||||
|
@ -43,9 +44,9 @@
|
|||
#include <class_pad.h>
|
||||
#include <class_track.h>
|
||||
#include <class_zone.h>
|
||||
#include <kicad_plugin.h>
|
||||
#include <pcb_plot_params.h>
|
||||
#include <zones.h>
|
||||
|
||||
#include <pcb_parser.h>
|
||||
|
||||
using namespace std;
|
||||
|
@ -318,6 +319,10 @@ BOARD_ITEM* PCB_PARSER::Parse() throw( IO_ERROR, PARSE_ERROR )
|
|||
item = (BOARD_ITEM*) parseBOARD();
|
||||
break;
|
||||
|
||||
case T_module:
|
||||
item = (BOARD_ITEM*) parseMODULE();
|
||||
break;
|
||||
|
||||
default:
|
||||
wxString err;
|
||||
err.Printf( _( "unknown token \"%s\"" ), GetChars( FromUTF8() ) );
|
||||
|
|
|
@ -47,8 +47,10 @@ class TEXTE_MODULE;
|
|||
class TEXTE_PCB;
|
||||
class MODULE;
|
||||
class PCB_TARGET;
|
||||
class PROPERTIES;
|
||||
class S3D_MASTER;
|
||||
class ZONE_CONTAINER;
|
||||
class FPL_CACHE;
|
||||
|
||||
|
||||
WX_DECLARE_STRING_HASH_MAP( int, LAYER_HASH_MAP );
|
||||
|
|
|
@ -301,6 +301,7 @@ enum pcbnew_ids
|
|||
ID_MODEDIT_CHECK,
|
||||
ID_MODEDIT_SELECT_CURRENT_LIB,
|
||||
ID_MODEDIT_SAVE_LIBMODULE,
|
||||
ID_MODEDIT_SAVE_LIBRARY_AS,
|
||||
ID_MODEDIT_DELETE_PART,
|
||||
ID_MODEDIT_NEW_MODULE,
|
||||
ID_MODEDIT_NEW_MODULE_FROM_WIZARD,
|
||||
|
|
Loading…
Reference in New Issue