KiCad PCB EDA Suite
Loading...
Searching...
No Matches
footprint_library_adapter.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 * @author Jon Evans <[email protected]>
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
22
23#include <chrono>
24#include <env_vars.h>
25#include <footprint_info_impl.h>
26#include <thread_pool.h>
27#include <trace_helpers.h>
28#include <footprint.h>
29
30#include <magic_enum.hpp>
31#include <wx/hash.h>
32#include <wx/log.h>
33
34using namespace std::chrono_literals;
35
36
38
40
42
44
46
47
52
53
59
60
62{
63 return ENV_VAR::GetVersionedEnvVarName( wxS( "FOOTPRINT_DIR" ) );
64}
65
66
67void FOOTPRINT_LIBRARY_ADAPTER::enumerateLibrary( LIB_DATA* aLib, const wxString& aUri )
68{
69 wxArrayString namesAS;
70 std::map<std::string, UTF8> options = aLib->row->GetOptionsMap();
71 PCB_IO* plugin = pcbplugin( aLib );
72 wxString nickname = aLib->row->Nickname();
73
74 long long timestamp = plugin->GetLibraryTimestamp( aUri );
75
76 // Hold across the enumerate-then-borrow sequence: GetEnumeratedFootprint returns borrowed
77 // FP_CACHE pointers, so no other thread may rebuild the cache until we finish cloning.
78 std::lock_guard pluginGuard( pluginMutex( nickname ) );
79
80 // FootprintEnumerate populates the plugin's internal FP_CACHE with parsed footprints
81 plugin->FootprintEnumerate( namesAS, aUri, false, &options );
82
83 std::vector<std::unique_ptr<FOOTPRINT>> footprints;
84 footprints.reserve( namesAS.size() );
85
86 // For plugins with internal caches (like kicad_sexpr), GetEnumeratedFootprint returns
87 // a borrowed pointer and ClearCachedFootprints handles cleanup. For other plugins,
88 // GetEnumeratedFootprint allocates new memory that we must delete after cloning.
89 const bool pluginCaches = plugin->CachesEnumeratedFootprints();
90
91 for( const wxString& footprintName : namesAS )
92 {
93 try
94 {
95 const FOOTPRINT* cached = plugin->GetEnumeratedFootprint( aUri, footprintName, &options );
96
97 if( !cached )
98 continue;
99
100 // Preserve disk UUIDs in the cache that serves keep-UUID loads
101 FOOTPRINT* footprint = static_cast<FOOTPRINT*>( cached->Clone() );
102 footprint->SetParent( nullptr );
103 footprint->SetParentGroup( nullptr );
104 footprint->ClearAllNets();
105
106 // For non-caching plugins, delete the allocated footprint now that we've cloned it
107 if( !pluginCaches )
108 delete cached;
109
110 LIB_ID id = footprint->GetFPID();
111 id.SetLibNickname( nickname );
112 footprint->SetFPID( id );
113 footprints.emplace_back( footprint );
114 }
115 catch( IO_ERROR& e )
116 {
117 wxLogTrace( traceLibraries, "FP: %s:%s enumeration error: %s",
118 nickname, footprintName, e.What() );
119 }
120 }
121
122 {
123 std::unique_lock lock( PreloadedFootprintsMutex );
124 PreloadedFootprints.Get()[nickname] = std::move( footprints );
125 PreloadedTimestamps.Get()[nickname] = timestamp;
126 }
127
128 // Clear the plugin's FP_CACHE now that we've copied footprints to PreloadedFootprints.
129 // This eliminates the double-caching that was consuming ~1.2GB of extra RAM.
130 plugin->ClearCachedFootprints( aUri );
131}
132
133
134std::optional<LIB_STATUS> FOOTPRINT_LIBRARY_ADAPTER::LoadOne( LIB_DATA* aLib )
135{
137
138 try
139 {
140 enumerateLibrary( aLib, getUri( aLib->row ) );
142 aLib->status.error.reset();
143 }
144 catch( IO_ERROR& e )
145 {
147 aLib->status.error = LIBRARY_ERROR( e.Problem(), e.Where() );
148 wxLogTrace( traceLibraries, "FP: %s: plugin threw exception: %s", aLib->row->Nickname(), e.What() );
149 }
150
151 return aLib->status;
152}
153
154
155std::optional<LIB_STATUS> FOOTPRINT_LIBRARY_ADAPTER::LoadOne( const wxString& nickname )
156{
158
159 if( result.has_value() )
160 return LoadOne( *result );
161
162 return LIB_STATUS{ .load_status = LOAD_STATUS::LOAD_ERROR,
163 .error = LIBRARY_ERROR( { result.error() } ) };
164}
165
166
167std::vector<FOOTPRINT*> FOOTPRINT_LIBRARY_ADAPTER::GetFootprints( const wxString& aNickname, bool aBestEfforts )
168{
169 std::vector<FOOTPRINT*> footprints;
170
171 std::shared_lock lock( PreloadedFootprintsMutex );
172 auto it = PreloadedFootprints.Get().find( aNickname );
173
174 if( it == PreloadedFootprints.Get().end() )
175 return footprints;
176
177 footprints.reserve( it->second.size() );
178
179 for( const auto& fp : it->second )
180 footprints.push_back( fp.get() );
181
182 return footprints;
183}
184
185
186
187std::vector<wxString> FOOTPRINT_LIBRARY_ADAPTER::GetFootprintNames( const wxString& aNickname, bool aBestEfforts )
188{
189 // TODO(JE) can we kill wxArrayString in internal API?
190 wxArrayString namesAS;
191 std::vector<wxString> names;
192
193 if( std::optional<const LIB_DATA*> maybeLib = fetchIfLoaded( aNickname ) )
194 {
195 const LIB_DATA* lib = *maybeLib;
196 std::map<std::string, UTF8> options = lib->row->GetOptionsMap();
197
198 try
199 {
200 std::lock_guard pluginGuard( pluginMutex( aNickname ) );
201
202 pcbplugin( lib )->FootprintEnumerate( namesAS, getUri( lib->row ), aBestEfforts, &options );
203 }
204 catch( IO_ERROR& e )
205 {
206 wxLogTrace( traceLibraries, "FP: Exception enumerating library %s: %s", lib->row->Nickname(), e.What() );
207
208 if( !aBestEfforts )
209 throw;
210 }
211 }
212
213 for( const wxString& name : namesAS )
214 names.emplace_back( name );
215
216 return names;
217}
218
219
220long long FOOTPRINT_LIBRARY_ADAPTER::GenerateTimestamp( const wxString* aNickname )
221{
222 long long hash = 0;
223
224 if( aNickname )
225 {
226 wxCHECK( HasLibrary( *aNickname, true ), hash );
227
228 if( std::optional<const LIB_DATA*> r = fetchIfLoaded( *aNickname ); r.has_value() )
229 {
230 PCB_IO* plugin = dynamic_cast<PCB_IO*>( ( *r )->plugin.get() );
231 wxCHECK( plugin, hash );
232 return plugin->GetLibraryTimestamp( LIBRARY_MANAGER::GetFullURI( ( *r )->row, true ) )
233 + wxHashTable::MakeKey( *aNickname );
234 }
235 }
236
237 for( const wxString& nickname : GetLibraryNames() )
238 {
239 if( std::optional<const LIB_DATA*> r = fetchIfLoaded( nickname ); r.has_value() )
240 {
241 wxCHECK2( ( *r )->plugin->IsPCB_IO(), continue );
242 PCB_IO* plugin = static_cast<PCB_IO*>( ( *r )->plugin.get() );
243 hash += plugin->GetLibraryTimestamp( LIBRARY_MANAGER::GetFullURI( ( *r )->row, true ) )
244 + wxHashTable::MakeKey( nickname );
245 }
246 }
247
248 return hash;
249}
250
251
253{
254 std::optional<LIB_DATA*> maybeLib = fetchIfLoaded( aNickname );
255
256 if( !maybeLib )
257 return;
258
259 LIB_DATA* lib = *maybeLib;
260 PCB_IO* plugin = dynamic_cast<PCB_IO*>( lib->plugin.get() );
261
262 if( !plugin )
263 return;
264
265 wxString uri = getUri( lib->row );
266 long long currentTimestamp = plugin->GetLibraryTimestamp( uri );
267
268 {
269 std::shared_lock lock( PreloadedFootprintsMutex );
270 auto tsIt = PreloadedTimestamps.Get().find( aNickname );
271
272 if( tsIt != PreloadedTimestamps.Get().end() && tsIt->second == currentTimestamp )
273 return;
274
275 wxLogTrace( traceLibraries, "FP: %s changed on disk, re-enumerating", aNickname );
276 }
277
278 try
279 {
280 enumerateLibrary( lib, uri );
281 }
282 catch( IO_ERROR& )
283 {
284 std::unique_lock lock( PreloadedFootprintsMutex );
285 PreloadedFootprints.Get().erase( aNickname );
286 PreloadedTimestamps.Get().erase( aNickname );
287 throw;
288 }
289}
290
291
293{
294 for( const wxString& nickname : GetLibraryNames() )
295 {
296 // An unreadable library must not stop the others, nor escape into the caller.
297 try
298 {
299 RefreshLibraryIfChanged( nickname );
300 }
301 catch( const IO_ERROR& e )
302 {
303 wxLogTrace( traceLibraries, "FP: %s: refresh failed: %s", nickname, e.What() );
304 }
305 }
306}
307
308
309bool FOOTPRINT_LIBRARY_ADAPTER::FootprintExists( const wxString& aNickname, const wxString& aName )
310{
311 if( std::optional<const LIB_DATA*> maybeLib = fetchIfLoaded( aNickname ) )
312 {
313 const LIB_DATA* lib = *maybeLib;
314 std::map<std::string, UTF8> options = lib->row->GetOptionsMap();
315
316 std::lock_guard pluginGuard( pluginMutex( aNickname ) );
317
318 return pcbplugin( lib )->FootprintExists( getUri( lib->row ), aName, &options );
319 }
320
321 return false;
322}
323
324
325FOOTPRINT* FOOTPRINT_LIBRARY_ADAPTER::LoadFootprint( const wxString& aNickname, const wxString& aName, bool aKeepUUID )
326{
327 // First check if the footprint is in PreloadedFootprints and clone from there.
328 // This avoids re-parsing the file and keeps FP_CACHE from being repopulated.
329 if( fetchIfLoaded( aNickname ) )
330 {
331 std::shared_lock lock( PreloadedFootprintsMutex );
332 auto libIt = PreloadedFootprints.Get().find( aNickname );
333
334 if( libIt != PreloadedFootprints.Get().end() )
335 {
336 for( const auto& fp : libIt->second )
337 {
338 if( fp->GetFPID().GetLibItemName() == UTF8( aName ) )
339 {
341
342 if( aKeepUUID )
343 copy = static_cast<FOOTPRINT*>( fp->Clone() );
344 else
345 copy = static_cast<FOOTPRINT*>( fp->Duplicate( IGNORE_PARENT_GROUP ) );
346
347 copy->SetParent( nullptr );
348 return copy;
349 }
350 }
351 }
352 }
353
354 // Footprint not found in PreloadedFootprints, fall back to plugin.
355 // This re-parses the file but is needed for footprints not yet enumerated.
356 if( std::optional<const LIB_DATA*> lib = fetchIfLoaded( aNickname ) )
357 {
358 try
359 {
360 std::lock_guard pluginGuard( pluginMutex( aNickname ) );
361
362 if( std::unique_ptr<FOOTPRINT> footprint =
363 pcbplugin( *lib )->FootprintLoad( getUri( ( *lib )->row ), aName, aKeepUUID ) )
364 {
365 LIB_ID id = footprint->GetFPID();
366 id.SetLibNickname( ( *lib )->row->Nickname() );
367 footprint->SetFPID( id );
368 footprint->SetParent( nullptr );
369 footprint->SetParentGroup( nullptr );
370 footprint->ClearAllNets();
371 return footprint.release();
372 }
373 }
374 catch( const IO_ERROR& ioe )
375 {
376 wxLogTrace( traceLibraries, "LoadFootprint: error loading %s:%s: %s", aNickname, aName, ioe.What() );
377 }
378 }
379 else
380 {
381 wxLogTrace( traceLibraries, "LoadFootprint: requested library %s not loaded", aNickname );
382 }
383
384 return nullptr;
385}
386
387
389{
390 wxString nickname = aFootprintId.GetLibNickname();
391 wxString footprintName = aFootprintId.GetLibItemName();
392
393 if( nickname.size() )
394 return LoadFootprint( nickname, footprintName, aKeepUUID );
395
396 // nickname is empty, sequentially search (alphabetically) all libs/nicks for first match:
397 for( const wxString& library : GetLibraryNames() )
398 {
399 // FootprintLoad() returns NULL on not found, does not throw exception
400 // unless there's an IO_ERROR.
401 if( FOOTPRINT* ret = LoadFootprint( library, footprintName, aKeepUUID ) )
402 return ret;
403 }
404
405 return nullptr;
406}
407
408
410 const FOOTPRINT* aFootprint,
411 bool aOverwrite )
412{
413 wxCHECK( aFootprint, SAVE_SKIPPED );
414
415 if( std::optional<const LIB_DATA*> lib = fetchIfLoaded( aNickname ) )
416 {
417 // Serialize the load-check / save / cache-update sequence against a concurrent rebuild.
418 std::lock_guard pluginGuard( pluginMutex( aNickname ) );
419
420 if( !aOverwrite )
421 {
422 wxString fpname = aFootprint->GetFPID().GetLibItemName();
423
424 try
425 {
426 std::unique_ptr<FOOTPRINT> existing =
427 pcbplugin( *lib )->FootprintLoad( getUri( ( *lib )->row ), fpname, false );
428
429 if( existing )
430 return SAVE_SKIPPED;
431 }
432 catch( IO_ERROR& e )
433 {
434 wxLogTrace( traceLibraries, "SaveFootprint: error checking for existing footprint %s: %s",
435 aFootprint->GetFPIDAsString(), e.What() );
436 return SAVE_SKIPPED;
437 }
438 }
439
440 try
441 {
442 pcbplugin( *lib )->FootprintSave( getUri( ( *lib )->row ), aFootprint );
443 }
444 catch( IO_ERROR& e )
445 {
446 // Re-throw rather than returning SAVE_SKIPPED; swallowing a write failure (read-only
447 // file, full disk) would report a successful save while the file is unchanged.
448 wxLogTrace( traceLibraries, "SaveFootprint: error saving %s: %s",
449 aFootprint->GetFPIDAsString(), e.What() );
450 throw;
451 }
452
453 {
454 std::unique_lock lock( PreloadedFootprintsMutex );
455 auto it = PreloadedFootprints.Get().find( aNickname );
456
457 if( it != PreloadedFootprints.Get().end() )
458 {
459 wxString fpName = aFootprint->GetFPID().GetLibItemName();
460
461 if( aOverwrite )
462 {
463 auto& footprints = it->second;
464 std::erase_if( footprints,
465 [&fpName]( const std::unique_ptr<FOOTPRINT>& fp )
466 {
467 return fp->GetFPID().GetLibItemName().wx_str() == fpName;
468 } );
469 }
470
471 // Must match what FootprintSave() just wrote, UUIDs included
472 FOOTPRINT* clone = static_cast<FOOTPRINT*>( aFootprint->Clone() );
473 clone->SetParent( nullptr );
474 clone->SetParentGroup( nullptr );
475 clone->ClearAllNets();
476
477 LIB_ID id = clone->GetFPID();
478 id.SetLibNickname( aNickname );
479 clone->SetFPID( id );
480
481 it->second.emplace_back( clone );
482 }
483 }
484
485 return SAVE_OK;
486 }
487 else
488 {
489 wxLogTrace( traceLibraries, "SaveFootprint: requested library %s not loaded", aNickname );
490 return SAVE_SKIPPED;
491 }
492}
493
494
495void FOOTPRINT_LIBRARY_ADAPTER::DeleteFootprint( const wxString& aNickname, const wxString& aFootprintName )
496{
497 if( std::optional<const LIB_DATA*> lib = fetchIfLoaded( aNickname ) )
498 {
499 std::lock_guard pluginGuard( pluginMutex( aNickname ) );
500
501 try
502 {
503 pcbplugin( *lib )->FootprintDelete( getUri( ( *lib )->row ), aFootprintName );
504 }
505 catch( IO_ERROR& e )
506 {
507 wxLogTrace( traceLibraries, "DeleteFootprint: error deleting %s:%s: %s", aNickname,
508 aFootprintName, e.What() );
509 throw;
510 }
511
512 {
513 std::unique_lock lock( PreloadedFootprintsMutex );
514 auto it = PreloadedFootprints.Get().find( aNickname );
515
516 if( it != PreloadedFootprints.Get().end() )
517 {
518 auto& footprints = it->second;
519 std::erase_if( footprints,
520 [&aFootprintName]( const std::unique_ptr<FOOTPRINT>& fp )
521 {
522 return fp->GetFPID().GetLibItemName().wx_str() == aFootprintName;
523 } );
524 }
525 }
526 }
527 else
528 {
529 wxLogTrace( traceLibraries, "DeleteFootprint: requested library %s not loaded", aNickname );
530 }
531}
532
533
535{
536 // Route through fetchIfLoaded() so LOAD_ERROR sentinel entries, which carry a null
537 // plugin, are filtered out instead of dereferenced.
538 if( std::optional<const LIB_DATA*> lib = fetchIfLoaded( aLib ) )
539 {
540 std::lock_guard pluginGuard( pluginMutex( aLib ) );
541
542 return ( *lib )->plugin->IsLibraryWritable( getUri( ( *lib )->row ) );
543 }
544
545 return false;
546}
547
548
550{
552
553 if( type == PCB_IO_MGR::NESTED_TABLE )
554 {
555 wxString msg;
556 wxFileName fileName( m_manager.GetFullURI( row, true ) );
557
558 if( fileName.FileExists() )
559 return tl::unexpected( LIBRARY_TABLE_OK() );
560 else
561 msg = wxString::Format( _( "Nested table '%s' not found." ), row->URI() );
562
563 return tl::unexpected( LIBRARY_ERROR( msg ) );
564 }
565 else if( type == PCB_IO_MGR::PCB_FILE_UNKNOWN )
566 {
567 wxLogTrace( traceLibraries, "FP: Plugin type %s is unknown!", row->Type() );
568 wxString msg = wxString::Format( _( "Unknown library type %s " ), row->Type() );
569 return tl::unexpected( LIBRARY_ERROR( msg ) );
570 }
571
573 wxCHECK( plugin, tl::unexpected( LIBRARY_ERROR( _( "Internal error" ) ) ) );
574
575 wxLogTrace( traceLibraries, "FP: Library %s (%s) plugin created", row->Nickname(),
576 magic_enum::enum_name( row->Scope() ) );
577
578 return plugin;
579}
580
581
583{
584 // Note: can't use dynamic_cast across compile units on Mac
585 wxCHECK( aRow->plugin->IsPCB_IO(), nullptr );
586 PCB_IO* ret = static_cast<PCB_IO*>( aRow->plugin.get() );
587 return ret;
588}
const char * name
virtual void SetParentGroup(EDA_GROUP *aGroup)
Definition eda_item.h:115
virtual void SetParent(EDA_ITEM *aParent)
Definition eda_item.cpp:153
bool IsFootprintLibWritable(const wxString &aNickname)
Return true if the library given by aNickname is writable.
void DeleteFootprint(const wxString &aNickname, const wxString &aFootprintName)
Deletes the aFootprintName from the library given by aNickname.
std::vector< FOOTPRINT * > GetFootprints(const wxString &aNickname, bool aBestEfforts=false)
Retrieves a list of footprints contained in a given loaded library.
void RefreshLibraryIfChanged(const wxString &aNickname)
Checks whether the library on disk has changed since it was last enumerated into PreloadedFootprints ...
static LEAK_AT_EXIT< std::shared_mutex > GlobalLibraryMutex
void enumerateLibrary(LIB_DATA *aLib, const wxString &aUri) override
Override in derived class to perform library-specific enumeration.
IO_BASE * plugin(const LIB_DATA *aRow) override
SAVE_T SaveFootprint(const wxString &aNickname, const FOOTPRINT *aFootprint, bool aOverwrite=true)
Write aFootprint to an existing library given by aNickname.
std::vector< wxString > GetFootprintNames(const wxString &aNickname, bool aBestEfforts=false)
Retrieves a list of footprint names contained in a given loaded library.
FOOTPRINT * LoadFootprint(const wxString &aNickname, const wxString &aName, bool aKeepUUID)
Load a FOOTPRINT having aName from the library given by aNickname.
static LEAK_AT_EXIT< std::map< wxString, LIB_DATA > > GlobalLibraries
static LEAK_AT_EXIT< std::map< wxString, long long > > PreloadedTimestamps
Filesystem timestamps from when PreloadedFootprints was last populated, guarded by PreloadedFootprint...
static PCB_IO * pcbplugin(const LIB_DATA *aRow)
FOOTPRINT * LoadFootprintWithOptionalNickname(const LIB_ID &aFootprintId, bool aKeepUUID)
Load a footprint having aFootprintId with possibly an empty nickname.
LIBRARY_RESULT< IO_BASE * > createPlugin(const LIBRARY_TABLE_ROW *row) override
Creates a concrete plugin for the given row.
FOOTPRINT_LIBRARY_ADAPTER(LIBRARY_MANAGER &aManager)
long long GenerateTimestamp(const wxString *aNickname)
Generates a filesystem timestamp / hash value for library(ies)
std::optional< LIB_STATUS > LoadOne(LIB_DATA *aLib) override
Loads or reloads the given library, if it exists.
SAVE_T
The set of return values from SaveSymbol() below.
static LEAK_AT_EXIT< std::map< wxString, std::vector< std::unique_ptr< FOOTPRINT > > > > PreloadedFootprints
Storage for preloaded footprints, indexed by library nickname.
bool FootprintExists(const wxString &aNickname, const wxString &aName)
static std::shared_mutex PreloadedFootprintsMutex
void SetFPID(const LIB_ID &aFPID)
Definition footprint.h:418
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
wxString GetFPIDAsString() const
Definition footprint.h:419
const LIB_ID & GetFPID() const
Definition footprint.h:417
void ClearAllNets()
Clear (i.e.
virtual bool IsPCB_IO() const
Work-around for lack of dynamic_cast across compile units on Mac.
Definition io_base.h:84
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
virtual const wxString Problem() const
what was the problem?
virtual const wxString Where() const
where did the Problem() occur?
A wrapper for static data that should not be destroyed at program exit.
void resetProjectCache()
Aborts pending loads and resets every project-scope cache entry in place (plugin and row cleared,...
void evictOwnedGlobalEntries()
Erases this adapter's own entries (LIB_DATA::global_owner == this) from the process-wide globalLibs()...
LIBRARY_MANAGER_ADAPTER(LIBRARY_MANAGER &aManager)
Constructs a type-specific adapter into the library manager.
wxString getUri(const LIBRARY_TABLE_ROW *aRow) const
LIBRARY_RESULT< LIB_DATA * > loadIfNeeded(const wxString &aNickname)
Fetches a loaded library, triggering a load of that library if it isn't loaded yet.
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library tables.
std::vector< wxString > GetLibraryNames() const
Returns a list of library nicknames that are available (skips any that failed to load)
static std::recursive_mutex & pluginMutex(const wxString &aNickname)
Serializes access to a library's shared plugin instance so its single mutable cache is not raced by c...
LIBRARY_MANAGER & m_manager
std::optional< const LIB_DATA * > fetchIfLoaded(const wxString &aNickname) const
std::optional< wxString > GetFullURI(LIBRARY_TABLE_TYPE aType, const wxString &aNickname, bool aSubstituted=false)
Return the full location specifying URI for the LIB, either in original UI form or in environment var...
LIBRARY_TABLE_SCOPE Scope() const
std::map< std::string, UTF8 > GetOptionsMap() const
const wxString & Type() const
const wxString & URI() const
const wxString & Nickname() const
A logical library item identifier and consists of various portions much like a URI.
Definition lib_id.h:45
int SetLibNickname(const UTF8 &aLibNickname)
Override the logical library name portion of the LIB_ID to aLibNickname.
Definition lib_id.cpp:113
const UTF8 & GetLibItemName() const
Definition lib_id.h:98
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition lib_id.h:83
static PCB_FILE_T EnumFromStr(const wxString &aFileType)
Return the PCB_FILE_T from the corresponding plugin type name: "kicad", "legacy", etc.
PCB_FILE_T
The set of file types that the PCB_IO_MGR knows about, and for which there has been a plugin written,...
Definition pcb_io_mgr.h:52
@ PCB_FILE_UNKNOWN
0 is not a legal menu id on Mac
Definition pcb_io_mgr.h:53
static PCB_IO * FindPlugin(PCB_FILE_T aFileType)
Return a PCB_IO which the caller can use to import, export, save, or load design documents.
A base class that BOARD loading and saving plugins should derive from.
Definition pcb_io.h:78
virtual std::unique_ptr< FOOTPRINT > FootprintLoad(const wxString &aLibraryPath, const wxString &aFootprintName, bool aKeepUUID=false, const std::map< std::string, UTF8 > *aProperties=nullptr)
Load a footprint having aFootprintName from the aLibraryPath containing a library format that this PC...
Definition pcb_io.cpp:160
virtual void FootprintEnumerate(wxArrayString &aFootprintNames, const wxString &aLibraryPath, bool aBestEfforts, const std::map< std::string, UTF8 > *aProperties=nullptr)
Return a list of footprint names contained within the library at aLibraryPath.
Definition pcb_io.cpp:112
virtual bool FootprintExists(const wxString &aLibraryPath, const wxString &aFootprintName, const std::map< std::string, UTF8 > *aProperties=nullptr)
Check for the existence of a footprint.
Definition pcb_io.cpp:152
virtual void FootprintDelete(const wxString &aLibraryPath, const wxString &aFootprintName, const std::map< std::string, UTF8 > *aProperties=nullptr)
Delete aFootprintName from the library at aLibraryPath.
Definition pcb_io.cpp:177
virtual void FootprintSave(const wxString &aLibraryPath, const FOOTPRINT *aFootprint, const std::map< std::string, UTF8 > *aProperties=nullptr)
Write aFootprint to an existing library located at aLibraryPath.
Definition pcb_io.cpp:169
An 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to and fro...
Definition utf8.h:67
#define _(s)
#define IGNORE_PARENT_GROUP
Definition eda_item.h:55
Functions related to environment variables, including help functions.
const wxChar *const traceLibraries
Flag to enable library table and library manager tracing.
tl::expected< ResultType, LIBRARY_ERROR > LIBRARY_RESULT
KICOMMON_API wxString GetVersionedEnvVarName(const wxString &aBaseName)
Construct a versioned environment variable based on this KiCad major version.
Definition env_vars.cpp:78
Storage for an actual loaded library (including library content owned by the plugin)
LIB_STATUS status
std::unique_ptr< IO_BASE > plugin
Never destroyed while holding the map's mutex; a plugin's worker thread may be blocked on it.
const LIBRARY_TABLE_ROW * row
The overall status of a loaded or loading library.
std::optional< LIBRARY_ERROR > error
LOAD_STATUS load_status
wxString result
Test unit parsing edge cases and error handling.
wxLogTrace helper definitions.