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() )
274 bool cont = dir.GetFirst( &dirname, fileSpec, wxDIR_DIRS );
278 aDesignBlockNames.Add( dirname.Before( wxT(
'.' ) ) );
279 cont = dir.GetNext( &dirname );
285 const wxString& aDesignBlockName,
bool aKeepUUID,
286 const std::map<std::string, UTF8>* aProperties )
288 wxString dbPath = aLibraryPath + wxFileName::GetPathSeparator() + aDesignBlockName + wxT(
"." )
290 wxString dbSchPath = dbPath + aDesignBlockName + wxT(
"." )
294 if( !wxFileExists( dbSchPath ) )
305 if( wxFileExists( dbMetadataPath ) )
309 nlohmann::ordered_json dbMetadata;
310 std::ifstream dbMetadataFile( dbMetadataPath.fn_str() );
312 dbMetadataFile >> dbMetadata;
314 if( dbMetadata.contains(
"description" ) )
317 if( dbMetadata.contains(
"keywords" ) )
320 nlohmann::ordered_map<wxString, wxString> fields;
323 if( dbMetadata.contains(
"fields" ) )
325 for(
auto& item : dbMetadata[
"fields"].items() )
327 wxString
name = wxString::FromUTF8( item.key() );
328 wxString value = wxString::FromUTF8( item.value().get<std::string>() );
330 fields[
name] = value;
339 _(
"Design block metadata file '%s' could not be read." ), dbMetadataPath ) );
350 const std::map<std::string, UTF8>* aProperties )
355 THROW_IO_ERROR(
_(
"Design block does not have a valid library ID." ) );
360 if( !schematicFile.FileExists() )
362 THROW_IO_ERROR( wxString::Format(
_(
"Schematic source file '%s' does not exist." ),
363 schematicFile.GetFullPath() ) );
367 wxFileName dbFolder( aLibraryPath + wxFileName::GetPathSeparator()
370 + wxFileName::GetPathSeparator() );
372 if( !dbFolder.DirExists() )
374 if( !dbFolder.Mkdir() )
376 THROW_IO_ERROR( wxString::Format(
_(
"Design block folder '%s' could not be created." ),
377 dbFolder.GetFullPath().GetData() ) );
387 if( schematicFile.GetFullPath() != dbSchematicFile )
390 if( !wxCopyFile( schematicFile.GetFullPath(), dbSchematicFile ) )
393 _(
"Schematic file '%s' could not be saved as design block at '%s'." ),
394 schematicFile.GetFullPath(), dbSchematicFile ) );
403 nlohmann::ordered_json dbMetadata;
405 dbMetadata[
"keywords"] = aDesignBlock->
GetKeywords();
406 dbMetadata[
"fields"] = aDesignBlock->
GetFields();
408 bool success =
false;
412 wxFFile mdFile( dbMetadataFile, wxT(
"wb" ) );
414 if( mdFile.IsOpened() )
415 success = mdFile.Write( dbMetadata.dump( 0 ) );
427 _(
"Design block metadata file '%s' could not be saved." ), dbMetadataFile ) );
433 const std::map<std::string, UTF8>* aProperties )
435 wxFileName dbDir = wxFileName( aLibPath + wxFileName::GetPathSeparator() + aDesignBlockName
438 if( !dbDir.DirExists() )
441 wxString::Format(
_(
"Design block '%s' does not exist." ), dbDir.GetFullName() ) );
445 if( !wxFileName::Rmdir( dbDir.GetFullPath(), wxPATH_RMDIR_RECURSIVE ) )
447 THROW_IO_ERROR( wxString::Format(
_(
"Design block folder '%s' could not be deleted." ),
448 dbDir.GetFullPath().GetData() ) );
455 wxFileName
path( aLibraryPath );
456 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)
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)
const wxString & GetKeywords() const
const wxString & GetLibDescription() const
void SetLibId(const LIB_ID &aName)
const wxString & GetSchematicFile() const
void SetFields(nlohmann::ordered_map< wxString, wxString > &aFields)
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
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)
#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.