29#include <wx/filename.h> 
   31#include <wx/translation.h> 
   34#include <wx/datetime.h> 
   48    default: 
return wxString::Format( 
_( 
"UNKNOWN (%d)" ), aFileType );
 
 
   56    if( aFileType == 
_( 
"KiCad" ) )
 
 
   68    default:                  
return nullptr;
 
 
   87                                          const wxString&              aOldFilePath,
 
   88                                          const wxString&              aNewFilePath )
 
  100    wxArrayString dbNames;
 
  101    wxFileName    newFileName( aNewFilePath );
 
  103    if( newFileName.HasExt() )
 
  105        wxString extraDir = newFileName.GetFullName();
 
  106        newFileName.ClearExt();
 
  107        newFileName.SetName( 
"" );
 
  108        newFileName.AppendDir( extraDir );
 
  111    if( !newFileName.DirExists() && !wxFileName::Mkdir( aNewFilePath, wxS_DIR_DEFAULT ) )
 
  116        bool bestEfforts = 
false; 
 
  117        oldFilePI->DesignBlockEnumerate( dbNames, aOldFilePath, bestEfforts, aOldFileProps );
 
  119        for( 
const wxString& dbName : dbNames )
 
  121            std::unique_ptr<const DESIGN_BLOCK> db(
 
  122                    oldFilePI->GetEnumeratedDesignBlock( aOldFilePath, dbName, aOldFileProps ) );
 
  123            kicadPI->DesignBlockSave( aNewFilePath, db.get() );
 
 
  144    wxDir libDir( aLibraryPath );
 
  146    if( !libDir.IsOpened() )
 
  152    bool     hasMoreFiles = libDir.GetFirst( &filename, wxEmptyString, wxDIR_DIRS );
 
  154    while( hasMoreFiles )
 
  156        wxFileName blockDir( aLibraryPath, filename );
 
  160            ts += 
TimestampDir( blockDir.GetFullPath(), wxT( 
"*" ) );
 
  162        hasMoreFiles = libDir.GetNext( &filename );
 
 
  170                                     const std::map<std::string, UTF8>* aProperties )
 
  172    if( wxDir::Exists( aLibraryPath ) )
 
  174        THROW_IO_ERROR( wxString::Format( 
_( 
"Cannot overwrite library path '%s'." ),
 
  175                                          aLibraryPath.GetData() ) );
 
  179    dir.SetPath( aLibraryPath );
 
  184                wxString::Format( 
_( 
"Library path '%s' could not be created.\n\n" 
  185                                     "Make sure you have write permissions and try again." ),
 
 
  192                                     const std::map<std::string, UTF8>* aProperties )
 
  195    fn.SetPath( aLibraryPath );
 
  198    if( !fn.DirExists() )
 
  201    if( !fn.IsDirWritable() )
 
  203        THROW_IO_ERROR( wxString::Format( 
_( 
"Insufficient permissions to delete folder '%s'." ),
 
  204                                          aLibraryPath.GetData() ) );
 
  207    wxDir dir( aLibraryPath );
 
  212        THROW_IO_ERROR( wxString::Format( 
_( 
"Library folder '%s' has unexpected files." ),
 
  213                                          aLibraryPath.GetData() ) );
 
  217    if( dir.HasSubDirs() )
 
  222        dir.GetAllFiles( aLibraryPath, &dirs, wxEmptyString, wxDIR_DIRS );
 
  224        for( 
size_t i = 0; i < dirs.GetCount(); i++ )
 
  226            wxFileName tmp = dirs[i];
 
  230                THROW_IO_ERROR( wxString::Format( 
_( 
"Unexpected folder '%s' found in library " 
  232                                                  dirs[i].GetData(), aLibraryPath.GetData() ) );
 
  236        for( 
size_t i = 0; i < dirs.GetCount(); i++ )
 
  237            wxRemoveFile( dirs[i] );
 
  241                aLibraryPath.GetData() );
 
  245    if( !wxFileName::Rmdir( aLibraryPath, wxPATH_RMDIR_RECURSIVE ) )
 
  247        THROW_IO_ERROR( wxString::Format( 
_( 
"Design block library '%s' cannot be deleted." ),
 
  248                                          aLibraryPath.GetData() ) );
 
  255    wxMilliSleep( 250L );
 
 
  263                                            const wxString& aLibraryPath, 
bool aBestEfforts,
 
  264                                            const std::map<std::string, UTF8>* aProperties )
 
  267    wxDir dir( aLibraryPath );
 
  269    if( !dir.IsOpened() )
 
  271        THROW_IO_ERROR( wxString::Format( 
_( 
"Design block '%s' does not exist." ), aLibraryPath ) );
 
  276    bool     cont = dir.GetFirst( &dirname, fileSpec, wxDIR_DIRS );
 
  280        aDesignBlockNames.Add( dirname.Before( wxT( 
'.' ) ) );
 
  281        cont = dir.GetNext( &dirname );
 
 
  287                                                const wxString& aDesignBlockName, 
bool aKeepUUID,
 
  288                                                const std::map<std::string, UTF8>* aProperties )
 
  290    wxString dbPath = aLibraryPath + wxFileName::GetPathSeparator() + aDesignBlockName + wxT( 
"." )
 
  292    wxString dbSchPath = dbPath + aDesignBlockName + wxT( 
"." )
 
  297    if( !wxDir::Exists( dbPath ) )
 
  298        THROW_IO_ERROR( wxString::Format( 
_( 
"Design block '%s' does not exist." ), dbPath ) );
 
  306    if( wxFileExists( dbSchPath ) )
 
  309    if( wxFileExists( dbPcbPath ) )
 
  313    if( wxFileExists( dbMetadataPath ) )
 
  317            nlohmann::ordered_json dbMetadata;
 
  318            std::ifstream          dbMetadataFile( dbMetadataPath.fn_str() );
 
  320            dbMetadataFile >> dbMetadata;
 
  322            if( dbMetadata.contains( 
"description" ) )
 
  325            if( dbMetadata.contains( 
"keywords" ) )
 
  329            if( dbMetadata.contains( 
"fields" ) )
 
  331                for( 
auto& item : dbMetadata[
"fields"].items() )
 
  333                    wxString 
name = wxString::FromUTF8( item.key() );
 
  334                    wxString value = wxString::FromUTF8( item.value().get<std::string>() );
 
  344                    _( 
"Design block metadata file '%s' could not be read." ), dbMetadataPath ) );
 
 
  353                                         const wxString&                    aDesignBlockName,
 
  354                                         const std::map<std::string, UTF8>* aProperties )
 
  356    wxString dbPath = aLibraryPath + wxFileName::GetPathSeparator() + aDesignBlockName + wxT( 
"." )
 
  359    return wxDir::Exists( dbPath );
 
 
  365                                       const std::map<std::string, UTF8>* aProperties )
 
  370        THROW_IO_ERROR( 
_( 
"Design block does not have a valid library ID." ) );
 
  375        THROW_IO_ERROR( 
_( 
"Design block does not have a schematic or board file." ) );
 
  381    if( !aDesignBlock->
GetSchematicFile().IsEmpty() && !schematicFile.FileExists() )
 
  384                wxString::Format( 
_( 
"Schematic source file '%s' does not exist." ), schematicFile.GetFullPath() ) );
 
  387    if( !aDesignBlock->
GetBoardFile().IsEmpty() && !boardFile.FileExists() )
 
  389        THROW_IO_ERROR( wxString::Format( 
_( 
"Board source file '%s' does not exist." ), boardFile.GetFullPath() ) );
 
  393    wxFileName dbFolder( aLibraryPath + wxFileName::GetPathSeparator()
 
  396                         + wxFileName::GetPathSeparator() );
 
  398    if( !dbFolder.DirExists() )
 
  400        if( !dbFolder.Mkdir() )
 
  402            THROW_IO_ERROR( wxString::Format( 
_( 
"Design block folder '%s' could not be created." ),
 
  403                                              dbFolder.GetFullPath().GetData() ) );
 
  410        wxString dbSchematicFile = dbFolder.GetFullPath() + aDesignBlock->
GetLibId().
GetLibItemName() + wxT( 
"." )
 
  415        if( schematicFile.GetFullPath() != dbSchematicFile )
 
  418            if( !wxCopyFile( schematicFile.GetFullPath(), dbSchematicFile ) )
 
  421                        wxString::Format( 
_( 
"Schematic file '%s' could not be saved as design block at '%s'." ),
 
  422                                          schematicFile.GetFullPath(), dbSchematicFile ) );
 
  435        if( boardFile.GetFullPath() != dbBoardFile )
 
  438            if( !wxCopyFile( boardFile.GetFullPath(), dbBoardFile ) )
 
  440                THROW_IO_ERROR( wxString::Format( 
_( 
"Board file '%s' could not be saved as design block at '%s'." ),
 
  441                                                  boardFile.GetFullPath(), dbBoardFile ) );
 
  450    nlohmann::ordered_json dbMetadata;
 
  452    dbMetadata[
"keywords"] = aDesignBlock->
GetKeywords();
 
  453    dbMetadata[
"fields"] = aDesignBlock->
GetFields();
 
  455    bool success = 
false;
 
  459        wxFFile mdFile( dbMetadataFile, wxT( 
"wb" ) );
 
  461        if( mdFile.IsOpened() )
 
  462            success = mdFile.Write( dbMetadata.dump( 0 ) );
 
  474                _( 
"Design block metadata file '%s' could not be saved." ), dbMetadataFile ) );
 
 
  480                                         const std::map<std::string, UTF8>* aProperties )
 
  482    wxFileName dbDir = wxFileName( aLibPath + wxFileName::GetPathSeparator() + aDesignBlockName
 
  485    if( !dbDir.DirExists() )
 
  488                wxString::Format( 
_( 
"Design block '%s' does not exist." ), dbDir.GetFullName() ) );
 
  492    if( !wxFileName::Rmdir( dbDir.GetFullPath(), wxPATH_RMDIR_RECURSIVE ) )
 
  494        THROW_IO_ERROR( wxString::Format( 
_( 
"Design block folder '%s' could not be deleted." ),
 
  495                                          dbDir.GetFullPath().GetData() ) );
 
 
  502    wxFileName 
path( aLibraryPath );
 
  503    return path.IsOk() && 
path.IsDirWritable();
 
 
@ KICAD_SEXP
S-expression KiCad file format.
 
@ DESIGN_BLOCK_FILE_UNKNOWN
0 is not a legal menu id on Mac
 
static const wxString ShowType(DESIGN_BLOCK_FILE_T aFileType)
 
static DESIGN_BLOCK_FILE_T GuessPluginTypeFromLibPath(const wxString &aLibPath, int aCtl=0)
 
static DESIGN_BLOCK_FILE_T EnumFromStr(const wxString &aFileType)
 
static bool ConvertLibrary(std::map< std::string, UTF8 > *aOldFileProps, const wxString &aOldFilePath, const wxString &aNewFilePath)
Convert a design block library to the latest KiCad format.
 
static DESIGN_BLOCK_IO * FindPlugin(DESIGN_BLOCK_FILE_T aFileType)
 
bool DesignBlockExists(const wxString &aLibraryPath, const wxString &aDesignBlockName, const std::map< std::string, UTF8 > *aProperties=nullptr)
 
long long GetLibraryTimestamp(const wxString &aLibraryPath) const
 
void DesignBlockDelete(const wxString &aLibraryPath, const wxString &aDesignBlockName, const std::map< std::string, UTF8 > *aProperties=nullptr)
 
DESIGN_BLOCK * DesignBlockLoad(const wxString &aLibraryPath, const wxString &aDesignBlockName, bool aKeepUUID=false, const std::map< std::string, UTF8 > *aProperties=nullptr)
 
void DesignBlockSave(const wxString &aLibraryPath, const DESIGN_BLOCK *aDesignBlock, const std::map< std::string, UTF8 > *aProperties=nullptr)
 
void DesignBlockEnumerate(wxArrayString &aDesignBlockNames, const wxString &aLibraryPath, bool aBestEfforts, const std::map< std::string, UTF8 > *aProperties=nullptr)
 
virtual bool DeleteLibrary(const wxString &aLibraryPath, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Delete an existing library and returns true, or if library does not exist returns false,...
 
void CreateLibrary(const wxString &aLibraryPath, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Create a new empty library at aLibraryPath empty.
 
bool IsLibraryWritable(const wxString &aLibraryPath) override
Return true if the library at aLibraryPath is writable.
 
const IO_BASE::IO_FILE_DESC GetLibraryDesc() const override
Get the descriptor for the library container that this IO plugin operates on.
 
void SetLibDescription(const wxString &aDesc)
 
void SetKeywords(const wxString &aKeywords)
 
void SetSchematicFile(const wxString &aFile)
 
void SetBoardFile(const wxString &aFile)
 
const wxString & GetKeywords() const
 
const wxString & GetLibDescription() const
 
void SetLibId(const LIB_ID &aName)
 
const wxString & GetBoardFile() const
 
const wxString & GetSchematicFile() const
 
const LIB_ID & GetLibId() const
 
const nlohmann::ordered_map< wxString, wxString > & GetFields() const
 
A logical library item identifier and consists of various portions much like a URI.
 
bool IsValid() const
Check if this LID_ID is valid.
 
const UTF8 & GetLibItemName() const
 
long long TimestampDir(const wxString &aDirPath, const wxString &aFilespec)
A copy of ConvertFileTimeToWx() because wxWidgets left it as a static function private to src/common/...
 
static const std::string KiCadDesignBlockLibPathExtension
 
static const std::string KiCadDesignBlockPathExtension
 
static const std::string JsonFileExtension
 
static const std::string KiCadSchematicFileExtension
 
static const std::string KiCadPcbFileExtension
 
const wxChar *const traceDesignBlocks
 
Some functions to handle hotkeys in KiCad.
 
std::unique_ptr< T > IO_RELEASER
Helper to hold and release an IO_BASE object when exceptions are thrown.
 
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
 
#define KICTL_NONKICAD_ONLY
chosen file is non-KiCad according to user
 
Container that describes file type info.
 
wxLogTrace helper definitions.
 
Definition of file extensions used in Kicad.