Commit 2aa27122 authored by Dick Hollenbeck's avatar Dick Hollenbeck

Eliminate many assumptions in Pcbnew's library manager, pertaining to locality of libraries and

their type, by using the more abstract PLUGIN::Footprint*() functions.

This is an intermediate phase only, other changes will be necessary as library table support comes in.
Encapsulate usage of library path searching, since that will go away as library table support comes in.
Add FOOTPRINT_EDIT_FRAME::{get,set}LibPath() and FOOTPRINT_EDIT_FRAME::{get,set}LibNickName() functions
to provide this encapsulation.
parent cb62f5c8
......@@ -4,6 +4,16 @@ KiCad ChangeLog 2012
Please add newer entries at the top, list the date and your name with
email address.
2012-Nov-19 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
Eliminate many assumptions in Pcbnew's library manager, pertaining to locality of libraries and
their type, by using the more abstract PLUGIN::Footprint*() functions.
This is an intermediate phase only, other changes will be necessary as library table support comes in.
Encapsulate usage of library path searching, since that will go away as library table support comes in.
Add FOOTPRINT_EDIT_FRAME::{get,set}LibPath() and FOOTPRINT_EDIT_FRAME::{get,set}LibNickName() functions
to provide this encapsulation.
2012-Nov-14 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
1) Switch to boost hashtable support from wx macros which did not handle std::string.
......
......@@ -20,15 +20,9 @@ set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMakeModules)
# reports.
#
option(USE_PCBNEW_SEXPR_FILE_FORMAT
"Use Pcbnew s-expression file format support (default OFF)." )
option(USE_PCBNEW_NANOMETRES
"Use nanometers for Pcbnew internal units instead of deci-mils (default ON)." ON)
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)")
......@@ -91,12 +85,6 @@ else (KICAD_STABLE_VERSION )
endif(KICAD_TESTING_VERSION )
endif(KICAD_STABLE_VERSION )
# Nanometers must be enabled when USE_PCBNEW_SEXPR_FILE_FORMAT=ON.
if( USE_PCBNEW_SEXPR_FILE_FORMAT AND NOT USE_PCBNEW_NANOMETRES )
set( TMP "The Pcbnew s-expression file format requires nano-meter internal units to be " )
set( TMP "${TMP} enabled using -DUSE_PCBNEW_NANOMETRES=ON." )
message( FATAL_ERROR ${TMP} )
endif( USE_PCBNEW_SEXPR_FILE_FORMAT AND NOT USE_PCBNEW_NANOMETRES )
#================================================
# Set flags for GCC.
......
......@@ -60,8 +60,6 @@
/// 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)
......
......@@ -506,13 +506,6 @@ 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" );
......@@ -520,13 +513,6 @@ void EDA_BASE_FRAME::CopyVersionInfoToClipboard( wxCommandEvent& event )
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" );
......
......@@ -54,7 +54,7 @@ bool FOOTPRINT_LIST::ReadFootprintFiles( wxArrayString& aFootprintsLibNames )
{
wxFileName filename = aFootprintsLibNames[ii];
filename.SetExt( FootprintLibFileExtension );
filename.SetExt( LegacyFootprintLibPathExtension );
wxString libPath = wxGetApp().FindLibraryPath( filename );
......
......@@ -41,7 +41,7 @@ const wxString VrmlFileExtension( wxT( "wrl" ) );
const wxString ProjectFileExtension( wxT( "pro" ) );
const wxString SchematicFileExtension( wxT( "sch" ) );
const wxString NetlistFileExtension( wxT( "net" ) );
const wxString FootprintLibFileExtension( wxT( "mod" ) );
const wxString LegacyFootprintLibPathExtension( wxT( "mod" ) );
const wxString ComponentFileExtension( wxT( "cmp" ) );
const wxString GerberFileExtension( wxT( "pho" ) );
const wxString PcbFileExtension( wxT( "brd" ) );
......@@ -51,11 +51,13 @@ 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" ) );
const wxString KiCadFootprintLibPathExtension( wxT( "pretty" ) ); ///< KICAD PLUGIN libpath
const wxString KiCadFootprintFileExtension( wxT( "kicad_mod" ) );
// These strings are wildcards for file selection dialogs.
// Because thes are static, one should explicitely call wxGetTranslation
// to display them translated.
// Because these are static, one should explicitly call wxGetTranslation
// to display them as translated.
const wxString SchematicSymbolFileWildcard( _( "KiCad drawing symbol file (*.sym)|*.sym" ) );
const wxString SchematicLibraryFileWildcard( _( "KiCad component library file (*.lib)|*.lib" ) );
const wxString ProjectFileWildcard( _( "KiCad project files (*.pro)|*.pro" ) );
......@@ -65,8 +67,9 @@ 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 s-expre library file (*.kicad_mod)|*.kicad_mod" ) );
const wxString LegacyFootprintLibFileWildcard( _( "KiCad footprint library file (*.mod)|*.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 LegacyFootprintLibPathWildcard( _( "Legacy footprint library file (*.mod)|*.mod" ) );
const wxString MacrosFileWildcard( _( "KiCad recorded macros (*.mcr)|*.mcr" ) );
// generic:
......
......@@ -299,7 +299,7 @@ void DIALOG_CVPCB_CONFIG::OnAddOrInsertLibClick( wxCommandEvent& event )
if( (event.GetId() == ID_ADD_LIB) || (event.GetId() == ID_INSERT_LIB) )
{
list = m_ListLibr;
wildcard = LegacyFootprintLibFileWildcard;
wildcard = LegacyFootprintLibPathWildcard;
}
wxArrayInt selections;
......
......@@ -39,7 +39,7 @@ MODULE* DISPLAY_FOOTPRINTS_FRAME::Get_Module( const wxString& aFootprintName )
{
wxFileName fn = parent->m_ModuleLibNames[i];
fn.SetExt( FootprintLibFileExtension );
fn.SetExt( LegacyFootprintLibPathExtension );
wxString libPath = wxGetApp().FindLibraryPath( fn );
......
......@@ -52,7 +52,7 @@ extern const wxString SchematicFileExtension;
extern const wxString NetlistFileExtension;
extern const wxString GerberFileExtension;
extern const wxString PcbFileExtension;
extern const wxString FootprintLibFileExtension;
extern const wxString LegacyFootprintLibPathExtension;
extern const wxString PdfFileExtension;
extern const wxString MacrosFileExtension;
extern const wxString ComponentFileExtension;
......@@ -60,7 +60,8 @@ extern const wxString DrillFileExtension;
extern const wxString SVGFileExtension;
extern const wxString ReportFileExtension;
extern const wxString FootprintPlaceFileExtension;
extern const wxString FootprintFileExtension;
extern const wxString KiCadFootprintFileExtension;
extern const wxString KiCadFootprintLibPathExtension;
/// Proper wxFileDialog wild card definitions.
extern const wxString SchematicSymbolFileWildcard;
......@@ -84,7 +85,8 @@ extern const wxString ReportFileWildcard;
extern const wxString FootprintPlaceFileWildcard;
extern const wxString VrmlFileWildcard;
extern const wxString DocModulesFileName;
extern const wxString LegacyFootprintLibFileWildcard;
extern const wxString FootprintLibFileWildcard;
extern const wxString LegacyFootprintLibPathWildcard;
extern const wxString KiCadFootprintLibFileWildcard;
extern const wxString KiCadFootprintLibPathWildcard;
#endif // INCLUDE_WILDCARDS_AND_FILES_EXT_H_
......@@ -115,13 +115,8 @@ std::string BOARD_ITEM::FormatInternalUnits( int aValue )
std::string BOARD_ITEM::FormatAngle( double aAngle )
{
char temp[50];
int len;
#if defined( USE_PCBNEW_SEXPR_FILE_FORMAT )
len = snprintf( temp, 49, "%.10g", aAngle / 10.0 );
#else
len = snprintf( temp, 49, "%.10g", aAngle );
#endif
int len = snprintf( temp, sizeof(temp), "%.10g", aAngle / 10.0 );
return std::string( temp, len );
}
......
......@@ -273,7 +273,7 @@ void DIALOG_PCBNEW_CONFIG_LIBS::OnAddOrInsertLibClick( wxCommandEvent& event )
wxFileDialog FilesDialog( this, _( "Footprint library files:" ), libpath,
wxEmptyString,
wxGetTranslation( LegacyFootprintLibFileWildcard ),
wxGetTranslation( LegacyFootprintLibPathWildcard ),
wxFD_DEFAULT_STYLE | wxFD_MULTIPLE );
if( FilesDialog.ShowModal() != wxID_OK )
......
......@@ -2659,7 +2659,7 @@ void EAGLE_PLUGIN::FootprintLibCreate( const wxString& aLibraryPath, PROPERTIES*
}
void EAGLE_PLUGIN::FootprintLibDelete( const wxString& aLibraryPath, PROPERTIES* aProperties )
bool EAGLE_PLUGIN::FootprintLibDelete( const wxString& aLibraryPath, PROPERTIES* aProperties )
{
}
......
......@@ -98,7 +98,7 @@ public:
void FootprintLibCreate( const wxString& aLibraryPath, PROPERTIES* aProperties = NULL );
void FootprintLibDelete( const wxString& aLibraryPath, PROPERTIES* aProperties = NULL );
bool FootprintLibDelete( const wxString& aLibraryPath, PROPERTIES* aProperties = NULL );
bool IsFootprintLibWritable( const wxString& aLibraryPath );
*/
......
......@@ -260,12 +260,13 @@ the changes?" ) ) )
GetBoard()->m_NetClasses.Clear();
}
BOARD* loadedBoard = 0; // it will be set to non-NULL if loadedOK
BOARD* loadedBoard = 0; // it will be set to non-NULL if loaded OK
try
{
PROPERTIES props;
// EAGLE_PLUGIN can use this info to center the BOARD, but it does not yet.
props["page_width"] = wxString::Format( wxT( "%d" ), GetPageSizeIU().x );
props["page_height"] = wxString::Format( wxT( "%d" ), GetPageSizeIU().y );
......@@ -409,11 +410,8 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool aCreateBackupF
int wildcardIndex = 0;
bool saveok = true;
wildcard = LegacyPcbFileWildcard;
#if defined( USE_PCBNEW_SEXPR_FILE_FORMAT )
wildcard += wxT( "|" ) + PcbFileWildcard;
#endif
wildcard << wxGetTranslation( LegacyPcbFileWildcard ) << wxChar( '|' ) <<
wxGetTranslation( PcbFileWildcard );
if( aFileName == wxEmptyString )
{
......@@ -431,6 +429,8 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool aCreateBackupF
GetBoard()->SetFileName( aFileName );
}
IO_MGR::PCB_FILE_T pluginType = ( wildcardIndex == 0 ) ? IO_MGR::LEGACY : IO_MGR::KICAD;
// If changes are made, update the board date
if( GetScreen()->IsModify() )
{
......@@ -443,7 +443,7 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool aCreateBackupF
pcbFileName = GetBoard()->GetFileName();
if( pcbFileName.GetExt().IsEmpty() )
pcbFileName.SetExt( IO_MGR::GetFileExtension( (IO_MGR::PCB_FILE_T) wildcardIndex ) );
pcbFileName.SetExt( IO_MGR::GetFileExtension( pluginType ) );
if( !IsWritable( pcbFileName ) )
return false;
......@@ -488,7 +488,7 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool aCreateBackupF
try
{
PROPERTIES props;
PLUGIN* plugin = IO_MGR::PluginFind( ( IO_MGR::PCB_FILE_T ) wildcardIndex );
PLUGIN* plugin = IO_MGR::PluginFind( pluginType );
if( plugin == NULL )
THROW_IO_ERROR( wxString::Format( _( "cannot find file plug in for file format '%s'" ),
......
......@@ -22,12 +22,13 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <wx/filename.h>
#include <io_mgr.h>
#include <legacy_plugin.h>
#include <kicad_plugin.h>
#include <eagle_plugin.h>
#include <wildcards_and_files_ext.h>
#define FMT_UNIMPLEMENTED _( "Plugin '%s' does not implement the '%s' function." )
#define FMT_NOTFOUND _( "Plugin type '%s' is not found." )
......@@ -110,6 +111,25 @@ const wxString IO_MGR::GetFileExtension( PCB_FILE_T aFileType )
}
IO_MGR::PCB_FILE_T IO_MGR::GuessPluginTypeFromLibPath( const wxString& aLibPath )
{
wxFileName fn = aLibPath;
PCB_FILE_T ret;
if( fn.GetExt() == LegacyFootprintLibPathExtension )
ret = LEGACY;
else
{
// Although KICAD PLUGIN uses libpaths with fixed extension of
// KiCadFootprintLibPathExtension, we don't make that assumption since
// a default choice is needed.
ret = KICAD;
}
return ret;
}
BOARD* IO_MGR::Load( PCB_FILE_T aFileType, const wxString& aFileName,
BOARD* aAppendToMe, PROPERTIES* aProperties )
{
......@@ -190,7 +210,7 @@ void PLUGIN::FootprintLibCreate( const wxString& aLibraryPath, PROPERTIES* aProp
}
void PLUGIN::FootprintLibDelete( const wxString& aLibraryPath, PROPERTIES* aProperties )
bool PLUGIN::FootprintLibDelete( const wxString& aLibraryPath, PROPERTIES* aProperties )
{
// not pure virtual so that plugins only have to implement subset of the PLUGIN interface.
THROW_IO_ERROR( wxString::Format( FMT_UNIMPLEMENTED, PluginName().GetData() , __FUNCTION__ ) );
......
......@@ -97,6 +97,12 @@ public:
*/
static const wxString GetFileExtension( PCB_FILE_T aFileType );
/**
* Function GuessPluginTypeFromLibPath
* returns a plugin type given a footprint library's libPath.
*/
static PCB_FILE_T GuessPluginTypeFromLibPath( const wxString& aLibPath );
/**
* Function Load
* finds the requested PLUGIN and if found, calls the PLUGIN->Load(..) funtion
......@@ -241,6 +247,8 @@ public:
virtual void Save( const wxString& aFileName, BOARD* aBoard,
PROPERTIES* aProperties = NULL );
//-----<Footprint Stuff>-----------------------------
/**
* Function FootprintEnumerate
* returns a list of footprint names contained within the library at @a aLibraryPath.
......@@ -341,8 +349,9 @@ public:
/**
* Function FootprintLibDelete
* deletes an existing footprint library, or complains if it cannot delete it
* or if it does not exist.
* deletes an existing footprint library and returns true, or if library does not
* exist returns false, or throws an exception if library exists but is read only or
* cannot be deleted for some other reason.
*
* @param aLibraryPath is a locator for the "library", usually a directory
* or file which will contain footprints.
......@@ -353,14 +362,18 @@ public:
* known to support. The caller continues to own this object (plugin may
* not delete it), and plugins should expect it to be optionally NULL.
*
* @throw IO_ERROR if there is a problem finding the library or deleting it.
* @return bool - true if library deleted, false if library did not exist.
*
* @throw IO_ERROR if there is a problem deleting an existing library.
*/
virtual void FootprintLibDelete( const wxString& aLibraryPath, PROPERTIES* aProperties = NULL );
virtual bool FootprintLibDelete( const wxString& aLibraryPath, PROPERTIES* aProperties = NULL );
/**
* Function IsFootprintLibWritable
* returns true iff the library at @a aLibraryPath is writable. (Often
* system libraries are read only because of where they are installed.)
*
* @throw IO_ERROR if no library at aLibraryPath exists.
*/
virtual bool IsFootprintLibWritable( const wxString& aLibraryPath );
......
......@@ -215,7 +215,7 @@ void FP_CACHE::Load()
}
wxString fpFileName;
wxString wildcard = wxT( "*." ) + FootprintFileExtension;
wxString wildcard = wxT( "*." ) + KiCadFootprintFileExtension;
if( !dir.GetFirst( &fpFileName, wildcard, wxDIR_FILES ) )
return;
......@@ -1662,7 +1662,7 @@ void PCB_IO::FootprintSave( const wxString& aLibraryPath, const MODULE* aFootpri
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 );
wxFileName fn( aLibraryPath, aFootprint->GetLibRef(), KiCadFootprintFileExtension );
if( !fn.IsOk() )
{
......@@ -1741,14 +1741,14 @@ void PCB_IO::FootprintLibCreate( const wxString& aLibraryPath, PROPERTIES* aProp
}
void PCB_IO::FootprintLibDelete( const wxString& aLibraryPath, PROPERTIES* aProperties )
bool 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;
return false;
if( !fn.IsDirWritable() )
{
......@@ -1777,7 +1777,7 @@ void PCB_IO::FootprintLibDelete( const wxString& aLibraryPath, PROPERTIES* aProp
{
tmp = files[i];
if( tmp.GetExt() != FootprintFileExtension )
if( tmp.GetExt() != KiCadFootprintFileExtension )
{
THROW_IO_ERROR( wxString::Format( _( "unexpected file '%s' has found in library path '%'" ),
files[i].GetData(), aLibraryPath.GetData() ) );
......@@ -1813,6 +1813,8 @@ void PCB_IO::FootprintLibDelete( const wxString& aLibraryPath, PROPERTIES* aProp
delete m_cache;
m_cache = NULL;
}
return true;
}
......
......@@ -94,7 +94,7 @@ public:
void FootprintLibCreate( const wxString& aLibraryPath, PROPERTIES* aProperties = NULL);
void FootprintLibDelete( const wxString& aLibraryPath, PROPERTIES* aProperties = NULL );
bool FootprintLibDelete( const wxString& aLibraryPath, PROPERTIES* aProperties = NULL );
bool IsFootprintLibWritable( const wxString& aLibraryPath );
......
......@@ -5,7 +5,6 @@
* Copyright (C) 2007-2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2004 Jean-Pierre Charras, jp.charras@wanadoo.fr
* 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
......@@ -4138,6 +4137,10 @@ void FPL_CACHE::Save()
wxRemove( m_lib_name ); // it is not an error if this does not exist
// Even on linux you can see an _intermittent_ error when calling wxRename(),
// and it is fully inexplicable. See if this dodges the error.
wxMilliSleep( 250L );
if( wxRename( tempFileName, m_lib_name ) )
{
THROW_IO_ERROR( wxString::Format(
......@@ -4339,16 +4342,12 @@ void LEGACY_PLUGIN::FootprintLibCreate( const wxString& aLibraryPath, PROPERTIES
}
void LEGACY_PLUGIN::FootprintLibDelete( const wxString& aLibraryPath, PROPERTIES* aProperties )
bool LEGACY_PLUGIN::FootprintLibDelete( const wxString& aLibraryPath, PROPERTIES* aProperties )
{
wxFileName fn = aLibraryPath;
if( !fn.FileExists() )
{
THROW_IO_ERROR( wxString::Format(
_( "library '%s' does not exist, cannot be deleted" ),
aLibraryPath.GetData() ) );
}
return false;
// 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.
......@@ -4364,6 +4363,8 @@ void LEGACY_PLUGIN::FootprintLibDelete( const wxString& aLibraryPath, PROPERTIES
delete m_cache;
m_cache = 0;
}
return true;
}
......
......@@ -92,7 +92,7 @@ public:
void FootprintLibCreate( const wxString& aLibraryPath, PROPERTIES* aProperties = NULL );
void FootprintLibDelete( const wxString& aLibraryPath, PROPERTIES* aProperties = NULL );
bool FootprintLibDelete( const wxString& aLibraryPath, PROPERTIES* aProperties = NULL );
bool IsFootprintLibWritable( const wxString& aLibraryPath );
......
......@@ -27,15 +27,43 @@
#include <legacy_plugin.h>
// unique, "file local" translations:
#define FMT_OK_OVERWRITE _( "Library '%s' exists, OK to replace ?" )
#define FMT_CREATE_LIB _( "Create New Library" )
#define FMT_OK_DELETE _( "Ok to delete module '%s' in library '%s'" )
#define FMT_IMPORT_MODULE _( "Import Footprint Module" )
#define FMT_FILE_NOT_FOUND _( "File '%s' not found" )
#define FMT_NOT_MODULE _( "Not a module file" )
#define FMT_MOD_NOT_FOUND _( "Unable to find or load footprint '%s' from lib path '%s'" )
#define FMT_BAD_PATH _( "Unable to find or load footprint from path '%s'" )
#define FMT_BAD_PATHS _( "The footprint library '%s' could not be found in any of the search paths." )
#define FMT_LIB_READ_ONLY _( "Library '%s' is read only, not writable" )
#define FMT_EXPORT_MODULE _( "Export Module" )
#define FMT_SAVE_MODULE _( "Save Module" )
#define FMT_MOD_REF _( "Module Reference:" )
#define FMT_EXPORTED _( "Module exported to file '%s'" )
#define FMT_MOD_DELETED _( "Component '%s' deleted from library '%s'" )
#define FMT_MOD_CREATE _( "Module Creation" )
#define FMT_NO_MODULES _( "No modules to archive!" )
#define FMT_LIBRARY _( "Library" ) // window title
#define FMT_MOD_EXISTS _( "Footprint '%s' already exists in library '%s'" )
#define FMT_NO_REF_ABORTED _( "No reference, aborted" )
#define FMT_SELECT_LIB _( "Select Active Library:" )
static const wxString ModExportFileWildcard( _( "KiCad foot print export files (*.emp)|*.emp" ) );
static const wxString ModImportFileWildcard( _( "GPcb foot print files (*)|*" ) );
#define BACKUP_EXT wxT( "bak" )
#define FILETMP_EXT wxT( "$$$" )
#define EXPORT_IMPORT_LASTPATH_KEY wxT( "import_last_path" )
const wxString ModExportFileExtension( wxT( "emp" ) );
static const wxString ModExportFileWildcard( _( "KiCad foot print export files (*.emp)|*.emp" ) );
static const wxString ModImportFileWildcard( _( "GPcb foot print files (*)|*" ) );
MODULE* FOOTPRINT_EDIT_FRAME::Import_Module()
{
......@@ -47,13 +75,15 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module()
if( config )
config->Read( EXPORT_IMPORT_LASTPATH_KEY, &lastOpenedPathForLoading );
wxString importWildCard = FootprintLibFileWildcard + wxT("|") +
ModExportFileWildcard + wxT("|") +
ModImportFileWildcard;
wxString wildCard;
wildCard << wxGetTranslation( KiCadFootprintLibFileWildcard ) << wxChar( '|' )
<< wxGetTranslation( ModExportFileWildcard ) << wxChar( '|' )
<< wxGetTranslation( ModImportFileWildcard );
wxFileDialog dlg( this, _( "Import Footprint Module" ),
wxFileDialog dlg( this, FMT_IMPORT_MODULE,
lastOpenedPathForLoading, wxEmptyString,
importWildCard, wxFD_OPEN | wxFD_FILE_MUST_EXIST );
wildCard, wxFD_OPEN | wxFD_FILE_MUST_EXIST );
if( dlg.ShowModal() == wxID_CANCEL )
return NULL;
......@@ -61,7 +91,7 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module()
FILE* fp = wxFopen( dlg.GetPath(), wxT( "rt" ) );
if( !fp )
{
wxString msg = wxString::Format( _( "File <%s> not found" ), GetChars( dlg.GetPath() ) );
wxString msg = wxString::Format( FMT_FILE_NOT_FOUND, GetChars( dlg.GetPath() ) );
DisplayError( this, msg );
return NULL;
}
......@@ -107,7 +137,7 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module()
}
else
{
DisplayError( this, _( "Not a module file" ) );
DisplayError( this, FMT_NOT_MODULE );
return NULL;
}
......@@ -135,8 +165,8 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module()
if( !module )
{
wxString msg = wxString::Format(
_( "Unable to find or load footprint '%s' from lib path '%s'" ),
GetChars( moduleName ), GetChars( dlg.GetPath() ) );
FMT_MOD_NOT_FOUND, GetChars( moduleName ), GetChars( dlg.GetPath() ) );
DisplayError( this, msg );
return NULL;
}
......@@ -160,9 +190,8 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module()
if( !f.IsOpened() )
{
wxString msg = wxString::Format(
_( "Unable to find or load footprint from path '%s'" ),
GetChars( dlg.GetPath() ) );
wxString msg = wxString::Format( FMT_BAD_PATH, GetChars( dlg.GetPath() ) );
DisplayError( this, msg );
return NULL;
}
......@@ -173,9 +202,8 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module()
if( !module )
{
wxString msg = wxString::Format(
_( "Unable to find or load footprint from lib path '%s'" ),
GetChars( dlg.GetPath() ) );
wxString msg = wxString::Format( FMT_BAD_PATH, GetChars( dlg.GetPath() ) );
DisplayError( this, msg );
return NULL;
}
......@@ -200,10 +228,9 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module()
}
void FOOTPRINT_EDIT_FRAME::Export_Module( MODULE* aModule, bool aCreateSysLib )
void FOOTPRINT_EDIT_FRAME::Export_Module( MODULE* aModule )
{
wxFileName fn;
wxString msg, path, title, wildcard;
wxConfig* config = wxGetApp().GetSettings();
if( aModule == NULL )
......@@ -211,19 +238,19 @@ void FOOTPRINT_EDIT_FRAME::Export_Module( MODULE* aModule, bool aCreateSysLib )
fn.SetName( aModule->m_LibRef );
// There is no longer any point to exporting as a new library. Work is planned
// for the library manager to make it easier to use.
title = _( "Export Module" );
wildcard = FootprintLibFileWildcard;
wxString wildcard = wxGetTranslation( KiCadFootprintLibFileWildcard );
fn.SetExt( FootprintFileExtension );
fn.SetExt( KiCadFootprintFileExtension );
if( config )
{
wxString path;
config->Read( EXPORT_IMPORT_LASTPATH_KEY, &path );
fn.SetPath( path );
}
wxFileDialog dlg( this, msg, fn.GetPath(), fn.GetFullName(),
wxGetTranslation( wildcard ),
wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
wxFileDialog dlg( this, FMT_EXPORT_MODULE, fn.GetPath(), fn.GetFullName(),
wildcard, wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
if( dlg.ShowModal() == wxID_CANCEL )
return;
......@@ -262,41 +289,164 @@ void FOOTPRINT_EDIT_FRAME::Export_Module( MODULE* aModule, bool aCreateSysLib )
return;
}
msg.Printf( _( "Module exported to file <%s>" ), GetChars( dlg.GetPath() ) );
wxString msg = wxString::Format( FMT_EXPORTED, GetChars( dlg.GetPath() ) );
DisplayInfoMessage( this, msg );
}
void FOOTPRINT_EDIT_FRAME::Delete_Module_In_Library( const wxString& aLibName )
bool FOOTPRINT_EDIT_FRAME::SaveCurrentModule( const wxString* aLibPath )
{
wxString footprintName = Select_1_Module_From_List( this, aLibName, wxEmptyString, wxEmptyString );
wxString libPath = aLibPath ? *aLibPath : getLibPath();
if( footprintName == wxEmptyString )
return;
IO_MGR::PCB_FILE_T piType = IO_MGR::GuessPluginTypeFromLibPath( libPath );
try
{
PLUGIN::RELEASER pi( IO_MGR::PluginFind( piType ) );
pi->FootprintSave( libPath, GetBoard()->m_Modules );
}
catch( IO_ERROR ioe )
{
DisplayError( this, ioe.errorText );
return false;
}
return true;
}
wxString FOOTPRINT_EDIT_FRAME::CreateNewLibrary()
{
wxFileName fn;
wxConfig* config = wxGetApp().GetSettings();
if( config )
{
wxString path;
config->Read( EXPORT_IMPORT_LASTPATH_KEY, &path );
fn.SetPath( path );
}
wxString wildcard;
wildcard << wxGetTranslation( LegacyFootprintLibPathWildcard ) << wxChar('|')
<< wxGetTranslation( KiCadFootprintLibPathWildcard );
// prompt user for libPath and PLUGIN (library) type
wxFileDialog dlg( this, FMT_CREATE_LIB, fn.GetPath(), wxEmptyString,
wildcard,
wxFD_SAVE
// | wxFD_OVERWRITE_PROMPT overwrite is tested below
// after file extension has been added.
);
if( dlg.ShowModal() == wxID_CANCEL )
return wxEmptyString;
fn = dlg.GetPath();
if( config ) // Save file path without filename, save user typing.
{
config->Write( EXPORT_IMPORT_LASTPATH_KEY, fn.GetPath() );
}
// wildcard's filter index has legacy in position 0.
IO_MGR::PCB_FILE_T piType = ( dlg.GetFilterIndex() == 0 ) ? IO_MGR::LEGACY : IO_MGR::KICAD;
// wxFileDialog does not supply nor enforce the file extension, add it here.
if( piType == IO_MGR::LEGACY )
{
fn.SetExt( LegacyFootprintLibPathExtension );
}
else
{
fn.SetExt( KiCadFootprintLibPathExtension );
}
wxString libPath = fn.GetFullPath();
try
{
PLUGIN::RELEASER pi( IO_MGR::PluginFind( piType ) );
bool writable = false;
bool exists = false;
try
{
writable = pi->IsFootprintLibWritable( libPath );
exists = true; // no exception was thrown, lib must exist.
}
catch( IO_ERROR )
{
// ignore, original values of 'writable' and 'exists' are accurate.
}
if( exists )
{
if( !writable )
{
wxString msg = wxString::Format( FMT_LIB_READ_ONLY, GetChars( libPath ) );
DisplayError( this, msg );
return wxEmptyString;
}
else
{
wxString msg = wxString::Format( FMT_OK_OVERWRITE, GetChars( libPath ) );
if( !IsOK( this, msg ) )
return wxEmptyString;
pi->FootprintLibDelete( libPath );
}
}
pi->FootprintLibCreate( libPath );
}
catch( IO_ERROR ioe )
{
DisplayError( this, ioe.errorText );
return wxEmptyString;
}
return libPath;
}
bool FOOTPRINT_EDIT_FRAME::DeleteModuleFromCurrentLibrary()
{
wxString libPath = getLibPath();
wxString footprintName = Select_1_Module_From_List( this, libPath,
wxEmptyString, wxEmptyString );
if( !footprintName )
return false;
// Confirmation
wxString msg = wxString::Format( _( "Ok to delete module '%s' in library '%s'" ),
footprintName.GetData(), aLibName.GetData() );
wxString msg = wxString::Format( FMT_OK_DELETE, footprintName.GetData(), libPath.GetData() );
if( !IsOK( this, msg ) )
return;
return false;
IO_MGR::PCB_FILE_T pluginType = IO_MGR::GuessPluginTypeFromLibPath( libPath );
try
{
PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::LEGACY ) );
PLUGIN::RELEASER pi( IO_MGR::PluginFind( pluginType ) );
pi->FootprintDelete( aLibName, footprintName );
pi->FootprintDelete( libPath, footprintName );
}
catch( IO_ERROR ioe )
{
DisplayError( NULL, ioe.errorText );
return;
return false;
}
msg.Printf( _( "Component '%s' deleted from library '%s'" ),
footprintName.GetData(), aLibName.GetData() );
msg.Printf( FMT_MOD_DELETED, footprintName.GetData(), libPath.GetData() );
SetStatusText( msg );
return true;
}
......@@ -312,7 +462,7 @@ void PCB_EDIT_FRAME::ArchiveModulesOnBoard( const wxString& aLibName, bool aNewM
if( GetBoard()->m_Modules == NULL )
{
DisplayInfoMessage( this, _( "No modules to archive!" ) );
DisplayInfoMessage( this, FMT_NO_MODULES );
return;
}
......@@ -320,9 +470,9 @@ void PCB_EDIT_FRAME::ArchiveModulesOnBoard( const wxString& aLibName, bool aNewM
if( !aLibName )
{
wxFileDialog dlg( this, _( "Library" ), path,
wxFileDialog dlg( this, FMT_LIBRARY, path,
wxEmptyString,
wxGetTranslation( LegacyFootprintLibFileWildcard ),
wxGetTranslation( LegacyFootprintLibPathWildcard ),
wxFD_SAVE );
if( dlg.ShowModal() == wxID_CANCEL )
......@@ -337,8 +487,7 @@ void PCB_EDIT_FRAME::ArchiveModulesOnBoard( const wxString& aLibName, bool aNewM
if( !aNewModulesOnly && lib_exists )
{
wxString msg;
msg.Printf( _( "Library %s exists, OK to replace ?" ), GetChars( fileName ) );
wxString msg = wxString::Format( FMT_OK_OVERWRITE, GetChars( fileName ) );
if( !IsOK( this, msg ) )
return;
......@@ -390,7 +539,7 @@ void PCB_EDIT_FRAME::ArchiveModulesOnBoard( const wxString& aLibName, bool aNewM
}
bool PCB_BASE_FRAME::Save_Module_In_Library( const wxString& aLibName,
bool PCB_BASE_FRAME::Save_Module_In_Library( const wxString& aLibPath,
MODULE* aModule,
bool aOverwrite,
bool aDisplayDialog )
......@@ -400,23 +549,12 @@ bool PCB_BASE_FRAME::Save_Module_In_Library( const wxString& aLibName,
aModule->DisplayInfo( this );
if( !wxFileExists( aLibName ) )
{
wxString msg = wxString::Format( _( "Library <%s> not found." ),
aLibName.GetData() );
DisplayError( this, msg );
return false;
}
if( !IsWritable( aLibName ) )
return false;
// Ask what to use as the footprint name in the library
wxString footprintName = aModule->GetLibRef();
if( aDisplayDialog )
{
wxTextEntryDialog dlg( this, _( "Name:" ), _( "Save Module" ), footprintName );
wxTextEntryDialog dlg( this, _( "Name:" ), FMT_SAVE_MODULE, footprintName );
if( dlg.ShowModal() != wxID_OK )
return false; // canceled by user
......@@ -438,13 +576,15 @@ bool PCB_BASE_FRAME::Save_Module_In_Library( const wxString& aLibName,
aModule->SetLibRef( footprintName );
}
IO_MGR::PCB_FILE_T pluginType = IO_MGR::GuessPluginTypeFromLibPath( aLibPath );
MODULE* module_exists = NULL;
try
{
PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::LEGACY ) );
PLUGIN::RELEASER pi( IO_MGR::PluginFind( pluginType ) );
module_exists = pi->FootprintLoad( aLibName, footprintName );
module_exists = pi->FootprintLoad( aLibPath, footprintName );
if( module_exists )
{
......@@ -453,9 +593,8 @@ bool PCB_BASE_FRAME::Save_Module_In_Library( const wxString& aLibName,
// an existing footprint is found in current lib
if( aDisplayDialog )
{
wxString msg = wxString::Format(
_( "Footprint '%s' already exists in library '%s'" ),
footprintName.GetData(), aLibName.GetData() );
wxString msg = wxString::Format( FMT_MOD_EXISTS,
footprintName.GetData(), aLibPath.GetData() );
SetStatusText( msg );
}
......@@ -467,8 +606,9 @@ bool PCB_BASE_FRAME::Save_Module_In_Library( const wxString& aLibName,
}
}
// this always overwrites any existing footprint
pi->FootprintSave( aLibName, aModule );
// this always overwrites any existing footprint, but should yell on its
// own if the library or footprint is not writable.
pi->FootprintSave( aLibPath, aModule );
}
catch( IO_ERROR ioe )
{
......@@ -482,7 +622,7 @@ bool PCB_BASE_FRAME::Save_Module_In_Library( const wxString& aLibName,
_( "Component [%s] replaced in <%s>" ) :
_( "Component [%s] added in <%s>" );
wxString msg = wxString::Format( fmt, footprintName.GetData(), aLibName.GetData() );
wxString msg = wxString::Format( fmt, footprintName.GetData(), aLibPath.GetData() );
SetStatusText( msg );
}
......@@ -492,7 +632,7 @@ bool PCB_BASE_FRAME::Save_Module_In_Library( const wxString& aLibName,
MODULE* PCB_BASE_FRAME::Create_1_Module( const wxString& aModuleName )
{
MODULE* Module;
MODULE* module;
wxString moduleName;
wxPoint newpos;
......@@ -501,8 +641,7 @@ MODULE* PCB_BASE_FRAME::Create_1_Module( const wxString& aModuleName )
// Ask for the new module reference
if( moduleName.IsEmpty() )
{
wxTextEntryDialog dlg( this, _( "Module Reference:" ),
_( "Module Creation" ), moduleName );
wxTextEntryDialog dlg( this, FMT_MOD_REF, FMT_MOD_CREATE, moduleName );
if( dlg.ShowModal() != wxID_OK )
return NULL; //Aborted by user
......@@ -515,37 +654,37 @@ MODULE* PCB_BASE_FRAME::Create_1_Module( const wxString& aModuleName )
if( moduleName.IsEmpty( ) )
{
DisplayInfoMessage( this, _( "No reference, aborted" ) );
DisplayInfoMessage( this, FMT_NO_REF_ABORTED );
return NULL;
}
// Creates the new module and add it to the head of the linked list of modules
Module = new MODULE( GetBoard() );
module = new MODULE( GetBoard() );
GetBoard()->Add( Module );
GetBoard()->Add( module );
// Update parameters: position, timestamp ...
newpos = GetScreen()->GetCrossHairPosition();
Module->SetPosition( newpos );
Module->SetLastEditTime();
module->SetPosition( newpos );
module->SetLastEditTime();
// Update its name in lib
Module->m_LibRef = moduleName;
module->m_LibRef = moduleName;
// Update reference:
Module->m_Reference->m_Text = moduleName;
Module->m_Reference->SetThickness( GetDesignSettings().m_ModuleTextWidth );
Module->m_Reference->SetSize( GetDesignSettings().m_ModuleTextSize );
module->m_Reference->m_Text = moduleName;
module->m_Reference->SetThickness( GetDesignSettings().m_ModuleTextWidth );
module->m_Reference->SetSize( GetDesignSettings().m_ModuleTextSize );
// Set the value field to a default value
Module->m_Value->m_Text = wxT( "VAL**" );
Module->m_Value->SetThickness( GetDesignSettings().m_ModuleTextWidth );
Module->m_Value->SetSize( GetDesignSettings().m_ModuleTextSize );
module->m_Value->m_Text = wxT( "VAL**" );
module->m_Value->SetThickness( GetDesignSettings().m_ModuleTextWidth );
module->m_Value->SetSize( GetDesignSettings().m_ModuleTextSize );
Module->SetPosition( wxPoint( 0, 0 ) );
module->SetPosition( wxPoint( 0, 0 ) );
Module->DisplayInfo( this );
return Module;
module->DisplayInfo( this );
return module;
}
......@@ -554,61 +693,31 @@ void FOOTPRINT_EDIT_FRAME::Select_Active_Library()
if( g_LibraryNames.GetCount() == 0 )
return;
EDA_LIST_DIALOG dlg( this, _( "Select Active Library:" ), g_LibraryNames, m_CurrentLib );
EDA_LIST_DIALOG dlg( this, FMT_SELECT_LIB, g_LibraryNames, getLibNickName() );
if( dlg.ShowModal() != wxID_OK )
return;
wxFileName fileName = wxFileName( wxEmptyString, dlg.GetTextSelection(),
FootprintLibFileExtension );
LegacyFootprintLibPathExtension );
fileName = wxGetApp().FindLibraryPath( fileName );
if( fileName.IsOk() && fileName.FileExists() )
{
m_CurrentLib = dlg.GetTextSelection();
setLibNickName( fileName.GetName() );
setLibPath( fileName.GetFullPath() );
}
else
{
wxString msg = wxString::Format(
_( "The footprint library <%s> could not be found in any of the search paths." ),
GetChars( dlg.GetTextSelection() ) );
DisplayError( this, msg );
m_CurrentLib.Empty();
}
UpdateTitle();
}
int FOOTPRINT_EDIT_FRAME::CreateLibrary( const wxString& aLibName )
{
wxFileName fileName = aLibName;
if( fileName.FileExists() )
{
wxString msg = wxString::Format(
_( "Library <%s> already exists." ),
aLibName.GetData() );
wxString msg = wxString::Format( FMT_BAD_PATHS, GetChars( dlg.GetTextSelection() ) );
DisplayError( this, msg );
return 0;
}
if( !IsWritable( fileName ) )
return 0;
try
{
PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::LEGACY ) );
pi->FootprintLibCreate( aLibName );
}
catch( IO_ERROR ioe )
{
DisplayError( this, ioe.errorText );
return 0;
setLibNickName( wxEmptyString );
setLibPath( wxEmptyString );
}
return 1; // remember how many times we succeeded
updateTitle();
}
......@@ -342,7 +342,7 @@ MODULE* PCB_BASE_FRAME::loadFootprintFromLibraries(
for( unsigned ii = 0; ii < g_LibraryNames.GetCount(); ii++ )
{
wxFileName fn = wxFileName( wxEmptyString, g_LibraryNames[ii], FootprintLibFileExtension );
wxFileName fn = wxFileName( wxEmptyString, g_LibraryNames[ii], LegacyFootprintLibPathExtension );
wxString libPath = wxGetApp().FindLibraryPath( fn );
......@@ -516,69 +516,30 @@ MODULE* FOOTPRINT_EDIT_FRAME::Select_1_Module_From_BOARD( BOARD* aPcb )
}
void FOOTPRINT_EDIT_FRAME::OnSaveLibraryAs( wxCommandEvent& aEvent )
{
wxFileName fn;
wxString msg, path, title;
FOOTPRINT_LIST fpInfoList;
title = _( "Save Footprint Library As" );
wxString curLibPath = getLibPath();
wxString dstLibPath = CreateNewLibrary();
fn = wxFileName( wxEmptyString, GetCurrentLib(), FootprintLibFileExtension );
path = wxGetApp().FindLibraryPath( fn );
fn.SetPath( path );
if( !dstLibPath )
return; // user aborted in CreateNewLibrary()
wxDirDialog dlg( this, msg, fn.GetPath() );
if( dlg.ShowModal() == wxID_CANCEL )
return;
fn.SetPath( dlg.GetPath() );
fn.AppendDir( GetCurrentLib() );
path = fn.GetPath();
IO_MGR::PCB_FILE_T dstType = IO_MGR::GuessPluginTypeFromLibPath( dstLibPath );
IO_MGR::PCB_FILE_T curType = IO_MGR::GuessPluginTypeFromLibPath( curLibPath );
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 ) );
PLUGIN::RELEASER cur( IO_MGR::PluginFind( curType ) );
PLUGIN::RELEASER dst( IO_MGR::PluginFind( dstType ) );
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;
wxArrayString mods = cur->FootprintEnumerate( curLibPath );
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++ )
for( unsigned i = 0; i < mods.size(); ++i )
{
MODULE* module = loadFootprintFromLibrary( libFileName.GetFullPath(),
fpInfoList.GetItem( i ).m_Module,
true, false );
std::auto_ptr<MODULE> m( cur->FootprintLoad( curLibPath, mods[i] ) );
dst->FootprintSave( dstLibPath, m.get() );
pi->FootprintSave( path, module );
// m is deleted here by auto_ptr.
}
}
catch( IO_ERROR ioe )
......@@ -587,8 +548,9 @@ void FOOTPRINT_EDIT_FRAME::OnSaveLibraryAs( wxCommandEvent& aEvent )
return;
}
msg.Printf( _( "Footprint library type '%s' saved to <%s> as s-expression" ),
GetCurrentLib().GetData(), path.GetData() );
wxString msg = wxString::Format(
_( "Footprint library\n'%s' saved as\n'%s'" ),
GetChars( curLibPath ), GetChars( dstLibPath ) );
DisplayInfoMessage( this, msg );
}
......@@ -99,24 +99,24 @@ 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." ),
AddMenuItem( fileMenu, ID_MODEDIT_SAVE_LIBRARY_AS,
_( "Save Current Library as Other" ),
_( "Save entire current library as new library." ),
wxNullBitmap );
#endif
// Save module
text = AddHotkeyName( _( "&Save Module in Active Library" ),
g_Module_Editor_Hokeys_Descr, HK_SAVE_MODULE );
AddMenuItem( fileMenu, ID_MODEDIT_SAVE_LIBMODULE, text,
_( "Save module in active library" ),
KiBitmap( save_library_xpm ) );
// Save module in new lib
AddMenuItem( fileMenu, ID_MODEDIT_CREATE_NEW_LIB_AND_SAVE_CURRENT_PART,
_( "S&ave Module in a New Library" ),
_( "Create new library and save current module" ),
_( "S&ave Module into a New Library" ),
_( "Create a new library and save current module into it" ),
KiBitmap( new_library_xpm ) );
// Export module
......
......@@ -255,15 +255,8 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break;
case ID_MODEDIT_DELETE_PART:
{
wxFileName fn = wxFileName( wxEmptyString, m_CurrentLib, FootprintLibFileExtension );
wxString full_libraryfilename = wxGetApp().FindLibraryPath( fn );
if( wxFileName::FileExists( full_libraryfilename ) )
Delete_Module_In_Library( full_libraryfilename );
DeleteModuleFromCurrentLibrary();
break;
}
case ID_MODEDIT_NEW_MODULE:
{
......@@ -288,8 +281,8 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
Zoom_Automatique( false );
}
break;
}
break;
case ID_MODEDIT_NEW_MODULE_FROM_WIZARD:
{
......@@ -332,20 +325,16 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
}
wizard->Destroy();
break;
}
break;
case ID_MODEDIT_SAVE_LIBMODULE:
if( GetBoard()->m_Modules == NULL )
break;
if( GetBoard()->m_Modules && getLibPath() != wxEmptyString )
{
wxFileName fn;
fn = wxFileName( wxEmptyString, m_CurrentLib, FootprintLibFileExtension );
wxString full_filename = wxGetApp().FindLibraryPath( fn );
Save_Module_In_Library( full_filename, GetBoard()->m_Modules, true, true );
Save_Module_In_Library( getLibPath(), GetBoard()->m_Modules, true, true );
GetScreen()->ClrModify();
break;
}
break;
case ID_MODEDIT_INSERT_MODULE_IN_BOARD:
case ID_MODEDIT_UPDATE_MODULE_IN_BOARD:
......@@ -451,12 +440,17 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
case ID_MODEDIT_EXPORT_PART:
if( GetBoard()->m_Modules )
Export_Module( GetBoard()->m_Modules, false );
Export_Module( GetBoard()->m_Modules );
break;
case ID_MODEDIT_CREATE_NEW_LIB_AND_SAVE_CURRENT_PART:
if( GetBoard()->m_Modules )
Export_Module( GetBoard()->m_Modules, true );
{
// CreateModuleLibrary() only creates a new library, does not save footprint
wxString libPath = CreateNewLibrary();
if( libPath.size() )
SaveCurrentModule( &libPath );
}
break;
case ID_MODEDIT_SHEET_SET:
......@@ -464,21 +458,15 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
case ID_MODEDIT_LOAD_MODULE:
{
wxString full_libraryfilename;
if( !m_CurrentLib.IsEmpty() )
{
wxFileName fn = wxFileName( wxEmptyString, m_CurrentLib, FootprintLibFileExtension );
full_libraryfilename = wxGetApp().FindLibraryPath( fn );
}
wxString libPath = getLibPath(); // might be empty
wxLogDebug( wxT( "Loading module from library " ) + full_libraryfilename );
wxLogDebug( wxT( "Loading module from library " ) + libPath );
GetScreen()->ClearUndoRedoList();
SetCurItem( NULL );
Clear_Pcb( true );
GetScreen()->SetCrossHairPosition( wxPoint( 0, 0 ) );
Load_Module_From_Library( full_libraryfilename, true );
Load_Module_From_Library( libPath, true );
redraw = true;
}
......@@ -566,17 +554,13 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break;
case ID_POPUP_PCB_MOVE_PAD_REQUEST:
{
m_canvas->MoveCursorToCrossHair();
StartMovePad( (D_PAD*) GetScreen()->GetCurItem(), &dc, false );
}
break;
case ID_POPUP_PCB_EDIT_PAD:
{
InstallPadOptionsFrame( (D_PAD*) GetScreen()->GetCurItem() );
m_canvas->MoveCursorToCrossHair();
}
break;
case ID_POPUP_PCB_DELETE_PAD:
......@@ -605,24 +589,18 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break;
case ID_POPUP_PCB_EDIT_TEXTMODULE:
{
InstallTextModOptionsFrame( (TEXTE_MODULE*) GetScreen()->GetCurItem(), &dc );
m_canvas->MoveCursorToCrossHair();
}
break;
case ID_POPUP_PCB_MOVE_TEXTMODULE_REQUEST:
{
m_canvas->MoveCursorToCrossHair();
StartMoveTexteModule( (TEXTE_MODULE*) GetScreen()->GetCurItem(), &dc );
}
break;
case ID_POPUP_PCB_ROTATE_TEXTMODULE:
{
RotateTextModule( (TEXTE_MODULE*) GetScreen()->GetCurItem(), &dc );
m_canvas->MoveCursorToCrossHair();
}
break;
case ID_POPUP_PCB_DELETE_TEXTMODULE:
......@@ -633,10 +611,8 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break;
case ID_POPUP_PCB_MOVE_EDGE:
{
Start_Move_EdgeMod( (EDGE_MODULE*) GetScreen()->GetCurItem(), &dc );
m_canvas->MoveCursorToCrossHair();
}
break;
case ID_POPUP_PCB_STOP_CURRENT_DRAWING:
......@@ -647,7 +623,6 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
End_Edge_Module( (EDGE_MODULE*) GetScreen()->GetCurItem() );
SetCurItem( NULL );
}
break;
case ID_POPUP_MODEDIT_ENTER_EDGE_WIDTH:
......
......@@ -7,12 +7,10 @@
#define MODULE_EDITOR_FRAME_H_
#include <wxBasePcbFrame.h>
#include <io_mgr.h>
class FOOTPRINT_EDIT_FRAME : public PCB_BASE_FRAME
{
public:
MODULE* CurrentModule;
public:
FOOTPRINT_EDIT_FRAME( PCB_EDIT_FRAME* aParent );
......@@ -223,34 +221,8 @@ public:
UNDO_REDO_T aTypeCommand,
const wxPoint& aTransformPoint = wxPoint( 0, 0 ) );
private:
static wxString m_CurrentLib;
static BOARD* s_Pcb; ///< retain board accross invocations of module editor
/**
* Function GetComponentFromUndoList
* performs an undo operation on the last edition:
* - Place the current edited library component in Redo list
* - Get old version of the current edited library component
*/
void GetComponentFromUndoList( wxCommandEvent& event );
/**
* Fucntion GetComponentFromRedoList
* performs a redo operation on the the last edition:
* - Place the current edited library component in undo list
* - Get old version of the current edited library component
*/
void GetComponentFromRedoList( wxCommandEvent& event );
/**
* Function UpdateTitle
* updates window title according to m_CurrentLib.
*/
void UpdateTitle();
wxString GetCurrentLib() const { return getLibNickName(); };
public:
// Footprint edition
void Place_Ancre( MODULE* module );
......@@ -272,10 +244,8 @@ public:
* So Create a new lib (which will contains one module) and export a footprint
* is basically the same thing
* @param aModule = the module to export
* @param aCreateSysLib : true = use default lib path to create lib
* false = use current path or last used path to export the footprint
*/
void Export_Module( MODULE* aModule, bool aCreateSysLib );
void Export_Module( MODULE* aModule );
/**
* Function Import_Module
......@@ -286,7 +256,26 @@ public:
* The import function can also read gpcb footprint file, in Newlib format
* (One footprint per file, Newlib files have no special ext.)
*/
MODULE* Import_Module( );
MODULE* Import_Module();
/**
* Function CreateNewLibrary
* prompts user for a library path, then creates a new footprint library at that
* location. If library exists, user is warned about that, and is given a chance
* to abort the new creation, and in that case existing library is first deleted.
*
* @return wxString - the newly created library path if library was successfully
* created, else wxEmptyString because user aborted or error.
*/
wxString CreateNewLibrary();
/**
* Function SaveCurrentModule
* saves the module which is currently being edited into aLibPath or into the
* currently selected library if aLibPath is NULL.
* @return bool - true if successfully saved, else false because abort or error.
*/
bool SaveCurrentModule( const wxString* aLibPath = NULL );
/**
* Function Load_Module_From_BOARD
......@@ -379,16 +368,54 @@ public:
*/
void DlgGlobalChange_PadSettings( D_PAD* aPad );
// handlers for libraries:
void Delete_Module_In_Library( const wxString& libname );
int CreateLibrary( const wxString& LibName );
/**
* Function DeleteModuleFromCurrentLibrary
* prompts user for footprint name, then deletes it from current library.
*/
bool DeleteModuleFromCurrentLibrary();
void Select_Active_Library();
wxString GetCurrentLib() const { return m_CurrentLib; };
DECLARE_EVENT_TABLE()
protected:
static BOARD* s_Pcb; ///< retain board accross invocations of module editor
/**
* Function GetComponentFromUndoList
* performs an undo operation on the last edition:
* - Place the current edited library component in Redo list
* - Get old version of the current edited library component
*/
void GetComponentFromUndoList( wxCommandEvent& event );
/**
* Function GetComponentFromRedoList
* performs a redo operation on the the last edition:
* - Place the current edited library component in undo list
* - Get old version of the current edited library component
*/
void GetComponentFromRedoList( wxCommandEvent& event );
/**
* Function UpdateTitle
* updates window title according to getLibNickName().
*/
void updateTitle();
// @todo these will eventually have to be made instance variables.
static wxString m_lib_nick_name;
static wxString m_lib_path;
/// The library nickName is a short string, for now the same as the library path
/// but without path and without extension. After library table support it becomes
/// a lookup key.
wxString getLibNickName() const { return m_lib_nick_name; }
void setLibNickName( const wxString& aLibNickName ) { m_lib_nick_name = aLibNickName; }
/// The libPath is the full string used in the PLUGIN::Footprint*() calls.
wxString getLibPath() const { return m_lib_path; }
void setLibPath( const wxString& aLibPath ) { m_lib_path = aLibPath; }
};
#endif // MODULE_EDITOR_FRAME_H_
......@@ -51,7 +51,8 @@
static PCB_SCREEN* s_screenModule; // the PCB_SCREEN used by the footprint editor
wxString FOOTPRINT_EDIT_FRAME::m_CurrentLib = wxEmptyString;
wxString FOOTPRINT_EDIT_FRAME::m_lib_nick_name;
wxString FOOTPRINT_EDIT_FRAME::m_lib_path;
BOARD* FOOTPRINT_EDIT_FRAME::s_Pcb;
......@@ -68,9 +69,7 @@ BEGIN_EVENT_TABLE( FOOTPRINT_EDIT_FRAME, PCB_BASE_FRAME )
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 )
......@@ -134,7 +133,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 )
......@@ -170,11 +169,12 @@ FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( PCB_EDIT_FRAME* aParent ) :
SetIcon( icon );
// Show a title (frame title + footprint name):
UpdateTitle();
updateTitle();
if( !s_Pcb )
{
s_Pcb = new BOARD();
// Ensure all layers and items are visible:
s_Pcb->SetVisibleAlls();
}
......@@ -344,7 +344,7 @@ void FOOTPRINT_EDIT_FRAME::OnUpdateVerticalToolbar( wxUpdateUIEvent& aEvent )
void FOOTPRINT_EDIT_FRAME::OnUpdateLibSelected( wxUpdateUIEvent& aEvent )
{
aEvent.Enable( m_CurrentLib != wxEmptyString );
aEvent.Enable( getLibPath() != wxEmptyString );
}
......@@ -356,7 +356,7 @@ void FOOTPRINT_EDIT_FRAME::OnUpdateModuleSelected( wxUpdateUIEvent& aEvent )
void FOOTPRINT_EDIT_FRAME::OnUpdateLibAndModuleSelected( wxUpdateUIEvent& aEvent )
{
aEvent.Enable( ( m_CurrentLib != wxEmptyString ) && ( GetBoard()->m_Modules != NULL ) );
aEvent.Enable( getLibPath() != wxEmptyString && GetBoard()->m_Modules != NULL );
}
......@@ -539,31 +539,42 @@ void FOOTPRINT_EDIT_FRAME::OnModify()
}
void FOOTPRINT_EDIT_FRAME::UpdateTitle()
void FOOTPRINT_EDIT_FRAME::updateTitle()
{
wxString title = _( "Module Editor " );
wxString libPath = getLibPath();
if( m_CurrentLib.IsEmpty() )
if( !libPath )
{
L_none:
title += _( "(no active library)" );
}
else
{
wxFileName fileName = wxFileName( wxEmptyString, m_CurrentLib, FootprintLibFileExtension );
fileName = wxGetApp().FindLibraryPath( fileName );
// See if we can open and test write-ability of the library.
IO_MGR::PCB_FILE_T pluginType = IO_MGR::GuessPluginTypeFromLibPath( libPath );
if( !fileName.IsOk() || !fileName.FileExists() )
{
title += _( "(no active library)" );
}
else
PLUGIN::RELEASER pi( IO_MGR::PluginFind( pluginType ) );
try
{
title = _( "Module Editor (active library: " ) + fileName.GetFullPath() + wxT( ")" );
bool writable = pi->IsFootprintLibWritable( libPath );
// no exception was thrown, this means libPath is valid, but it may be read only.
title = _( "Module Editor (active library: " ) + getLibNickName() + wxT( ")" );
if( !fileName.IsFileWritable() )
if( !writable )
title += _( " [Read Only]" );
}
catch( IO_ERROR ioe )
{
// user may be bewildered as to why after selecting a library it is not showing up
// in the title, we could show an error message, but that should have been done at time
// of libary selection UI.
goto L_none;
}
}
SetTitle( title );
}
......@@ -109,7 +109,7 @@ void FOOTPRINT_VIEWER_FRAME::SelectCurrentLibrary( wxCommandEvent& event )
*/
void FOOTPRINT_VIEWER_FRAME::SelectCurrentFootprint( wxCommandEvent& event )
{
wxString libname = m_libraryName + wxT(".") + FootprintLibFileExtension;
wxString libname = m_libraryName + wxT(".") + LegacyFootprintLibPathExtension;
MODULE* oldmodule = GetBoard()->m_Modules;
MODULE * module = Load_Module_From_Library( libname, false );
if( module )
......@@ -160,7 +160,7 @@ void FOOTPRINT_VIEWER_FRAME::SelectAndViewFootprint( int aMode )
SetCurItem( NULL );
// Delete the current footprint
GetBoard()->m_Modules.DeleteAll();
GetModuleLibrary( m_libraryName + wxT(".") + FootprintLibFileExtension,
GetModuleLibrary( m_libraryName + wxT(".") + LegacyFootprintLibPathExtension,
m_footprintName, true );
Update3D_Frame();
}
......
......@@ -190,7 +190,7 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( PCB_BASE_FRAME* parent,
// If a footprint was previsiously loaded, reload it
if( !m_libraryName.IsEmpty() && !m_footprintName.IsEmpty() )
GetModuleLibrary( m_libraryName + wxT(".") + FootprintLibFileExtension,
GetModuleLibrary( m_libraryName + wxT(".") + LegacyFootprintLibPathExtension,
m_footprintName, false );
......@@ -451,7 +451,7 @@ void FOOTPRINT_VIEWER_FRAME::ClickOnFootprintList( wxCommandEvent& event )
SetCurItem( NULL );
// Delete the current footprint
GetBoard()->m_Modules.DeleteAll();
GetModuleLibrary( m_libraryName + wxT(".") + FootprintLibFileExtension,
GetModuleLibrary( m_libraryName + wxT(".") + LegacyFootprintLibPathExtension,
m_footprintName, true );
DisplayLibInfos();
Zoom_Automatique( false );
......
......@@ -20,7 +20,6 @@ class TEXTE_MODULE;
class ZONE_CONTAINER;
class BOARD;
// Shared Config keys for plot and print
#define OPTKEY_LAYERBASE wxT( "PlotLayer_%d" )
#define OPTKEY_PRINT_X_FINESCALE_ADJ wxT( "PrintXFineScaleAdj" )
......@@ -127,14 +126,14 @@ private:
* the drill mark size depending on the current plot options
*/
void plotOneDrillMark( PAD_SHAPE_T aDrillShape,
const wxPoint &aDrillPos, wxSize aDrillSize,
const wxSize &aPadSize,
const wxPoint& aDrillPos, wxSize aDrillSize,
const wxSize& aPadSize,
double aOrientation, int aSmallDrill );
};
PLOTTER *StartPlotBoard( BOARD *aBoard,
PCB_PLOT_PARAMS *aPlotOpts,
PLOTTER* StartPlotBoard( BOARD* aBoard,
PCB_PLOT_PARAMS* aPlotOpts,
const wxString& aFullFileName,
const wxString& aSheetDesc );
......@@ -148,7 +147,7 @@ PLOTTER *StartPlotBoard( BOARD *aBoard,
* @param aLayer = the layer id to plot
* @param aPlotOpt = the plot options (files, sketch). Has meaning for some formats only
*/
void PlotOneBoardLayer( BOARD *aBoard, PLOTTER* aPlotter, int aLayer,
void PlotOneBoardLayer( BOARD* aBoard, PLOTTER* aPlotter, int aLayer,
const PCB_PLOT_PARAMS& aPlotOpt );
/**
......@@ -172,7 +171,7 @@ void PlotOneBoardLayer( BOARD *aBoard, PLOTTER* aPlotter, int aLayer,
* SetDrillMarksType( DrillMarksType aVal ) controle the actual hole:
* no hole, small hole, actual hole
*/
void PlotStandardLayer( BOARD *aBoard, PLOTTER* aPlotter, long aLayerMask,
void PlotStandardLayer( BOARD* aBoard, PLOTTER* aPlotter, long aLayerMask,
const PCB_PLOT_PARAMS& aPlotOpt );
/**
......@@ -184,7 +183,7 @@ void PlotStandardLayer( BOARD *aBoard, PLOTTER* aPlotter, long aLayerMask,
* @param aLayerMask = the mask to define the layers to plot (silkscreen Front and/or Back)
* @param aPlotOpt = the plot options (files, sketch). Has meaning for some formats only
*/
void PlotSilkScreen( BOARD *aBoard, PLOTTER* aPlotter, long aLayerMask,
void PlotSilkScreen( BOARD* aBoard, PLOTTER* aPlotter, long aLayerMask,
const PCB_PLOT_PARAMS& aPlotOpt );
......@@ -197,7 +196,7 @@ void PlotSilkScreen( BOARD *aBoard, PLOTTER* aPlotter, long aLayerMask,
* @param aBoardFilename = the board full filename
* @param aMessageBox = a wxMessageBox to show meesage (can be NULL)
*/
bool EnsureOutputDirectory( wxFileName *aOutputDir,
bool EnsureOutputDirectory( wxFileName* aOutputDir,
const wxString& aBoardFilename,
wxTextCtrl* aMessageBox );
......@@ -213,7 +212,7 @@ bool EnsureOutputDirectory( wxFileName *aOutputDir,
* @param aSuffix = the suffix to add to the base filename
* @param aExtension = the file extension
*/
void BuildPlotFileName( wxFileName *aFilename,
void BuildPlotFileName( wxFileName* aFilename,
const wxString& aOutputDir,
const wxString& aSuffix,
const wxString& aExtension );
......
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