diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 652d8082e7..2bce31be3c 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -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 +================================================================================ +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 ================================================================================ 1) Switch to boost hashtable support from wx macros which did not handle std::string. diff --git a/CMakeLists.txt b/CMakeLists.txt index 2bdde92549..5c2e7fddce 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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. diff --git a/CMakeModules/config.h.cmake b/CMakeModules/config.h.cmake index 6882ff1108..159569b02f 100644 --- a/CMakeModules/config.h.cmake +++ b/CMakeModules/config.h.cmake @@ -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) diff --git a/common/basicframe.cpp b/common/basicframe.cpp index d677278dcf..e92c2701a4 100644 --- a/common/basicframe.cpp +++ b/common/basicframe.cpp @@ -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" ); diff --git a/common/footprint_info.cpp b/common/footprint_info.cpp index 5a5e415782..84c387ad44 100644 --- a/common/footprint_info.cpp +++ b/common/footprint_info.cpp @@ -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 ); diff --git a/common/wildcards_and_files_ext.cpp b/common/wildcards_and_files_ext.cpp index 651417c74b..adef81ba05 100644 --- a/common/wildcards_and_files_ext.cpp +++ b/common/wildcards_and_files_ext.cpp @@ -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: diff --git a/cvpcb/dialogs/dialog_cvpcb_config.cpp b/cvpcb/dialogs/dialog_cvpcb_config.cpp index 24f1faea21..7ffa02d5cc 100644 --- a/cvpcb/dialogs/dialog_cvpcb_config.cpp +++ b/cvpcb/dialogs/dialog_cvpcb_config.cpp @@ -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; diff --git a/cvpcb/loadcmp.cpp b/cvpcb/loadcmp.cpp index 4b4c679798..d01699a8be 100644 --- a/cvpcb/loadcmp.cpp +++ b/cvpcb/loadcmp.cpp @@ -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 ); diff --git a/include/wildcards_and_files_ext.h b/include/wildcards_and_files_ext.h index 28cf5db4c1..330a22e217 100644 --- a/include/wildcards_and_files_ext.h +++ b/include/wildcards_and_files_ext.h @@ -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_ diff --git a/pcbnew/class_board_item.cpp b/pcbnew/class_board_item.cpp index 15621107c9..82718a486c 100644 --- a/pcbnew/class_board_item.cpp +++ b/pcbnew/class_board_item.cpp @@ -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 ); } diff --git a/pcbnew/dialogs/dialog_pcbnew_config_libs_and_paths.cpp b/pcbnew/dialogs/dialog_pcbnew_config_libs_and_paths.cpp index da17ab87c7..7813c5c58e 100644 --- a/pcbnew/dialogs/dialog_pcbnew_config_libs_and_paths.cpp +++ b/pcbnew/dialogs/dialog_pcbnew_config_libs_and_paths.cpp @@ -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 ) diff --git a/pcbnew/eagle_plugin.cpp b/pcbnew/eagle_plugin.cpp index 2f872a6328..1a11a6eeaf 100644 --- a/pcbnew/eagle_plugin.cpp +++ b/pcbnew/eagle_plugin.cpp @@ -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 ) { } diff --git a/pcbnew/eagle_plugin.h b/pcbnew/eagle_plugin.h index 3b48141897..816b2bb1ba 100644 --- a/pcbnew/eagle_plugin.h +++ b/pcbnew/eagle_plugin.h @@ -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 ); */ diff --git a/pcbnew/files.cpp b/pcbnew/files.cpp index ce754602c5..85b679fe59 100644 --- a/pcbnew/files.cpp +++ b/pcbnew/files.cpp @@ -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; @@ -487,8 +487,8 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool aCreateBackupF try { - PROPERTIES props; - PLUGIN* plugin = IO_MGR::PluginFind( ( IO_MGR::PCB_FILE_T ) wildcardIndex ); + PROPERTIES props; + PLUGIN* plugin = IO_MGR::PluginFind( pluginType ); if( plugin == NULL ) THROW_IO_ERROR( wxString::Format( _( "cannot find file plug in for file format '%s'" ), diff --git a/pcbnew/io_mgr.cpp b/pcbnew/io_mgr.cpp index 725b7f0aca..1f32f77bea 100644 --- a/pcbnew/io_mgr.cpp +++ b/pcbnew/io_mgr.cpp @@ -22,12 +22,13 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +#include #include #include #include #include - +#include #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__ ) ); diff --git a/pcbnew/io_mgr.h b/pcbnew/io_mgr.h index 895ddbdb18..85ec6ebc16 100644 --- a/pcbnew/io_mgr.h +++ b/pcbnew/io_mgr.h @@ -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 ); + //---------------------------------- + /** * 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 ); diff --git a/pcbnew/kicad_plugin.cpp b/pcbnew/kicad_plugin.cpp index 81f1fbd89e..a40016419f 100644 --- a/pcbnew/kicad_plugin.cpp +++ b/pcbnew/kicad_plugin.cpp @@ -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; } diff --git a/pcbnew/kicad_plugin.h b/pcbnew/kicad_plugin.h index 4aaabddbee..cb6a387ae6 100644 --- a/pcbnew/kicad_plugin.h +++ b/pcbnew/kicad_plugin.h @@ -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 ); diff --git a/pcbnew/legacy_plugin.cpp b/pcbnew/legacy_plugin.cpp index dc0b699974..cf565fb466 100644 --- a/pcbnew/legacy_plugin.cpp +++ b/pcbnew/legacy_plugin.cpp @@ -5,7 +5,6 @@ * Copyright (C) 2007-2012 SoftPLC Corporation, Dick Hollenbeck * 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; } diff --git a/pcbnew/legacy_plugin.h b/pcbnew/legacy_plugin.h index 497243e1a8..82d0681e6c 100644 --- a/pcbnew/legacy_plugin.h +++ b/pcbnew/legacy_plugin.h @@ -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 ); diff --git a/pcbnew/librairi.cpp b/pcbnew/librairi.cpp index 21e9fc5871..cd608fc11b 100644 --- a/pcbnew/librairi.cpp +++ b/pcbnew/librairi.cpp @@ -27,15 +27,43 @@ #include +// 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; - wxFileDialog dlg( this, _( "Import Footprint Module" ), + wildCard << wxGetTranslation( KiCadFootprintLibFileWildcard ) << wxChar( '|' ) + << wxGetTranslation( ModExportFileWildcard ) << wxChar( '|' ) + << wxGetTranslation( ModImportFileWildcard ); + + 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,30 +228,29 @@ 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(); + wxFileName fn; + wxConfig* config = wxGetApp().GetSettings(); if( aModule == NULL ) return; 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 ); - config->Read( EXPORT_IMPORT_LASTPATH_KEY, &path ); - fn.SetPath( path ); + 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; - - // Confirmation - wxString msg = wxString::Format( _( "Ok to delete module '%s' in library '%s'" ), - footprintName.GetData(), aLibName.GetData() ); - - if( !IsOK( this, msg ) ) - return; + IO_MGR::PCB_FILE_T piType = IO_MGR::GuessPluginTypeFromLibPath( libPath ); try { - PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::LEGACY ) ); + PLUGIN::RELEASER pi( IO_MGR::PluginFind( piType ) ); - pi->FootprintDelete( aLibName, footprintName ); + 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( FMT_OK_DELETE, footprintName.GetData(), libPath.GetData() ); + + if( !IsOK( this, msg ) ) + return false; + + IO_MGR::PCB_FILE_T pluginType = IO_MGR::GuessPluginTypeFromLibPath( libPath ); + + try + { + PLUGIN::RELEASER pi( IO_MGR::PluginFind( pluginType ) ); + + 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() ) ); + wxString msg = wxString::Format( FMT_BAD_PATHS, GetChars( dlg.GetTextSelection() ) ); DisplayError( this, msg ); - m_CurrentLib.Empty(); + + setLibNickName( wxEmptyString ); + setLibPath( wxEmptyString ); } - UpdateTitle(); + 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() ); - - 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; - } - - return 1; // remember how many times we succeeded -} diff --git a/pcbnew/loadcmp.cpp b/pcbnew/loadcmp.cpp index b5d3778a19..75ec660f7e 100644 --- a/pcbnew/loadcmp.cpp +++ b/pcbnew/loadcmp.cpp @@ -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; + wxString curLibPath = getLibPath(); + wxString dstLibPath = CreateNewLibrary(); - title = _( "Save Footprint Library As" ); + if( !dstLibPath ) + return; // user aborted in CreateNewLibrary() - 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(); + 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 + wxArrayString mods = cur->FootprintEnumerate( curLibPath ); + + for( unsigned i = 0; i < mods.size(); ++i ) { - // 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. - } + std::auto_ptr m( cur->FootprintLoad( curLibPath, mods[i] ) ); + dst->FootprintSave( dstLibPath, m.get() ); - pi->FootprintLibCreate( fn.GetPath() ); - - wxArrayString libNameList; - - 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 ); - - 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 ); } diff --git a/pcbnew/menubar_modedit.cpp b/pcbnew/menubar_modedit.cpp index 8954b9b2f9..890684e00c 100644 --- a/pcbnew/menubar_modedit.cpp +++ b/pcbnew/menubar_modedit.cpp @@ -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 diff --git a/pcbnew/modedit.cpp b/pcbnew/modedit.cpp index 8aa62a831e..74d8a3487e 100644 --- a/pcbnew/modedit.cpp +++ b/pcbnew/modedit.cpp @@ -232,201 +232,190 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) case ID_OPEN_MODULE_VIEWER: { - FOOTPRINT_VIEWER_FRAME * viewer = FOOTPRINT_VIEWER_FRAME::GetActiveFootprintViewer(); - if( viewer == NULL ) - { - viewer = new FOOTPRINT_VIEWER_FRAME( this, NULL ); - viewer->Show( true ); - viewer->Zoom_Automatique( false ); - } - else - { - if( viewer->IsIconized() ) - viewer->Iconize( false ); + FOOTPRINT_VIEWER_FRAME * viewer = FOOTPRINT_VIEWER_FRAME::GetActiveFootprintViewer(); + if( viewer == NULL ) + { + viewer = new FOOTPRINT_VIEWER_FRAME( this, NULL ); + viewer->Show( true ); + viewer->Zoom_Automatique( false ); + } + else + { + if( viewer->IsIconized() ) + viewer->Iconize( false ); - viewer->Raise(); + viewer->Raise(); - // Raising the window does not set the focus on Linux. This should work on - // any platform. - if( wxWindow::FindFocus() != viewer ) - viewer->SetFocus(); - } + // Raising the window does not set the focus on Linux. This should work on + // any platform. + if( wxWindow::FindFocus() != viewer ) + viewer->SetFocus(); + } } 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: - { - Clear_Pcb( true ); - GetScreen()->ClearUndoRedoList(); - SetCurItem( NULL ); - GetScreen()->SetCrossHairPosition( wxPoint( 0, 0 ) ); - - MODULE* module = Create_1_Module( wxEmptyString ); - - if( module ) // i.e. if create module command not aborted { - // Initialize data relative to nets and netclasses (for a new - // module the defaults are used) - // This is mandatory to handle and draw pads - GetBoard()->BuildListOfNets(); - redraw = true; - module->SetPosition( wxPoint( 0, 0 ) ); + Clear_Pcb( true ); + GetScreen()->ClearUndoRedoList(); + SetCurItem( NULL ); + GetScreen()->SetCrossHairPosition( wxPoint( 0, 0 ) ); - if( GetBoard()->m_Modules ) - GetBoard()->m_Modules->ClearFlags(); + MODULE* module = Create_1_Module( wxEmptyString ); - Zoom_Automatique( false ); + if( module ) // i.e. if create module command not aborted + { + // Initialize data relative to nets and netclasses (for a new + // module the defaults are used) + // This is mandatory to handle and draw pads + GetBoard()->BuildListOfNets(); + redraw = true; + module->SetPosition( wxPoint( 0, 0 ) ); + + if( GetBoard()->m_Modules ) + GetBoard()->m_Modules->ClearFlags(); + + Zoom_Automatique( false ); + } } break; - } - case ID_MODEDIT_NEW_MODULE_FROM_WIZARD: - { - Clear_Pcb( true ); - GetScreen()->ClearUndoRedoList(); - SetCurItem( NULL ); - GetScreen()->SetCrossHairPosition( wxPoint( 0, 0 ) ); - - wxSemaphore semaphore( 0, 1 ); - FOOTPRINT_WIZARD_FRAME *wizard = new FOOTPRINT_WIZARD_FRAME( this, &semaphore, - KICAD_DEFAULT_DRAWFRAME_STYLE | wxFRAME_FLOAT_ON_PARENT ); - wizard->Show( true ); - wizard->Zoom_Automatique( false ); - - while( semaphore.TryWait() == wxSEMA_BUSY ) // Wait for viewer closing event + case ID_MODEDIT_NEW_MODULE_FROM_WIZARD: { - wxYield(); - wxMilliSleep( 50 ); + Clear_Pcb( true ); + GetScreen()->ClearUndoRedoList(); + SetCurItem( NULL ); + GetScreen()->SetCrossHairPosition( wxPoint( 0, 0 ) ); + + wxSemaphore semaphore( 0, 1 ); + FOOTPRINT_WIZARD_FRAME *wizard = new FOOTPRINT_WIZARD_FRAME( this, &semaphore, + KICAD_DEFAULT_DRAWFRAME_STYLE | wxFRAME_FLOAT_ON_PARENT ); + wizard->Show( true ); + wizard->Zoom_Automatique( false ); + + while( semaphore.TryWait() == wxSEMA_BUSY ) // Wait for viewer closing event + { + wxYield(); + wxMilliSleep( 50 ); + } + + MODULE* module = wizard->GetBuiltFootprint(); + + if( module ) // i.e. if create module command not aborted + { + /* Here we should make a copy of the object before adding to board*/ + module->SetParent( (EDA_ITEM*)GetBoard() ); + GetBoard()->m_Modules.Append( module ); + + // Initialize data relative to nets and netclasses (for a new + // module the defaults are used) + // This is mandatory to handle and draw pads + GetBoard()->BuildListOfNets(); + redraw = true; + module->SetPosition( wxPoint( 0, 0 ) ); + + if( GetBoard()->m_Modules ) + GetBoard()->m_Modules->ClearFlags(); + + + } + + wizard->Destroy(); } - - MODULE* module = wizard->GetBuiltFootprint(); - - if( module ) // i.e. if create module command not aborted - { - /* Here we should make a copy of the object before adding to board*/ - module->SetParent( (EDA_ITEM*)GetBoard() ); - GetBoard()->m_Modules.Append( module ); - - // Initialize data relative to nets and netclasses (for a new - // module the defaults are used) - // This is mandatory to handle and draw pads - GetBoard()->BuildListOfNets(); - redraw = true; - module->SetPosition( wxPoint( 0, 0 ) ); - - if( GetBoard()->m_Modules ) - GetBoard()->m_Modules->ClearFlags(); - - - } - - wizard->Destroy(); break; - } case ID_MODEDIT_SAVE_LIBMODULE: - if( GetBoard()->m_Modules == NULL ) - break; - { - 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 ); - GetScreen()->ClrModify(); + if( GetBoard()->m_Modules && getLibPath() != wxEmptyString ) + { + Save_Module_In_Library( getLibPath(), GetBoard()->m_Modules, true, true ); + GetScreen()->ClrModify(); + } break; - } case ID_MODEDIT_INSERT_MODULE_IN_BOARD: case ID_MODEDIT_UPDATE_MODULE_IN_BOARD: - { - // update module in the current board, - // not just add it to the board with total disregard for the netlist... - PCB_EDIT_FRAME* pcbframe = (PCB_EDIT_FRAME*) GetParent(); - BOARD* mainpcb = pcbframe->GetBoard(); - MODULE* source_module = NULL; - MODULE* module_in_edit = GetBoard()->m_Modules; - - // Search the old module (source) if exists - // Because this source could be deleted when editing the main board... - if( module_in_edit->m_Link ) // this is not a new module ... { - source_module = mainpcb->m_Modules; + // update module in the current board, + // not just add it to the board with total disregard for the netlist... + PCB_EDIT_FRAME* pcbframe = (PCB_EDIT_FRAME*) GetParent(); + BOARD* mainpcb = pcbframe->GetBoard(); + MODULE* source_module = NULL; + MODULE* module_in_edit = GetBoard()->m_Modules; - for( ; source_module != NULL; source_module = (MODULE*) source_module->Next() ) + // Search the old module (source) if exists + // Because this source could be deleted when editing the main board... + if( module_in_edit->m_Link ) // this is not a new module ... { - if( module_in_edit->m_Link == source_module->GetTimeStamp() ) - break; + source_module = mainpcb->m_Modules; + + for( ; source_module != NULL; source_module = (MODULE*) source_module->Next() ) + { + if( module_in_edit->m_Link == source_module->GetTimeStamp() ) + break; + } } + + if( ( source_module == NULL ) + && ( id == ID_MODEDIT_UPDATE_MODULE_IN_BOARD ) ) // source not found + { + wxString msg; + msg.Printf( _( "Unable to find the footprint source on the main board" ) ); + msg << _( "\nCannot update the footprint" ); + DisplayError( this, msg ); + break; + } + + if( ( source_module != NULL ) + && ( id == ID_MODEDIT_INSERT_MODULE_IN_BOARD ) ) // source not found + { + wxString msg; + msg.Printf( _( "A footprint source was found on the main board" ) ); + msg << _( "\nCannot insert this footprint" ); + DisplayError( this, msg ); + break; + } + + // Create the "new" module + MODULE* newmodule = new MODULE( *module_in_edit ); + newmodule->SetParent( mainpcb ); + newmodule->m_Link = 0; + + // Put the footprint in the main pcb linked list. + mainpcb->Add( newmodule ); + + if( source_module ) // this is an update command + { + // In the main board, + // the new module replace the old module (pos, orient, ref, value + // and connexions are kept) + // and the source_module (old module) is deleted + PICKED_ITEMS_LIST pickList; + pcbframe->Exchange_Module( source_module, newmodule, &pickList ); + newmodule->SetTimeStamp( module_in_edit->m_Link ); + + if( pickList.GetCount() ) + pcbframe->SaveCopyInUndoList( pickList, UR_UNSPECIFIED ); + } + else // This is an insert command + { + wxPoint cursor_pos = pcbframe->GetScreen()->GetCrossHairPosition(); + pcbframe->GetScreen()->SetCrossHairPosition( wxPoint( 0, 0 ) ); + pcbframe->PlaceModule( newmodule, NULL ); + pcbframe->GetScreen()->SetCrossHairPosition( cursor_pos ); + newmodule->SetTimeStamp( GetNewTimeStamp() ); + pcbframe->SaveCopyInUndoList( newmodule, UR_NEW ); + } + + newmodule->ClearFlags(); + GetScreen()->ClrModify(); + pcbframe->SetCurItem( NULL ); + mainpcb->m_Status_Pcb = 0; } - - if( ( source_module == NULL ) - && ( id == ID_MODEDIT_UPDATE_MODULE_IN_BOARD ) ) // source not found - { - wxString msg; - msg.Printf( _( "Unable to find the footprint source on the main board" ) ); - msg << _( "\nCannot update the footprint" ); - DisplayError( this, msg ); - break; - } - - if( ( source_module != NULL ) - && ( id == ID_MODEDIT_INSERT_MODULE_IN_BOARD ) ) // source not found - { - wxString msg; - msg.Printf( _( "A footprint source was found on the main board" ) ); - msg << _( "\nCannot insert this footprint" ); - DisplayError( this, msg ); - break; - } - - // Create the "new" module - MODULE* newmodule = new MODULE( *module_in_edit ); - newmodule->SetParent( mainpcb ); - newmodule->m_Link = 0; - - // Put the footprint in the main pcb linked list. - mainpcb->Add( newmodule ); - - if( source_module ) // this is an update command - { - // In the main board, - // the new module replace the old module (pos, orient, ref, value - // and connexions are kept) - // and the source_module (old module) is deleted - PICKED_ITEMS_LIST pickList; - pcbframe->Exchange_Module( source_module, newmodule, &pickList ); - newmodule->SetTimeStamp( module_in_edit->m_Link ); - - if( pickList.GetCount() ) - pcbframe->SaveCopyInUndoList( pickList, UR_UNSPECIFIED ); - } - else // This is an insert command - { - wxPoint cursor_pos = pcbframe->GetScreen()->GetCrossHairPosition(); - pcbframe->GetScreen()->SetCrossHairPosition( wxPoint( 0, 0 ) ); - pcbframe->PlaceModule( newmodule, NULL ); - pcbframe->GetScreen()->SetCrossHairPosition( cursor_pos ); - newmodule->SetTimeStamp( GetNewTimeStamp() ); - pcbframe->SaveCopyInUndoList( newmodule, UR_NEW ); - } - - newmodule->ClearFlags(); - GetScreen()->ClrModify(); - pcbframe->SetCurItem( NULL ); - mainpcb->m_Status_Pcb = 0; - } - break; + break; case ID_MODEDIT_IMPORT_PART: if( ! Clear_Pcb( true ) ) @@ -451,37 +440,36 @@ 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: break; 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 " ) + libPath ); + + GetScreen()->ClearUndoRedoList(); + SetCurItem( NULL ); + Clear_Pcb( true ); + GetScreen()->SetCrossHairPosition( wxPoint( 0, 0 ) ); + Load_Module_From_Library( libPath, true ); + redraw = true; } - wxLogDebug( wxT( "Loading module from library " ) + full_libraryfilename ); - - GetScreen()->ClearUndoRedoList(); - SetCurItem( NULL ); - Clear_Pcb( true ); - GetScreen()->SetCrossHairPosition( wxPoint( 0, 0 ) ); - Load_Module_From_Library( full_libraryfilename, true ); - redraw = true; - } - if( GetBoard()->m_Modules ) GetBoard()->m_Modules->ClearFlags(); @@ -553,30 +541,26 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) break; case ID_POPUP_PCB_EDIT_MODULE: - { - DIALOG_MODULE_MODULE_EDITOR dialog( this, (MODULE*) GetScreen()->GetCurItem() ); - int ret = dialog.ShowModal(); - GetScreen()->GetCurItem()->ClearFlags(); - GetScreen()->GetCurItem()->ClearFlags(); - m_canvas->MoveCursorToCrossHair(); + { + DIALOG_MODULE_MODULE_EDITOR dialog( this, (MODULE*) GetScreen()->GetCurItem() ); + int ret = dialog.ShowModal(); + GetScreen()->GetCurItem()->ClearFlags(); + GetScreen()->GetCurItem()->ClearFlags(); + m_canvas->MoveCursorToCrossHair(); - if( ret > 0 ) - m_canvas->Refresh(); - } - break; + if( ret > 0 ) + m_canvas->Refresh(); + } + break; case ID_POPUP_PCB_MOVE_PAD_REQUEST: - { m_canvas->MoveCursorToCrossHair(); StartMovePad( (D_PAD*) GetScreen()->GetCurItem(), &dc, false ); - } - break; + break; case ID_POPUP_PCB_EDIT_PAD: - { InstallPadOptionsFrame( (D_PAD*) GetScreen()->GetCurItem() ); m_canvas->MoveCursorToCrossHair(); - } break; case ID_POPUP_PCB_DELETE_PAD: @@ -605,25 +589,19 @@ 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; + break; case ID_POPUP_PCB_MOVE_TEXTMODULE_REQUEST: - { m_canvas->MoveCursorToCrossHair(); StartMoveTexteModule( (TEXTE_MODULE*) GetScreen()->GetCurItem(), &dc ); - } - break; + break; case ID_POPUP_PCB_ROTATE_TEXTMODULE: - { RotateTextModule( (TEXTE_MODULE*) GetScreen()->GetCurItem(), &dc ); m_canvas->MoveCursorToCrossHair(); - } - break; + break; case ID_POPUP_PCB_DELETE_TEXTMODULE: SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT ); @@ -633,11 +611,9 @@ 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; + break; case ID_POPUP_PCB_STOP_CURRENT_DRAWING: m_canvas->MoveCursorToCrossHair(); @@ -647,25 +623,24 @@ 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: - { - EDGE_MODULE* edge = NULL; - if( GetScreen()->GetCurItem() - && ( GetScreen()->GetCurItem()->Type() == PCB_MODULE_EDGE_T ) ) { - edge = (EDGE_MODULE*) GetScreen()->GetCurItem(); + EDGE_MODULE* edge = NULL; + if( GetScreen()->GetCurItem() + && ( GetScreen()->GetCurItem()->Type() == PCB_MODULE_EDGE_T ) ) + { + edge = (EDGE_MODULE*) GetScreen()->GetCurItem(); + } + + Enter_Edge_Width( edge ); + m_canvas->MoveCursorToCrossHair(); + + if( edge ) + m_canvas->Refresh(); } - - Enter_Edge_Width( edge ); - m_canvas->MoveCursorToCrossHair(); - - if( edge ) - m_canvas->Refresh(); - } - break; + break; case ID_POPUP_MODEDIT_EDIT_BODY_ITEM : m_canvas->MoveCursorToCrossHair(); @@ -716,18 +691,18 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) break; case ID_PCB_PAD_SETUP: - { - BOARD_ITEM* item = GetCurItem(); - - if( item ) { - if( item->Type() != PCB_PAD_T ) - item = NULL; - } + BOARD_ITEM* item = GetCurItem(); - InstallPadOptionsFrame( (D_PAD*) item ); - } - break; + if( item ) + { + if( item->Type() != PCB_PAD_T ) + item = NULL; + } + + InstallPadOptionsFrame( (D_PAD*) item ); + } + break; case ID_PCB_USER_GRID_SETUP: InstallGridFrame( pos ); diff --git a/pcbnew/module_editor_frame.h b/pcbnew/module_editor_frame.h index a764291941..c032b671e2 100644 --- a/pcbnew/module_editor_frame.h +++ b/pcbnew/module_editor_frame.h @@ -7,12 +7,10 @@ #define MODULE_EDITOR_FRAME_H_ #include +#include 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; + wxString GetCurrentLib() const { return getLibNickName(); }; - 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(); - -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_ diff --git a/pcbnew/moduleframe.cpp b/pcbnew/moduleframe.cpp index e45848a5af..bb676a423d 100644 --- a/pcbnew/moduleframe.cpp +++ b/pcbnew/moduleframe.cpp @@ -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 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 - { - title = _( "Module Editor (active library: " ) + fileName.GetFullPath() + wxT( ")" ); + PLUGIN::RELEASER pi( IO_MGR::PluginFind( pluginType ) ); - if( !fileName.IsFileWritable() ) + try + { + 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( !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 ); } + diff --git a/pcbnew/modview.cpp b/pcbnew/modview.cpp index 5b30206376..b29bef96e3 100644 --- a/pcbnew/modview.cpp +++ b/pcbnew/modview.cpp @@ -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(); } diff --git a/pcbnew/modview_frame.cpp b/pcbnew/modview_frame.cpp index fbf7106f71..5b6c2cce39 100644 --- a/pcbnew/modview_frame.cpp +++ b/pcbnew/modview_frame.cpp @@ -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 ); diff --git a/pcbnew/pcbplot.h b/pcbnew/pcbplot.h index ae32f3da3a..f61aa4efa2 100644 --- a/pcbnew/pcbplot.h +++ b/pcbnew/pcbplot.h @@ -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 );