KiCad PCB EDA Suite
lib_table_base.h
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 change_log.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#ifndef _LIB_TABLE_BASE_H_
27#define _LIB_TABLE_BASE_H_
28
29#include <map>
30#include <boost/noncopyable.hpp>
31#include <boost/ptr_container/ptr_vector.hpp>
32#include <memory>
33#include <mutex>
34#include <project.h>
35#include <string_utf8_map.h>
36#include <richio.h>
37
38
39#define FP_LATE_ENVVAR 1
40
41class OUTPUTFORMATTER;
42class LIB_TABLE_LEXER;
43class LIB_ID;
44class LIB_TABLE_ROW;
45class LIB_TABLE_GRID;
46class LIB_TABLE;
47class IO_ERROR;
48
49
50typedef boost::ptr_vector< LIB_TABLE_ROW > LIB_TABLE_ROWS;
51typedef LIB_TABLE_ROWS::iterator LIB_TABLE_ROWS_ITER;
52typedef LIB_TABLE_ROWS::const_iterator LIB_TABLE_ROWS_CITER;
53
54
61
62
67class LIB_TABLE_ROW : boost::noncopyable
68{
69public:
71 enabled( true ),
72 visible( true ),
73 m_loaded( false ),
74 m_parent( nullptr )
75 {
76 }
77
79 {
80 }
81
82 LIB_TABLE_ROW( const wxString& aNick, const wxString& aURI, const wxString& aOptions,
83 const wxString& aDescr = wxEmptyString, LIB_TABLE* aParent = nullptr ) :
84 nickName( aNick ),
85 description( aDescr ),
86 enabled( true ),
87 visible( true ),
88 m_loaded( false ),
89 m_parent( aParent )
90 {
91 properties.reset();
92 SetOptions( aOptions );
93 SetFullURI( aURI );
94 }
95
96 bool operator==( const LIB_TABLE_ROW& r ) const;
97
98 bool operator!=( const LIB_TABLE_ROW& r ) const { return !( *this == r ); }
99
103 const wxString& GetNickName() const { return nickName; }
104
108 void SetNickName( const wxString& aNickName ) { nickName = aNickName; }
109
113 bool GetIsLoaded() const { return m_loaded; }
114
118 void SetLoaded( bool aLoaded ) { m_loaded = aLoaded; };
119
123 bool GetIsEnabled() const { return enabled; }
124
128 void SetEnabled( bool aEnabled = true ) { enabled = aEnabled; }
129
130 bool GetIsVisible() const { return visible; }
131
132 void SetVisible( bool aVisible = true ) { visible = aVisible; }
133
137 virtual const wxString GetType() const = 0;
138
143 virtual void SetType( const wxString& aType ) = 0;
144
151 const wxString GetFullURI( bool aSubstituted = false ) const;
152
156 void SetFullURI( const wxString& aFullURI );
157
162 const wxString& GetOptions() const { return options; }
163
167 void SetOptions( const wxString& aOptions );
168
172 const wxString& GetDescr() const { return description; }
173
177 void SetDescr( const wxString& aDescr ) { description = aDescr; }
178
179 LIB_TABLE* GetParent() const { return m_parent; }
180
181 void SetParent( LIB_TABLE* aParent ) { m_parent = aParent; }
182
183 std::mutex& GetMutex() { return m_loadMutex; }
184
189 const STRING_UTF8_MAP* GetProperties() const { return properties.get(); }
190
199 void Format( OUTPUTFORMATTER* out, int nestLevel ) const;
200
202 {
203 return do_clone();
204 }
205
206protected:
208 nickName( aRow.nickName ),
209 uri_user( aRow.uri_user ),
211 uri_expanded( aRow.uri_expanded ),
212#endif
213 options( aRow.options ),
214 description( aRow.description ),
215 enabled( aRow.enabled ),
216 visible( aRow.visible ),
217 m_loaded( aRow.m_loaded ),
218 m_parent( aRow.m_parent )
219 {
220 if( aRow.properties )
221 properties = std::make_unique<STRING_UTF8_MAP>( *aRow.properties.get() );
222 else
223 properties.reset();
224 }
225
226 void operator=( const LIB_TABLE_ROW& aRow );
227
228private:
229 virtual LIB_TABLE_ROW* do_clone() const = 0;
230
231 void setProperties( STRING_UTF8_MAP* aProperties );
232
233 wxString nickName;
234 wxString uri_user;
235
236#if !FP_LATE_ENVVAR
237 wxString uri_expanded;
238#endif
239
240 wxString options;
241 wxString description;
242
243 bool enabled = true;
244 bool visible = true;
245 bool m_loaded = false;
247
248 std::unique_ptr<STRING_UTF8_MAP> properties;
249
250 std::mutex m_loadMutex;
251};
252
253
300{
301public:
314 virtual void Parse( LIB_TABLE_LEXER* aLexer ) = 0;
315
326 virtual void Format( OUTPUTFORMATTER* aOutput, int aIndentLevel ) const = 0;
327
336 LIB_TABLE( LIB_TABLE* aFallBackTable = nullptr );
337
338 virtual ~LIB_TABLE();
339
341 void Clear()
342 {
343 std::lock_guard<std::mutex> lock( m_nickIndexMutex );
344
345 rows.clear();
346 nickIndex.clear();
347 }
348
355 bool operator==( const LIB_TABLE& r ) const
356 {
357 if( rows.size() == r.rows.size() )
358 {
359 unsigned i;
360
361 for( i = 0; i < rows.size() && rows[i] == r.rows[i]; ++i )
362 ;
363
364 if( i == rows.size() )
365 return true;
366 }
367
368 return false;
369 }
370
371 bool operator!=( const LIB_TABLE& r ) const { return !( *this == r ); }
372
376 unsigned GetCount() const
377 {
378 return rows.size();
379 }
380
386 LIB_TABLE_ROW& At( unsigned aIndex )
387 {
388 return rows[aIndex];
389 }
390
394 const LIB_TABLE_ROW& At( unsigned aIndex ) const
395 {
396 return rows[aIndex];
397 }
398
407 bool IsEmpty( bool aIncludeFallback = true );
408
413 const wxString GetDescription( const wxString& aNickname );
414
421 bool HasLibrary( const wxString& aNickname, bool aCheckEnabled = false ) const;
422
429 bool HasLibraryWithPath( const wxString& aPath ) const;
430
435 std::vector<wxString> GetLogicalLibs();
436
440 wxString GetFullURI( const wxString& aLibNickname, bool aExpandEnvVars = true ) const;
441
454 bool InsertRow( LIB_TABLE_ROW* aRow, bool doReplace = false );
455
461 bool RemoveRow( const LIB_TABLE_ROW* aRow )
462 {
463 for( auto iter = rows.begin(); iter != rows.end(); ++iter )
464 {
465 if( *iter == *aRow )
466 {
467 rows.erase( iter, iter + 1 );
468 return true;
469 }
470 }
471 return false;
472 }
473
478 const LIB_TABLE_ROW* FindRowByURI( const wxString& aURI );
479
488 void Load( const wxString& aFileName );
489
495 void Save( const wxString& aFileName ) const;
496
509 static STRING_UTF8_MAP* ParseOptions( const std::string& aOptionsList );
510
521 static UTF8 FormatOptions( const STRING_UTF8_MAP* aProperties );
522
523protected:
532 LIB_TABLE_ROW* findRow( const wxString& aNickname, bool aCheckIfEnabled = false ) const;
533
534 void reindex()
535 {
536 std::lock_guard<std::mutex> lock( m_nickIndexMutex );
537
538 nickIndex.clear();
539
540 for( LIB_TABLE_ROWS_ITER it = rows.begin(); it != rows.end(); ++it )
541 nickIndex.insert( INDEX_VALUE( it->GetNickName(), it - rows.begin() ) );
542 }
543
545 {
546 // The dialog lib table editor may not maintain the nickIndex.
547 // Lazy indexing may be required. To handle lazy indexing, we must enforce
548 // that "nickIndex" is either empty or accurate, but never inaccurate.
549 if( !nickIndex.size() )
550 reindex();
551 }
552
553private:
554 friend class PANEL_FP_LIB_TABLE;
555 friend class LIB_TABLE_GRID;
556
557protected:
559
561 typedef std::map<wxString,int> INDEX; // "int" is std::vector array index
562 typedef INDEX::iterator INDEX_ITER;
563 typedef INDEX::const_iterator INDEX_CITER;
564 typedef INDEX::value_type INDEX_VALUE;
565
568
570
572 mutable std::mutex m_nickIndexMutex;
573};
574
575#endif // _LIB_TABLE_BASE_H_
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:76
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:49
This abstract base class mixes any object derived from LIB_TABLE into wxGridTableBase so the result c...
Hold a record identifying a library accessed by the appropriate plug in object in the LIB_TABLE.
void SetFullURI(const wxString &aFullURI)
Change the full URI for the library.
bool visible
Whether the LIB_TABLE_ROW is visible in choosers.
const wxString & GetOptions() const
Return the options string, which may hold a password or anything else needed to instantiate the under...
std::mutex & GetMutex()
wxString nickName
const wxString & GetDescr() const
Return the description of the library referenced by this row.
virtual LIB_TABLE_ROW * do_clone() const =0
bool GetIsLoaded() const
std::unique_ptr< STRING_UTF8_MAP > properties
void SetVisible(bool aVisible=true)
void operator=(const LIB_TABLE_ROW &aRow)
wxString options
void SetNickName(const wxString &aNickName)
Change the logical name of this library, useful for an editor.
wxString uri_user
what user entered from UI or loaded from disk
LIB_TABLE * GetParent() const
bool operator!=(const LIB_TABLE_ROW &r) const
virtual const wxString GetType() const =0
Return the type of library represented by this row.
wxString description
void SetEnabled(bool aEnabled=true)
Change the enabled status of this library.
void SetDescr(const wxString &aDescr)
Change the description of the library referenced by this row.
void Format(OUTPUTFORMATTER *out, int nestLevel) const
Serialize this object as utf8 text to an OUTPUTFORMATTER, and tries to make it look good using multip...
bool enabled
Whether the LIB_TABLE_ROW is enabled.
void SetParent(LIB_TABLE *aParent)
bool m_loaded
Whether the LIB_TABLE_ROW is loaded.
void setProperties(STRING_UTF8_MAP *aProperties)
LIB_TABLE_ROW(const LIB_TABLE_ROW &aRow)
void SetLoaded(bool aLoaded)
Mark the row as being a loaded library.
virtual ~LIB_TABLE_ROW()
LIB_TABLE * m_parent
Pointer to the table this row lives in (maybe null)
virtual void SetType(const wxString &aType)=0
Change the type of library represented by this row that must be implemented in the derived object to ...
const wxString & GetNickName() const
std::mutex m_loadMutex
LIB_TABLE_ROW(const wxString &aNick, const wxString &aURI, const wxString &aOptions, const wxString &aDescr=wxEmptyString, LIB_TABLE *aParent=nullptr)
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...
LIB_TABLE_ROW * clone() const
bool operator==(const LIB_TABLE_ROW &r) const
bool GetIsEnabled() const
void SetOptions(const wxString &aOptions)
Change the library options strings.
const STRING_UTF8_MAP * GetProperties() const
Return the constant #PROPERTIES for this library (LIB_TABLE_ROW).
bool GetIsVisible() const
Manage LIB_TABLE_ROW records (rows), and can be searched based on library nickname.
const wxString GetDescription(const wxString &aNickname)
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.
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.
bool operator==(const LIB_TABLE &r) const
Compares this table against another.
virtual ~LIB_TABLE()
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.
LIB_TABLE_ROWS rows
virtual void Format(OUTPUTFORMATTER *aOutput, int aIndentLevel) const =0
Generate the table in s-expression format to aOutput with an indentation level of aIndentLevel.
bool RemoveRow(const LIB_TABLE_ROW *aRow)
Removes a row from the table.
void Clear()
Delete all rows.
INDEX::value_type INDEX_VALUE
wxString GetFullURI(const wxString &aLibNickname, bool aExpandEnvVars=true) const
Return the full URI of the library mapped to aLibNickname.
LIB_TABLE(LIB_TABLE *aFallBackTable=nullptr)
Build a library table by pre-pending this table fragment in front of aFallBackTable.
bool IsEmpty(bool aIncludeFallback=true)
Return true if the table is empty.
unsigned GetCount() const
Get the number of rows contained in the table.
virtual void Parse(LIB_TABLE_LEXER *aLexer)=0
Parse the #LIB_TABLE_LEXER s-expression library table format into the appropriate LIB_TABLE_ROW objec...
std::map< wxString, int > INDEX
this is a non-owning index into the LIB_TABLE_ROWS table
INDEX::const_iterator INDEX_CITER
LIB_TABLE * fallBack
const LIB_TABLE_ROW * FindRowByURI(const wxString &aURI)
std::mutex m_nickIndexMutex
Mutex to protect access to the nickIndex variable.
bool operator!=(const LIB_TABLE &r) const
void Save(const wxString &aFileName) const
Write this library table to aFileName in s-expression form.
void ensureIndex()
INDEX nickIndex
this particular key is the nickName within each row.
static STRING_UTF8_MAP * ParseOptions(const std::string &aOptionsList)
Parses aOptionsList and places the result into a #PROPERTIES object which is returned.
const LIB_TABLE_ROW & At(unsigned aIndex) const
Get the 'n'th LIB_TABLE_ROW object.
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,...
INDEX::iterator INDEX_ITER
void reindex()
static UTF8 FormatOptions(const STRING_UTF8_MAP *aProperties)
Returns a list of options from the aProperties parameter.
An interface used to output 8 bit text in a convenient way.
Definition: richio.h:310
Dialog to show and edit symbol library tables.
A PROJECT can hold stuff it knows nothing about, in the form of _ELEM derivatives.
Definition: project.h:75
A name/value tuple with unique names and optional values.
An 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to and fro...
Definition: utf8.h:71
E_SERIE r
Definition: eserie.cpp:41
boost::ptr_vector< LIB_TABLE_ROW > LIB_TABLE_ROWS
LIB_TABLE_ROWS::iterator LIB_TABLE_ROWS_ITER
LIB_TABLE_ROW * new_clone(const LIB_TABLE_ROW &aRow)
Allows boost pointer containers to make clones of the data stored in them.
LIB_TABLE_ROWS::const_iterator LIB_TABLE_ROWS_CITER
#define FP_LATE_ENVVAR
late=1/early=0 environment variable expansion