KiCad PCB EDA Suite
fp_lib_table.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 (C) 2010-2012 SoftPLC Corporation, Dick Hollenbeck <[email protected]>
5 * Copyright (C) 2012 Wayne Stambaugh <[email protected]>
6 * Copyright (C) 2012-2021 KiCad Developers, see AUTHORS.txt for contributors.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
26
27#include <kiface_base.h>
28#include <footprint_info.h>
29#include <lib_id.h>
30#include <lib_table_lexer.h>
31#include <pgm_base.h>
32#include <search_stack.h>
35#include <systemdirsappend.h>
36#include <fp_lib_table.h>
37#include <footprint.h>
38
39#include <wx/dir.h>
40#include <wx/hash.h>
41
42#define OPT_SEP '|'
43
44using namespace LIB_TABLE_T;
45
46
47static const wxChar global_tbl_name[] = wxT( "fp-lib-table" );
48
49
51{
52 return LIB_TABLE_ROW::operator == ( aRow ) && type == aRow.type;
53}
54
55
56void FP_LIB_TABLE_ROW::SetType( const wxString& aType )
57{
58 type = IO_MGR::EnumFromStr( aType );
59
60 if( IO_MGR::PCB_FILE_T( -1 ) == type )
62
64}
65
66
68 LIB_TABLE( aFallBackTable )
69{
70 // not copying fall back, simply search aFallBackTable separately
71 // if "nickName not found".
72}
73
74
75void FP_LIB_TABLE::Parse( LIB_TABLE_LEXER* in )
76{
77 T tok;
78 wxString errMsg; // to collect error messages
79
80 // This table may be nested within a larger s-expression, or not.
81 // Allow for parser of that optional containing s-epression to have looked ahead.
82 if( in->CurTok() != T_fp_lib_table )
83 {
84 in->NeedLEFT();
85
86 if( ( tok = in->NextTok() ) != T_fp_lib_table )
87 in->Expecting( T_fp_lib_table );
88 }
89
90 while( ( tok = in->NextTok() ) != T_RIGHT )
91 {
92 std::unique_ptr<FP_LIB_TABLE_ROW> row = std::make_unique<FP_LIB_TABLE_ROW>();
93
94 if( tok == T_EOF )
95 in->Expecting( T_RIGHT );
96
97 if( tok != T_LEFT )
98 in->Expecting( T_LEFT );
99
100 // in case there is a "row integrity" error, tell where later.
101 int lineNum = in->CurLineNumber();
102 tok = in->NextTok();
103
104 // Optionally parse the current version number
105 if( tok == T_version )
106 {
107 in->NeedNUMBER( "version" );
108 m_version = std::stoi( in->CurText() );
109 in->NeedRIGHT();
110 continue;
111 }
112
113 if( tok != T_lib )
114 in->Expecting( T_lib );
115
116 // (name NICKNAME)
117 in->NeedLEFT();
118
119 if( ( tok = in->NextTok() ) != T_name )
120 in->Expecting( T_name );
121
122 in->NeedSYMBOLorNUMBER();
123
124 row->SetNickName( in->FromUTF8() );
125
126 in->NeedRIGHT();
127
128 // After (name), remaining (lib) elements are order independent, and in
129 // some cases optional.
130 bool sawType = false;
131 bool sawOpts = false;
132 bool sawDesc = false;
133 bool sawUri = false;
134 bool sawDisabled = false;
135
136 while( ( tok = in->NextTok() ) != T_RIGHT )
137 {
138 if( tok == T_EOF )
139 in->Unexpected( T_EOF );
140
141 if( tok != T_LEFT )
142 in->Expecting( T_LEFT );
143
144 tok = in->NeedSYMBOLorNUMBER();
145
146 switch( tok )
147 {
148 case T_uri:
149 if( sawUri )
150 in->Duplicate( tok );
151 sawUri = true;
152 in->NeedSYMBOLorNUMBER();
153 row->SetFullURI( in->FromUTF8() );
154 break;
155
156 case T_type:
157 if( sawType )
158 in->Duplicate( tok );
159 sawType = true;
160 in->NeedSYMBOLorNUMBER();
161 row->SetType( in->FromUTF8() );
162 break;
163
164 case T_options:
165 if( sawOpts )
166 in->Duplicate( tok );
167 sawOpts = true;
168 in->NeedSYMBOLorNUMBER();
169 row->SetOptions( in->FromUTF8() );
170 break;
171
172 case T_descr:
173 if( sawDesc )
174 in->Duplicate( tok );
175 sawDesc = true;
176 in->NeedSYMBOLorNUMBER();
177 row->SetDescr( in->FromUTF8() );
178 break;
179
180 case T_disabled:
181 if( sawDisabled )
182 in->Duplicate( tok );
183 sawDisabled = true;
184 row->SetEnabled( false );
185 break;
186
187 case T_hidden:
188 // Hiding footprint libraries is not yet supported. Unclear what path can set this
189 // attribute, but clear it on load.
190 row->SetVisible();
191 break;
192
193 default:
194 in->Unexpected( tok );
195 }
196
197 in->NeedRIGHT();
198 }
199
200 if( !sawType )
201 in->Expecting( T_type );
202
203 if( !sawUri )
204 in->Expecting( T_uri );
205
206 // all nickNames within this table fragment must be unique, so we do not
207 // use doReplace in InsertRow(). (However a fallBack table can have a
208 // conflicting nickName and ours will supercede that one since in
209 // FindLib() we search this table before any fall back.)
210 wxString nickname = row->GetNickName(); // store it to be able to used it
211 // after row deletion if an error occurs
212 LIB_TABLE_ROW* tmp = row.release();
213
214 if( !InsertRow( tmp ) )
215 {
216 delete tmp; // The table did not take ownership of the row.
217
218 wxString msg = wxString::Format( _( "Duplicate library nickname '%s' found in "
219 "footprint library table file line %d." ),
220 nickname,
221 lineNum );
222
223 if( !errMsg.IsEmpty() )
224 errMsg << '\n';
225
226 errMsg << msg;
227 }
228 }
229
230 if( !errMsg.IsEmpty() )
231 THROW_IO_ERROR( errMsg );
232}
233
234
235bool FP_LIB_TABLE::operator==( const FP_LIB_TABLE& aFpTable ) const
236{
237 if( m_rows.size() == aFpTable.m_rows.size() )
238 {
239 for( unsigned i = 0; i < m_rows.size(); ++i )
240 {
241 if( (FP_LIB_TABLE_ROW&)m_rows[i] != (FP_LIB_TABLE_ROW&)aFpTable.m_rows[i] )
242 return false;
243 }
244
245 return true;
246 }
247
248 return false;
249}
250
251
252void FP_LIB_TABLE::Format( OUTPUTFORMATTER* aOutput, int aIndentLevel ) const
253{
254 aOutput->Print( aIndentLevel, "(fp_lib_table\n" );
255 aOutput->Print( aIndentLevel + 1, "(version %d)\n", m_version );
256
257 for( LIB_TABLE_ROWS_CITER it = m_rows.begin(); it != m_rows.end(); ++it )
258 it->Format( aOutput, aIndentLevel+1 );
259
260 aOutput->Print( aIndentLevel, ")\n" );
261}
262
263
264long long FP_LIB_TABLE::GenerateTimestamp( const wxString* aNickname )
265{
266 long long hash = 0;
267
268 if( aNickname )
269 {
270 const FP_LIB_TABLE_ROW* row = FindRow( *aNickname, true );
271
272 wxCHECK( row && row->plugin, hash );
273
274 return row->plugin->GetLibraryTimestamp( row->GetFullURI( true ) ) +
275 wxHashTable::MakeKey( *aNickname );
276 }
277
278 for( const wxString& nickname : GetLogicalLibs() )
279 {
280 const FP_LIB_TABLE_ROW* row = FindRow( nickname, true );
281
282 wxCHECK2( row && row->plugin, continue );
283
284 hash += row->plugin->GetLibraryTimestamp( row->GetFullURI( true ) ) +
285 wxHashTable::MakeKey( nickname );
286 }
287
288 return hash;
289}
290
291
292void FP_LIB_TABLE::FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aNickname,
293 bool aBestEfforts )
294{
295 const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
296 wxASSERT( (PLUGIN*) row->plugin );
297 row->plugin->FootprintEnumerate( aFootprintNames, row->GetFullURI( true ), aBestEfforts,
298 row->GetProperties() );
299}
300
301
302void FP_LIB_TABLE::PrefetchLib( const wxString& aNickname )
303{
304 const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
305 wxASSERT( (PLUGIN*) row->plugin );
306 row->plugin->PrefetchLib( row->GetFullURI( true ), row->GetProperties() );
307}
308
309
310const FP_LIB_TABLE_ROW* FP_LIB_TABLE::FindRow( const wxString& aNickname, bool aCheckIfEnabled )
311{
312 // Do not optimize this code. Is done this way specifically to fix a runtime
313 // error with clang 4.0.1.
314 LIB_TABLE_ROW* ltrow = findRow( aNickname, aCheckIfEnabled );
315 FP_LIB_TABLE_ROW* row = dynamic_cast< FP_LIB_TABLE_ROW* >( ltrow );
316
317 if( !row )
318 {
319 wxString msg = wxString::Format( _( "fp-lib-table files contain no library named '%s'." ),
320 aNickname );
321
322 THROW_IO_ERROR( msg );
323 }
324
325 // We've been 'lazy' up until now, but it cannot be deferred any longer,
326 // instantiate a PLUGIN of the proper kind if it is not already in this
327 // FP_LIB_TABLE_ROW.
328 if( !row->plugin )
329 row->setPlugin( IO_MGR::PluginFind( row->type ) );
330
331 return row;
332}
333
334
335static void setLibNickname( FOOTPRINT* aModule, const wxString& aNickname,
336 const wxString& aFootprintName )
337{
338 // The library cannot know its own name, because it might have been renamed or moved.
339 // Therefore footprints cannot know their own library nickname when residing in
340 // a footprint library.
341 // Only at this API layer can we tell the footprint about its actual library nickname.
342 if( aModule )
343 {
344 // remove "const"-ness, I really do want to set nickname without
345 // having to copy the LIB_ID and its two strings, twice each.
346 LIB_ID& fpid = (LIB_ID&) aModule->GetFPID();
347
348 // Catch any misbehaving plugin, which should be setting internal footprint name properly:
349 wxASSERT( aFootprintName == fpid.GetLibItemName().wx_str() );
350
351 // and clearing nickname
352 wxASSERT( !fpid.GetLibNickname().size() );
353
354 fpid.SetLibNickname( aNickname );
355 }
356}
357
358
359const FOOTPRINT* FP_LIB_TABLE::GetEnumeratedFootprint( const wxString& aNickname,
360 const wxString& aFootprintName )
361{
362 const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
363 wxASSERT( (PLUGIN*) row->plugin );
364
365 return row->plugin->GetEnumeratedFootprint( row->GetFullURI( true ), aFootprintName,
366 row->GetProperties() );
367}
368
369
370bool FP_LIB_TABLE::FootprintExists( const wxString& aNickname, const wxString& aFootprintName )
371{
372 try
373 {
374 const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
375 wxASSERT( (PLUGIN*) row->plugin );
376
377 return row->plugin->FootprintExists( row->GetFullURI( true ), aFootprintName,
378 row->GetProperties() );
379 }
380 catch( ... )
381 {
382 return false;
383 }
384}
385
386
387FOOTPRINT* FP_LIB_TABLE::FootprintLoad( const wxString& aNickname,
388 const wxString& aFootprintName, bool aKeepUUID )
389{
390 const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
391 wxASSERT( (PLUGIN*) row->plugin );
392
393 FOOTPRINT* ret = row->plugin->FootprintLoad( row->GetFullURI( true ), aFootprintName,
394 aKeepUUID, row->GetProperties() );
395
396 setLibNickname( ret, row->GetNickName(), aFootprintName );
397
398 return ret;
399}
400
401
403 const FOOTPRINT* aFootprint, bool aOverwrite )
404{
405 const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
406 wxASSERT( (PLUGIN*) row->plugin );
407
408 if( !aOverwrite )
409 {
410 // Try loading the footprint to see if it already exists, caller wants overwrite
411 // protection, which is atypical, not the default.
412
413 wxString fpname = aFootprint->GetFPID().GetLibItemName();
414
415 std::unique_ptr<FOOTPRINT> footprint( row->plugin->FootprintLoad( row->GetFullURI( true ),
416 fpname,
417 row->GetProperties() ) );
418
419 if( footprint.get() )
420 return SAVE_SKIPPED;
421 }
422
423 row->plugin->FootprintSave( row->GetFullURI( true ), aFootprint, row->GetProperties() );
424
425 return SAVE_OK;
426}
427
428
429void FP_LIB_TABLE::FootprintDelete( const wxString& aNickname, const wxString& aFootprintName )
430{
431 const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
432 wxASSERT( (PLUGIN*) row->plugin );
433 return row->plugin->FootprintDelete( row->GetFullURI( true ), aFootprintName,
434 row->GetProperties() );
435}
436
437
438bool FP_LIB_TABLE::IsFootprintLibWritable( const wxString& aNickname )
439{
440 const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
441 wxASSERT( (PLUGIN*) row->plugin );
442 return row->plugin->IsFootprintLibWritable( row->GetFullURI( true ) );
443}
444
445
446void FP_LIB_TABLE::FootprintLibDelete( const wxString& aNickname )
447{
448 const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
449 wxASSERT( (PLUGIN*) row->plugin );
450 row->plugin->FootprintLibDelete( row->GetFullURI( true ), row->GetProperties() );
451}
452
453
454void FP_LIB_TABLE::FootprintLibCreate( const wxString& aNickname )
455{
456 const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
457 wxASSERT( (PLUGIN*) row->plugin );
458 row->plugin->FootprintLibCreate( row->GetFullURI( true ), row->GetProperties() );
459}
460
461
463 bool aKeepUUID )
464{
465 wxString nickname = aFootprintId.GetLibNickname();
466 wxString fpname = aFootprintId.GetLibItemName();
467
468 if( nickname.size() )
469 {
470 return FootprintLoad( nickname, fpname, aKeepUUID );
471 }
472
473 // nickname is empty, sequentially search (alphabetically) all libs/nicks for first match:
474 else
475 {
476 std::vector<wxString> nicks = GetLogicalLibs();
477
478 // Search each library going through libraries alphabetically.
479 for( unsigned i = 0; i < nicks.size(); ++i )
480 {
481 // FootprintLoad() returns NULL on not found, does not throw exception
482 // unless there's an IO_ERROR.
483 FOOTPRINT* ret = FootprintLoad( nicks[i], fpname, aKeepUUID );
484
485 if( ret )
486 return ret;
487 }
488
489 return nullptr;
490 }
491}
492
493
495{
496 return wxS( "KICAD7_FOOTPRINT_DIR" );
497}
498
499
500class PCM_FP_LIB_TRAVERSER final : public wxDirTraverser
501{
502public:
503 explicit PCM_FP_LIB_TRAVERSER( const wxString& aPath, FP_LIB_TABLE& aTable,
504 const wxString& aPrefix ) :
505 m_lib_table( aTable ),
506 m_path_prefix( aPath ),
507 m_lib_prefix( aPrefix )
508 {
509 wxFileName f( aPath, wxS( "" ) );
510 m_prefix_dir_count = f.GetDirCount();
511 }
512
513 wxDirTraverseResult OnFile( const wxString& aFilePath ) override { return wxDIR_CONTINUE; }
514
515 wxDirTraverseResult OnDir( const wxString& dirPath ) override
516 {
517 wxFileName dir = wxFileName::DirName( dirPath );
518
519 // consider a directory to be a lib if it's name ends with .pretty and
520 // it is under $KICAD7_3RD_PARTY/footprints/<pkgid>/ i.e. has nested level of at least +3
521 if( dirPath.EndsWith( wxS( ".pretty" ) ) && dir.GetDirCount() >= m_prefix_dir_count + 3 )
522 {
523 wxArrayString parts = dir.GetDirs();
524 parts.RemoveAt( 0, m_prefix_dir_count );
525 parts.Insert( wxS( "${KICAD7_3RD_PARTY}" ), 0 );
526
527 wxString libPath = wxJoin( parts, '/' );
528
529 if( !m_lib_table.HasLibraryWithPath( libPath ) )
530 {
531 wxString name = parts.Last().substr( 0, parts.Last().length() - 7 );
532 wxString nickname = wxString::Format( wxS( "%s%s" ), m_lib_prefix, name );
533
534 if( m_lib_table.HasLibrary( nickname ) )
535 {
536 int increment = 1;
537 do
538 {
539 nickname = wxString::Format( wxS( "%s%s_%d" ), m_lib_prefix, name, increment );
540 increment++;
541 } while( m_lib_table.HasLibrary( nickname ) );
542 }
543
545 new FP_LIB_TABLE_ROW( nickname, libPath, wxT( "KiCad" ), wxEmptyString,
546 _( "Added by Plugin and Content Manager" ) ) );
547 }
548 }
549
550 return wxDIR_CONTINUE;
551 }
552
553private:
556 wxString m_lib_prefix;
558};
559
560
562{
563 bool tableExists = true;
564 wxFileName fn = GetGlobalTableFileName();
565
566 if( !fn.FileExists() )
567 {
568 tableExists = false;
569
570 if( !fn.DirExists() && !fn.Mkdir( 0x777, wxPATH_MKDIR_FULL ) )
571 {
572 THROW_IO_ERROR( wxString::Format( _( "Cannot create global library table path '%s'." ),
573 fn.GetPath() ) );
574 }
575
576 // Attempt to copy the default global file table from the KiCad
577 // template folder to the user's home configuration path.
578 SEARCH_STACK ss;
579
580 SystemDirsAppend( &ss );
581
582 wxString templatePath =
583 Pgm().GetLocalEnvVariables().at( wxT( "KICAD7_TEMPLATE_DIR" ) ).GetValue();
584
585 if( !templatePath.IsEmpty() )
586 ss.AddPaths( templatePath, 0 );
587
588 wxString fileName = ss.FindValidPath( global_tbl_name );
589
590 // The fallback is to create an empty global footprint table for the user to populate.
591 if( fileName.IsEmpty() || !::wxCopyFile( fileName, fn.GetFullPath(), false ) )
592 {
593 FP_LIB_TABLE emptyTable;
594
595 emptyTable.Save( fn.GetFullPath() );
596 }
597 }
598
599 aTable.Clear();
600 aTable.Load( fn.GetFullPath() );
601
602 SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
604
605 wxString packagesPath = Pgm().GetLocalEnvVariables().at( wxT( "KICAD7_3RD_PARTY" ) ).GetValue();
606
607 if( settings->m_PcmLibAutoAdd )
608 {
609 // Scan for libraries in PCM packages directory
610
611 wxFileName d( packagesPath, wxS( "" ) );
612 d.AppendDir( wxS( "footprints" ) );
613
614 if( d.DirExists() )
615 {
616 PCM_FP_LIB_TRAVERSER traverser( packagesPath, aTable, settings->m_PcmLibPrefix );
617 wxDir dir( d.GetPath() );
618
619 dir.Traverse( traverser );
620 }
621 }
622
623 if( settings->m_PcmLibAutoRemove )
624 {
625 // Remove PCM libraries that no longer exist
626 std::vector<wxString> to_remove;
627
628 for( size_t i = 0; i < aTable.GetCount(); i++ )
629 {
630 LIB_TABLE_ROW& row = aTable.At( i );
631 wxString path = row.GetFullURI( true );
632
633 if( path.StartsWith( packagesPath ) && !wxDir::Exists( path ) )
634 to_remove.push_back( row.GetNickName() );
635 }
636
637 for( const wxString& nickName : to_remove )
638 aTable.RemoveRow( aTable.FindRow( nickName ) );
639 }
640
641 return tableExists;
642}
643
644
646{
647 wxFileName fn;
648
650 fn.SetName( global_tbl_name );
651
652 return fn.GetFullPath();
653}
const char * name
Definition: DXF_plotter.cpp:56
const LIB_ID & GetFPID() const
Definition: footprint.h:212
Hold a record identifying a library accessed by the appropriate footprint library PLUGIN object in th...
Definition: fp_lib_table.h:41
void SetType(const wxString &aType) override
Change the type represented by this row.
bool operator==(const FP_LIB_TABLE_ROW &aRow) const
void setPlugin(PLUGIN *aPlugin)
Definition: fp_lib_table.h:84
PLUGIN::RELEASER plugin
Definition: fp_lib_table.h:91
const FP_LIB_TABLE_ROW * FindRow(const wxString &aNickName, bool aCheckIfEnabled=false)
Return an FP_LIB_TABLE_ROW if aNickName is found in this table or in any chained fall back table frag...
void FootprintDelete(const wxString &aNickname, const wxString &aFootprintName)
Delete the aFootprintName from the library given by aNickname.
static bool LoadGlobalTable(FP_LIB_TABLE &aTable)
Load the global footprint library table into aTable.
bool operator==(const FP_LIB_TABLE &aFpTable) const
void FootprintEnumerate(wxArrayString &aFootprintNames, const wxString &aNickname, bool aBestEfforts)
Return a list of footprint names contained within the library given by aNickname.
void FootprintLibCreate(const wxString &aNickname)
FP_LIB_TABLE(FP_LIB_TABLE *aFallBackTable=nullptr)
Build a footprint library table by pre-pending this table fragment in front of aFallBackTable.
const FOOTPRINT * GetEnumeratedFootprint(const wxString &aNickname, const wxString &aFootprintName)
A version of FootprintLoad() for use after FootprintEnumerate() for more efficient cache management.
static const wxString GlobalPathEnvVariableName()
Return the name of the environment variable used to hold the directory of locally installed "KiCad sp...
FOOTPRINT * FootprintLoadWithOptionalNickname(const LIB_ID &aFootprintId, bool aKeepUUID=false)
Load a footprint having aFootprintId with possibly an empty nickname.
long long GenerateTimestamp(const wxString *aNickname)
Generate a hashed timestamp representing the last-mod-times of the library indicated by aNickname,...
void FootprintLibDelete(const wxString &aNickname)
bool FootprintExists(const wxString &aNickname, const wxString &aFootprintName)
Indicates whether or not the given footprint already exists in the given library.
virtual void Parse(LIB_TABLE_LEXER *aLexer) override
Parse the #LIB_TABLE_LEXER s-expression library table format into the appropriate LIB_TABLE_ROW objec...
bool IsFootprintLibWritable(const wxString &aNickname)
Return true if the library given by aNickname is writable.
void PrefetchLib(const wxString &aNickname)
If possible, prefetches the specified library (e.g.
virtual void Format(OUTPUTFORMATTER *aOutput, int aIndentLevel) const override
Generate the table in s-expression format to aOutput with an indentation level of aIndentLevel.
SAVE_T
The set of return values from FootprintSave() below.
Definition: fp_lib_table.h:199
FOOTPRINT * FootprintLoad(const wxString &aNickname, const wxString &aFootprintName, bool aKeepUUID=false)
Load a footprint having aFootprintName from the library given by aNickname.
SAVE_T FootprintSave(const wxString &aNickname, const FOOTPRINT *aFootprint, bool aOverwrite=true)
Write aFootprint to an existing library given by aNickname.
static wxString GetGlobalTableFileName()
PCB_FILE_T
The set of file types that the IO_MGR knows about, and for which there has been a plugin written.
Definition: io_mgr.h:54
@ KICAD_SEXP
S-expression Pcbnew file format.
Definition: io_mgr.h:56
static PCB_FILE_T EnumFromStr(const wxString &aFileType)
Return the PCB_FILE_T from the corresponding plugin type name: "kicad", "legacy", etc.
Definition: io_mgr.cpp:93
static PLUGIN * PluginFind(PCB_FILE_T aFileType)
Return a PLUGIN which the caller can use to import, export, save, or load design documents.
Definition: io_mgr.cpp:58
wxString m_PcmLibPrefix
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:49
int SetLibNickname(const UTF8 &aNickname)
Override the logical library name portion of the LIB_ID to aNickname.
Definition: lib_id.cpp:98
const UTF8 & GetLibItemName() const
Definition: lib_id.h:102
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:87
Hold a record identifying a library accessed by the appropriate plug in object in the LIB_TABLE.
const wxString & GetNickName() const
const wxString GetFullURI(bool aSubstituted=false) const
Return the full location specifying URI for the LIB, either in original UI form or in environment var...
bool operator==(const LIB_TABLE_ROW &r) const
const STRING_UTF8_MAP * GetProperties() const
Return the constant #PROPERTIES for this library (LIB_TABLE_ROW).
Manage LIB_TABLE_ROW records (rows), and can be searched based on library nickname.
std::vector< wxString > GetLogicalLibs()
Return the logical library names, all of them that are pertinent to a look up done on this LIB_TABLE.
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library table.
int m_version
Versioning to handle importing old tables.
LIB_TABLE_ROW & At(unsigned aIndex)
Get the 'n'th LIB_TABLE_ROW object.
bool InsertRow(LIB_TABLE_ROW *aRow, bool doReplace=false)
Adds aRow if it does not already exist or if doReplace is true.
LIB_TABLE_ROWS m_rows
void Load(const wxString &aFileName)
Load the library table using the path defined by aFileName aFallBackTable.
bool HasLibraryWithPath(const wxString &aPath) const
Test for the existence of aPath in the library table.
bool RemoveRow(const LIB_TABLE_ROW *aRow)
Removes a row from the table.
void Clear()
Delete all rows.
unsigned GetCount() const
Get the number of rows contained in the table.
void Save(const wxString &aFileName) const
Write this library table to aFileName in s-expression form.
LIB_TABLE_ROW * findRow(const wxString &aNickname, bool aCheckIfEnabled=false) const
Return a LIB_TABLE_ROW if aNickname is found in this table or in any chained fallBack table fragment,...
An interface used to output 8 bit text in a convenient way.
Definition: richio.h:310
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:433
PCM_FP_LIB_TRAVERSER(const wxString &aPath, FP_LIB_TABLE &aTable, const wxString &aPrefix)
wxDirTraverseResult OnFile(const wxString &aFilePath) override
wxDirTraverseResult OnDir(const wxString &dirPath) override
FP_LIB_TABLE & m_lib_table
void release()
Definition: io_mgr.h:585
A base class that BOARD loading and saving plugins should derive from.
Definition: io_mgr.h:270
virtual const FOOTPRINT * GetEnumeratedFootprint(const wxString &aLibraryPath, const wxString &aFootprintName, const STRING_UTF8_MAP *aProperties=nullptr)
A version of FootprintLoad() for use after FootprintEnumerate() for more efficient cache management.
Definition: plugin.cpp:80
virtual void FootprintLibCreate(const wxString &aLibraryPath, const STRING_UTF8_MAP *aProperties=nullptr)
Create a new empty footprint library at aLibraryPath empty.
Definition: plugin.cpp:122
virtual bool FootprintLibDelete(const wxString &aLibraryPath, const STRING_UTF8_MAP *aProperties=nullptr)
Delete an existing footprint library and returns true, or if library does not exist returns false,...
Definition: plugin.cpp:129
virtual void FootprintSave(const wxString &aLibraryPath, const FOOTPRINT *aFootprint, const STRING_UTF8_MAP *aProperties=nullptr)
Write aFootprint to an existing library located at aLibraryPath.
Definition: plugin.cpp:106
virtual void FootprintDelete(const wxString &aLibraryPath, const wxString &aFootprintName, const STRING_UTF8_MAP *aProperties=nullptr)
Delete aFootprintName from the library at aLibraryPath.
Definition: plugin.cpp:114
virtual bool FootprintExists(const wxString &aLibraryPath, const wxString &aFootprintName, const STRING_UTF8_MAP *aProperties=nullptr)
Check for the existence of a footprint.
Definition: plugin.cpp:89
virtual FOOTPRINT * FootprintLoad(const wxString &aLibraryPath, const wxString &aFootprintName, bool aKeepUUID=false, const STRING_UTF8_MAP *aProperties=nullptr)
Load a footprint having aFootprintName from the aLibraryPath containing a library format that this PL...
Definition: plugin.cpp:97
virtual bool IsFootprintLibWritable(const wxString &aLibraryPath)
Return true if the library at aLibraryPath is writable.
Definition: plugin.cpp:137
virtual long long GetLibraryTimestamp(const wxString &aLibraryPath) const =0
Generate a timestamp representing all the files in the library (including the library directory).
virtual void PrefetchLib(const wxString &aLibraryPath, const STRING_UTF8_MAP *aProperties=nullptr)
If possible, prefetches the specified library (e.g.
Definition: plugin.cpp:75
virtual void FootprintEnumerate(wxArrayString &aFootprintNames, const wxString &aLibraryPath, bool aBestEfforts, const STRING_UTF8_MAP *aProperties=nullptr)
Return a list of footprint names contained within the library at aLibraryPath.
Definition: plugin.cpp:67
Look for files in a number of paths.
Definition: search_stack.h:42
void AddPaths(const wxString &aPaths, int aIndex=-1)
Insert or append path(s).
T * GetAppSettings(bool aLoadNow=true)
Returns a handle to the a given settings by type If the settings have already been loaded,...
static wxString GetUserSettingsPath()
Return the user configuration path used to store KiCad's configuration files.
std::string::size_type size() const
Definition: utf8.h:110
wxString wx_str() const
Definition: utf8.cpp:46
#define _(s)
static const wxChar global_tbl_name[]
static void setLibNickname(FOOTPRINT *aModule, const wxString &aNickname, const wxString &aFootprintName)
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
LIB_TABLE_ROWS::const_iterator LIB_TABLE_ROWS_CITER
see class PGM_BASE
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
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:111
void SystemDirsAppend(SEARCH_STACK *aSearchStack)
Append system places to aSearchStack in a platform specific way and pertinent to KiCad programs.
System directories search utilities.