KiCad PCB EDA Suite
FP_CACHE Class Reference

#include <pcb_plugin.h>

Public Member Functions

 FP_CACHE (PCB_PLUGIN *aOwner, const wxString &aLibraryPath)
 
wxString GetPath () const
 
bool IsWritable () const
 
bool Exists () const
 
FP_CACHE_FOOTPRINT_MAPGetFootprints ()
 
void Save (FOOTPRINT *aFootprint=nullptr)
 Save the footprint cache or a single footprint from it to disk. More...
 
void Load ()
 
void Remove (const wxString &aFootprintName)
 
bool IsModified ()
 Return true if the cache is not up-to-date. More...
 
bool IsPath (const wxString &aPath) const
 Check if aPath is the same as the current cache path. More...
 
void SetPath (const wxString &aPath)
 

Static Public Member Functions

static long long GetTimestamp (const wxString &aLibPath)
 Generate a timestamp representing all source files in the cache (including the parent directory). More...
 

Private Attributes

PCB_PLUGINm_owner
 
wxFileName m_lib_path
 
wxString m_lib_raw_path
 
FP_CACHE_FOOTPRINT_MAP m_footprints
 
bool m_cache_dirty
 
long long m_cache_timestamp
 

Detailed Description

Definition at line 188 of file pcb_plugin.h.

Constructor & Destructor Documentation

◆ FP_CACHE()

FP_CACHE::FP_CACHE ( PCB_PLUGIN aOwner,
const wxString &  aLibraryPath 
)

Definition at line 75 of file pcb_plugin.cpp.

76{
77 m_owner = aOwner;
78 m_lib_raw_path = aLibraryPath;
79 m_lib_path.SetPath( aLibraryPath );
81 m_cache_dirty = true;
82}
long long m_cache_timestamp
Definition: pcb_plugin.h:197
bool m_cache_dirty
Definition: pcb_plugin.h:195
wxString m_lib_raw_path
Definition: pcb_plugin.h:192
PCB_PLUGIN * m_owner
Definition: pcb_plugin.h:190
wxFileName m_lib_path
Definition: pcb_plugin.h:191

References m_cache_dirty, m_cache_timestamp, m_lib_path, m_lib_raw_path, and m_owner.

Member Function Documentation

◆ Exists()

bool FP_CACHE::Exists ( ) const
inline

Definition at line 207 of file pcb_plugin.h.

207{ return m_lib_path.IsOk() && m_lib_path.DirExists(); }

References m_lib_path.

Referenced by PCB_PLUGIN::FootprintSave().

◆ GetFootprints()

◆ GetPath()

wxString FP_CACHE::GetPath ( ) const
inline

Definition at line 203 of file pcb_plugin.h.

203{ return m_lib_raw_path; }

References m_lib_raw_path.

◆ GetTimestamp()

long long FP_CACHE::GetTimestamp ( const wxString &  aLibPath)
static

Generate a timestamp representing all source files in the cache (including the parent directory).

Timestamps should not be considered ordered. They either match or they don't.

Definition at line 263 of file pcb_plugin.cpp.

264{
265 wxString fileSpec = wxT( "*." ) + KiCadFootprintFileExtension;
266
267 return TimestampDir( aLibPath, fileSpec );
268}
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/...
Definition: common.cpp:536
const std::string KiCadFootprintFileExtension

References KiCadFootprintFileExtension, and TimestampDir().

Referenced by PCB_PLUGIN::GetLibraryTimestamp(), IsModified(), and Load().

◆ IsModified()

bool FP_CACHE::IsModified ( )

Return true if the cache is not up-to-date.

Definition at line 255 of file pcb_plugin.cpp.

256{
258
259 return m_cache_dirty;
260}
static long long GetTimestamp(const wxString &aLibPath)
Generate a timestamp representing all source files in the cache (including the parent directory).
Definition: pcb_plugin.cpp:263

References GetTimestamp(), m_cache_dirty, m_cache_timestamp, and m_lib_path.

Referenced by PCB_PLUGIN::validateCache().

◆ IsPath()

bool FP_CACHE::IsPath ( const wxString &  aPath) const

Check if aPath is the same as the current cache path.

This tests paths by converting aPath using the native separators. Internally FP_CACHE stores the current path using native separators. This prevents path miscompares on Windows due to the fact that paths can be stored with / instead of \ in the footprint library table.

Parameters
aPathis the library path to test against.
Returns
true if aPath is the same as the cache path.

Definition at line 236 of file pcb_plugin.cpp.

237{
238 return aPath == m_lib_raw_path;
239}

References m_lib_raw_path.

Referenced by PCB_PLUGIN::FootprintLibDelete(), and PCB_PLUGIN::validateCache().

◆ IsWritable()

bool FP_CACHE::IsWritable ( ) const
inline

Definition at line 205 of file pcb_plugin.h.

205{ return m_lib_path.IsOk() && m_lib_path.IsDirWritable(); }

References m_lib_path.

Referenced by PCB_PLUGIN::FootprintDelete(), PCB_PLUGIN::FootprintSave(), and PCB_PLUGIN::IsFootprintLibWritable().

◆ Load()

void FP_CACHE::Load ( )

Definition at line 152 of file pcb_plugin.cpp.

153{
154 m_cache_dirty = false;
156
157 wxDir dir( m_lib_raw_path );
158
159 if( !dir.IsOpened() )
160 {
161 wxString msg = wxString::Format( _( "Footprint library '%s' not found." ),
163 THROW_IO_ERROR( msg );
164 }
165
166 wxString fullName;
167 wxString fileSpec = wxT( "*." ) + KiCadFootprintFileExtension;
168
169 // wxFileName construction is egregiously slow. Construct it once and just swap out
170 // the filename thereafter.
171 WX_FILENAME fn( m_lib_raw_path, wxT( "dummyName" ) );
172
173 if( dir.GetFirst( &fullName, fileSpec ) )
174 {
175 wxString cacheError;
176
177 do
178 {
179 fn.SetFullName( fullName );
180
181 // Queue I/O errors so only files that fail to parse don't get loaded.
182 try
183 {
184 FILE_LINE_READER reader( fn.GetFullPath() );
185 PCB_PARSER parser( &reader, nullptr, nullptr );
186
187 // use dynamic cast in case somebody renames a .kicad_pcb as .kicad_mod and chucks it into a library folder
188 // the parsing definitely fails then
189 FOOTPRINT* footprint = dynamic_cast<FOOTPRINT*>( parser.Parse() );
190 wxString fpName = fn.GetName();
191
192 if( !footprint )
193 {
194 THROW_IO_ERROR( wxString::Format( _( "Unable to read file '%s'" ), fn.GetFullPath() ) );
195 }
196
197 footprint->SetFPID( LIB_ID( wxEmptyString, fpName ) );
198 m_footprints.insert( fpName, new FP_CACHE_ITEM( footprint, fn ) );
199 }
200 catch( const IO_ERROR& ioe )
201 {
202 if( !cacheError.IsEmpty() )
203 cacheError += wxT( "\n\n" );
204
205 cacheError += ioe.What();
206 }
207 } while( dir.GetNext( &fullName ) );
208
210
211 if( !cacheError.IsEmpty() )
212 THROW_IO_ERROR( cacheError );
213 }
214}
A LINE_READER that reads from an open file.
Definition: richio.h:173
void SetFPID(const LIB_ID &aFPID)
Definition: footprint.h:213
Helper class for creating a footprint library cache.
Definition: pcb_plugin.h:174
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:76
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:49
Read a Pcbnew s-expression formatted LINE_READER object and returns the appropriate BOARD_ITEM object...
Definition: pcb_parser.h:74
A wrapper around a wxFileName which is much more performant with a subset of the API.
Definition: wx_filename.h:49
#define _(s)
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200

References _, Format(), WX_FILENAME::GetFullPath(), WX_FILENAME::GetName(), GetTimestamp(), KiCadFootprintFileExtension, m_cache_dirty, m_cache_timestamp, m_footprints, m_lib_raw_path, PCB_PARSER::Parse(), FOOTPRINT::SetFPID(), WX_FILENAME::SetFullName(), THROW_IO_ERROR, and IO_ERROR::What().

Referenced by PCBNEW_JOBS_HANDLER::JobExportFpSvg(), PCBNEW_JOBS_HANDLER::JobExportFpUpgrade(), and PCB_PLUGIN::validateCache().

◆ Remove()

void FP_CACHE::Remove ( const wxString &  aFootprintName)

Definition at line 217 of file pcb_plugin.cpp.

218{
219 FP_CACHE_FOOTPRINT_MAP::const_iterator it = m_footprints.find( aFootprintName );
220
221 if( it == m_footprints.end() )
222 {
223 wxString msg = wxString::Format( _( "Library '%s' has no footprint '%s'." ),
225 aFootprintName );
226 THROW_IO_ERROR( msg );
227 }
228
229 // Remove the footprint from the cache and delete the footprint file from the library.
230 wxString fullPath = it->second->GetFileName().GetFullPath();
231 m_footprints.erase( aFootprintName );
232 wxRemoveFile( fullPath );
233}

References _, Format(), m_footprints, m_lib_raw_path, and THROW_IO_ERROR.

Referenced by PCB_PLUGIN::FootprintDelete().

◆ Save()

void FP_CACHE::Save ( FOOTPRINT aFootprint = nullptr)

Save the footprint cache or a single footprint from it to disk.

Parameters
aFootprintif set, save only this footprint, otherwise, save the full library

Definition at line 85 of file pcb_plugin.cpp.

86{
88
89 if( !m_lib_path.DirExists() && !m_lib_path.Mkdir() )
90 {
91 THROW_IO_ERROR( wxString::Format( _( "Cannot create footprint library '%s'." ),
93 }
94
95 if( !m_lib_path.IsDirWritable() )
96 {
97 THROW_IO_ERROR( wxString::Format( _( "Footprint library '%s' is read only." ),
99 }
100
101 for( FP_CACHE_FOOTPRINT_MAP::iterator it = m_footprints.begin(); it != m_footprints.end(); ++it )
102 {
103 if( aFootprint && aFootprint != it->second->GetFootprint() )
104 continue;
105
106 WX_FILENAME fn = it->second->GetFileName();
107
108 wxString tempFileName =
109#ifdef USE_TMP_FILE
110 wxFileName::CreateTempFileName( fn.GetPath() );
111#else
112 fn.GetFullPath();
113#endif
114 // Allow file output stream to go out of scope to close the file stream before
115 // renaming the file.
116 {
117 wxLogTrace( traceKicadPcbPlugin, wxT( "Creating temporary library file '%s'." ),
118 tempFileName );
119
120 FILE_OUTPUTFORMATTER formatter( tempFileName );
121
122 m_owner->SetOutputFormatter( &formatter );
123 m_owner->Format( (BOARD_ITEM*) it->second->GetFootprint() );
124 }
125
126#ifdef USE_TMP_FILE
127 wxRemove( fn.GetFullPath() ); // it is not an error if this does not exist
128
129 // Even on Linux you can see an _intermittent_ error when calling wxRename(),
130 // and it is fully inexplicable. See if this dodges the error.
131 wxMilliSleep( 250L );
132
133 if( !wxRenameFile( tempFileName, fn.GetFullPath() ) )
134 {
135 wxString msg = wxString::Format( _( "Cannot rename temporary file '%s' to '%s'" ),
136 tempFileName,
137 fn.GetFullPath() );
138 THROW_IO_ERROR( msg );
139 }
140#endif
142 }
143
144 m_cache_timestamp += m_lib_path.GetModificationTime().GetValue().GetValue();
145
146 // If we've saved the full cache, we clear the dirty flag.
147 if( !aFootprint )
148 m_cache_dirty = false;
149}
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:58
Used for text file output.
Definition: richio.h:457
void SetOutputFormatter(OUTPUTFORMATTER *aFormatter)
Definition: pcb_plugin.h:346
void Format(const BOARD_ITEM *aItem, int aNestLevel=0) const
Output aItem to aFormatter in s-expression format.
Definition: pcb_plugin.cpp:331
wxString GetPath() const
Definition: wx_filename.cpp:60
wxString GetFullPath() const
Definition: wx_filename.cpp:66
long long GetTimestamp()
Definition: wx_filename.cpp:81
const wxChar *const traceKicadPcbPlugin
Flag to enable GEDA PCB plugin debug output.

References _, PCB_PLUGIN::Format(), Format(), WX_FILENAME::GetFullPath(), WX_FILENAME::GetPath(), WX_FILENAME::GetTimestamp(), m_cache_dirty, m_cache_timestamp, m_footprints, m_lib_path, m_lib_raw_path, m_owner, PCB_PLUGIN::SetOutputFormatter(), THROW_IO_ERROR, and traceKicadPcbPlugin.

Referenced by PCB_PLUGIN::FootprintLibCreate(), PCB_PLUGIN::FootprintSave(), and PCBNEW_JOBS_HANDLER::JobExportFpUpgrade().

◆ SetPath()

void FP_CACHE::SetPath ( const wxString &  aPath)

Definition at line 242 of file pcb_plugin.cpp.

243{
244 m_lib_raw_path = aPath;
245 m_lib_path.SetPath( aPath );
246
247
248 for( const auto& footprint : GetFootprints() )
249 {
250 footprint.second->SetFilePath( aPath );
251 }
252}
FP_CACHE_FOOTPRINT_MAP & GetFootprints()
Definition: pcb_plugin.h:209

References GetFootprints(), m_lib_path, and m_lib_raw_path.

Referenced by PCBNEW_JOBS_HANDLER::JobExportFpUpgrade().

Member Data Documentation

◆ m_cache_dirty

bool FP_CACHE::m_cache_dirty
private

Definition at line 195 of file pcb_plugin.h.

Referenced by FP_CACHE(), IsModified(), Load(), and Save().

◆ m_cache_timestamp

long long FP_CACHE::m_cache_timestamp
private

Definition at line 197 of file pcb_plugin.h.

Referenced by FP_CACHE(), IsModified(), Load(), and Save().

◆ m_footprints

FP_CACHE_FOOTPRINT_MAP FP_CACHE::m_footprints
private

Definition at line 193 of file pcb_plugin.h.

Referenced by GetFootprints(), Load(), Remove(), and Save().

◆ m_lib_path

wxFileName FP_CACHE::m_lib_path
private

Definition at line 191 of file pcb_plugin.h.

Referenced by Exists(), FP_CACHE(), IsModified(), IsWritable(), Save(), and SetPath().

◆ m_lib_raw_path

wxString FP_CACHE::m_lib_raw_path
private

Definition at line 192 of file pcb_plugin.h.

Referenced by FP_CACHE(), GetPath(), IsPath(), Load(), Remove(), Save(), and SetPath().

◆ m_owner

PCB_PLUGIN* FP_CACHE::m_owner
private

Definition at line 190 of file pcb_plugin.h.

Referenced by FP_CACHE(), and Save().


The documentation for this class was generated from the following files: