From 2aa27122b0032585a0f754d6e6fa65b7d01ff64d Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Mon, 19 Nov 2012 10:19:38 -0600 Subject: [PATCH] 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. --- CHANGELOG.txt | 10 + CMakeLists.txt | 12 - CMakeModules/config.h.cmake | 2 - common/basicframe.cpp | 14 - common/footprint_info.cpp | 2 +- common/wildcards_and_files_ext.cpp | 15 +- cvpcb/dialogs/dialog_cvpcb_config.cpp | 2 +- cvpcb/loadcmp.cpp | 2 +- include/wildcards_and_files_ext.h | 10 +- pcbnew/class_board_item.cpp | 7 +- .../dialog_pcbnew_config_libs_and_paths.cpp | 2 +- pcbnew/eagle_plugin.cpp | 2 +- pcbnew/eagle_plugin.h | 2 +- pcbnew/files.cpp | 18 +- pcbnew/io_mgr.cpp | 24 +- pcbnew/io_mgr.h | 21 +- pcbnew/kicad_plugin.cpp | 12 +- pcbnew/kicad_plugin.h | 2 +- pcbnew/legacy_plugin.cpp | 15 +- pcbnew/legacy_plugin.h | 2 +- pcbnew/librairi.cpp | 375 +++++++++------ pcbnew/loadcmp.cpp | 74 +-- pcbnew/menubar_modedit.cpp | 12 +- pcbnew/modedit.cpp | 445 +++++++++--------- pcbnew/module_editor_frame.h | 107 +++-- pcbnew/moduleframe.cpp | 51 +- pcbnew/modview.cpp | 4 +- pcbnew/modview_frame.cpp | 4 +- pcbnew/pcbplot.h | 19 +- 29 files changed, 684 insertions(+), 583 deletions(-) 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 );