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 <properties.h>
36 #include <richio.h>
37 
38 
39 #define FP_LATE_ENVVAR 1
40 
41 class OUTPUTFORMATTER;
42 class LIB_TABLE_LEXER;
43 class LIB_ID;
44 class LIB_TABLE_ROW;
45 class LIB_TABLE_GRID;
46 class IO_ERROR;
47 
48 
49 typedef boost::ptr_vector< LIB_TABLE_ROW > LIB_TABLE_ROWS;
50 typedef LIB_TABLE_ROWS::iterator LIB_TABLE_ROWS_ITER;
51 typedef LIB_TABLE_ROWS::const_iterator LIB_TABLE_ROWS_CITER;
52 
53 
59 LIB_TABLE_ROW* new_clone( const LIB_TABLE_ROW& aRow );
60 
61 
66 class LIB_TABLE_ROW : boost::noncopyable
67 {
68 public:
70  enabled( true ),
71  m_loaded( false )
72  {
73  }
74 
75  virtual ~LIB_TABLE_ROW()
76  {
77  }
78 
79  LIB_TABLE_ROW( const wxString& aNick, const wxString& aURI, const wxString& aOptions,
80  const wxString& aDescr = wxEmptyString ) :
81  nickName( aNick ),
82  description( aDescr ),
83  enabled( true ),
84  m_loaded( false )
85  {
86  properties.reset();
87  SetOptions( aOptions );
88  SetFullURI( aURI );
89  }
90 
91  bool operator==( const LIB_TABLE_ROW& r ) const;
92 
93  bool operator!=( const LIB_TABLE_ROW& r ) const { return !( *this == r ); }
94 
98  const wxString& GetNickName() const { return nickName; }
99 
103  void SetNickName( const wxString& aNickName ) { nickName = aNickName; }
104 
108  bool GetIsLoaded() const { return m_loaded; }
109 
113  void SetLoaded( bool aLoaded ) { m_loaded = aLoaded; };
114 
118  bool GetIsEnabled() const { return enabled; }
119 
123  void SetEnabled( bool aEnabled = true ) { enabled = aEnabled; }
124 
128  virtual const wxString GetType() const = 0;
129 
134  virtual void SetType( const wxString& aType ) = 0;
135 
142  const wxString GetFullURI( bool aSubstituted = false ) const;
143 
147  void SetFullURI( const wxString& aFullURI );
148 
153  const wxString& GetOptions() const { return options; }
154 
158  void SetOptions( const wxString& aOptions );
159 
163  const wxString& GetDescr() const { return description; }
164 
168  void SetDescr( const wxString& aDescr ) { description = aDescr; }
169 
174  const PROPERTIES* GetProperties() const { return properties.get(); }
175 
184  void Format( OUTPUTFORMATTER* out, int nestLevel ) const;
185 
187  {
188  return do_clone();
189  }
190 
191 protected:
192  LIB_TABLE_ROW( const LIB_TABLE_ROW& aRow ) :
193  nickName( aRow.nickName ),
194  uri_user( aRow.uri_user ),
195 #if !FP_LATE_ENVVAR
196  uri_expanded( aRow.uri_expanded ),
197 #endif
198  options( aRow.options ),
199  description( aRow.description ),
200  enabled( aRow.enabled ),
201  m_loaded( aRow.m_loaded )
202  {
203  if( aRow.properties )
204  properties = std::make_unique<PROPERTIES>( *aRow.properties.get() );
205  else
206  properties.reset();
207  }
208 
209  void operator=( const LIB_TABLE_ROW& aRow );
210 
211 private:
212  virtual LIB_TABLE_ROW* do_clone() const = 0;
213 
214  void setProperties( PROPERTIES* aProperties );
215 
216  wxString nickName;
217  wxString uri_user;
218 
219 #if !FP_LATE_ENVVAR
220  wxString uri_expanded;
221 #endif
222 
223  wxString options;
224  wxString description;
225 
226  bool enabled = true;
227  bool m_loaded = false;
228 
229  std::unique_ptr< PROPERTIES > properties;
230 };
231 
232 
278 class LIB_TABLE : public PROJECT::_ELEM
279 {
280 public:
293  virtual void Parse( LIB_TABLE_LEXER* aLexer ) = 0;
294 
305  virtual void Format( OUTPUTFORMATTER* aOutput, int aIndentLevel ) const = 0;
306 
315  LIB_TABLE( LIB_TABLE* aFallBackTable = nullptr );
316 
317  virtual ~LIB_TABLE();
318 
320  void Clear()
321  {
322  std::lock_guard<std::recursive_mutex> lock( m_nickIndexMutex );
323 
324  rows.clear();
325  nickIndex.clear();
326  }
327 
334  bool operator==( const LIB_TABLE& r ) const
335  {
336  if( rows.size() == r.rows.size() )
337  {
338  unsigned i;
339 
340  for( i = 0; i < rows.size() && rows[i] == r.rows[i]; ++i )
341  ;
342 
343  if( i == rows.size() )
344  return true;
345  }
346 
347  return false;
348  }
349 
350  bool operator!=( const LIB_TABLE& r ) const { return !( *this == r ); }
351 
355  unsigned GetCount() const
356  {
357  return rows.size();
358  }
359 
365  LIB_TABLE_ROW& At( unsigned aIndex )
366  {
367  return rows[aIndex];
368  }
369 
373  const LIB_TABLE_ROW& At( unsigned aIndex ) const
374  {
375  return rows[aIndex];
376  }
377 
386  bool IsEmpty( bool aIncludeFallback = true );
387 
392  const wxString GetDescription( const wxString& aNickname );
393 
400  bool HasLibrary( const wxString& aNickname, bool aCheckEnabled = false ) const;
401 
406  std::vector<wxString> GetLogicalLibs();
407 
411  wxString GetFullURI( const wxString& aLibNickname, bool aExpandEnvVars = true ) const;
412 
425  bool InsertRow( LIB_TABLE_ROW* aRow, bool doReplace = false );
426 
432  bool RemoveRow( LIB_TABLE_ROW* aRow )
433  {
434  for( auto iter = rows.begin(); iter != rows.end(); ++iter )
435  {
436  if( *iter == *aRow )
437  {
438  rows.erase( iter, iter + 1 );
439  return true;
440  }
441  }
442  return false;
443  }
444 
449  const LIB_TABLE_ROW* FindRowByURI( const wxString& aURI );
450 
459  void Load( const wxString& aFileName );
460 
466  void Save( const wxString& aFileName ) const;
467 
480  static PROPERTIES* ParseOptions( const std::string& aOptionsList );
481 
492  static UTF8 FormatOptions( const PROPERTIES* aProperties );
493 
494 protected:
503  LIB_TABLE_ROW* findRow( const wxString& aNickname, bool aCheckIfEnabled = false ) const;
504 
505  void reindex()
506  {
507  std::lock_guard<std::recursive_mutex> lock( m_nickIndexMutex );
508 
509  nickIndex.clear();
510 
511  for( LIB_TABLE_ROWS_ITER it = rows.begin(); it != rows.end(); ++it )
512  nickIndex.insert( INDEX_VALUE( it->GetNickName(), it - rows.begin() ) );
513  }
514 
515  void ensureIndex()
516  {
517  std::lock_guard<std::recursive_mutex> lock( m_nickIndexMutex );
518 
519  // The dialog lib table editor may not maintain the nickIndex.
520  // Lazy indexing may be required. To handle lazy indexing, we must enforce
521  // that "nickIndex" is either empty or accurate, but never inaccurate.
522  if( !nickIndex.size() )
523  reindex();
524  }
525 
526 private:
527  friend class PANEL_FP_LIB_TABLE;
528  friend class LIB_TABLE_GRID;
529 
530 protected:
532 
534  typedef std::map<wxString,int> INDEX; // "int" is std::vector array index
535  typedef INDEX::iterator INDEX_ITER;
536  typedef INDEX::const_iterator INDEX_CITER;
537  typedef INDEX::value_type INDEX_VALUE;
538 
541 
543 
545  mutable std::recursive_mutex m_nickIndexMutex;
546 };
547 
548 #endif // _LIB_TABLE_BASE_H_
An 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to and fro...
Definition: utf8.h:70
void ensureIndex()
const wxString & GetOptions() const
Return the options string, which may hold a password or anything else needed to instantiate the under...
LIB_TABLE_ROW(const LIB_TABLE_ROW &aRow)
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library table.
Hold a record identifying a library accessed by the appropriate plug in object in the LIB_TABLE.
void Clear()
Delete all rows.
bool InsertRow(LIB_TABLE_ROW *aRow, bool doReplace=false)
Adds aRow if it does not already exist or if doReplace is true.
void reindex()
unsigned GetCount() const
Get the number of rows contained in the table.
std::map< wxString, int > INDEX
this is a non-owning index into the LIB_TABLE_ROWS table
bool enabled
Whether the LIB_TABLE_ROW is enabled.
INDEX::const_iterator INDEX_CITER
void setProperties(PROPERTIES *aProperties)
LIB_TABLE(LIB_TABLE *aFallBackTable=nullptr)
Build a library table by pre-pending this table fragment in front of aFallBackTable.
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 ...
An interface used to output 8 bit text in a convenient way.
Definition: richio.h:309
bool operator==(const LIB_TABLE &r) const
Compares this table against another.
LIB_TABLE_ROWS rows
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:51
virtual const wxString GetType() const =0
Return the type of library represented by this row.
A name/value tuple with unique names and optional values.
Definition: properties.h:33
std::unique_ptr< PROPERTIES > properties
bool operator==(const LIB_TABLE_ROW &r) const
LIB_TABLE * fallBack
static UTF8 FormatOptions(const PROPERTIES *aProperties)
Returns a list of options from the aProperties parameter.
bool GetIsLoaded() const
INDEX::value_type INDEX_VALUE
const wxString & GetDescr() const
Return the description of the library referenced by this row.
This abstract base class mixes any object derived from LIB_TABLE into wxGridTableBase so the result c...
virtual ~LIB_TABLE()
wxString description
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...
void SetLoaded(bool aLoaded)
Mark the row as being a loaded library.
void SetEnabled(bool aEnabled=true)
Change the enabled status of this library.
const wxString & GetNickName() const
static PROPERTIES * ParseOptions(const std::string &aOptionsList)
Parses aOptionsList and places the result into a PROPERTIES object which is returned.
LIB_TABLE_ROW * clone() const
bool GetIsEnabled() const
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...
const wxString GetDescription(const wxString &aNickname)
virtual ~LIB_TABLE_ROW()
wxString GetFullURI(const wxString &aLibNickname, bool aExpandEnvVars=true) const
Return the full URI of the library mapped to aLibNickname.
const LIB_TABLE_ROW * FindRowByURI(const wxString &aURI)
const LIB_TABLE_ROW & At(unsigned aIndex) const
Get the 'n'th LIB_TABLE_ROW object.
virtual void Format(OUTPUTFORMATTER *aOutput, int aIndentLevel) const =0
Generate the table in s-expression format to aOutput with an indentation level of aIndentLevel.
void operator=(const LIB_TABLE_ROW &aRow)
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,...
void Load(const wxString &aFileName)
Load the library table using the path defined by aFileName aFallBackTable.
E_SERIE r
Definition: eserie.cpp:41
#define FP_LATE_ENVVAR
late=1/early=0 environment variable expansion
bool RemoveRow(LIB_TABLE_ROW *aRow)
Removes a row from the table.
bool operator!=(const LIB_TABLE &r) const
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 operator!=(const LIB_TABLE_ROW &r) const
LIB_TABLE_ROW * new_clone(const LIB_TABLE_ROW &aRow)
Allows boost pointer containers to make clones of the data stored in them.
void SetFullURI(const wxString &aFullURI)
Change the full URI for the library.
LIB_TABLE_ROWS::const_iterator LIB_TABLE_ROWS_CITER
LIB_TABLE_ROW & At(unsigned aIndex)
Get the 'n'th LIB_TABLE_ROW object.
INDEX::iterator INDEX_ITER
wxString options
virtual LIB_TABLE_ROW * do_clone() const =0
void SetNickName(const wxString &aNickName)
Change the logical name of this library, useful for an editor.
LIB_TABLE_ROWS::iterator LIB_TABLE_ROWS_ITER
void Save(const wxString &aFileName) const
Write this library table to aFileName in s-expression form.
A PROJECT can hold stuff it knows nothing about, in the form of _ELEM derivatives.
Definition: project.h:73
void SetOptions(const wxString &aOptions)
Change the library options strings.
wxString nickName
const PROPERTIES * GetProperties() const
Return the constant PROPERTIES for this library (LIB_TABLE_ROW).
boost::ptr_vector< LIB_TABLE_ROW > LIB_TABLE_ROWS
Dialog to show and edit symbol library tables.
LIB_TABLE_ROW(const wxString &aNick, const wxString &aURI, const wxString &aOptions, const wxString &aDescr=wxEmptyString)
std::recursive_mutex m_nickIndexMutex
Mutex to protect access to the nickIndex variable.
wxString uri_user
what user entered from UI or loaded from disk
void SetDescr(const wxString &aDescr)
Change the description of the library referenced by this row.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:75
INDEX nickIndex
this particular key is the nickName within each row.
bool m_loaded
Whether the LIB_TABLE_ROW is loaded.
bool IsEmpty(bool aIncludeFallback=true)
Return true if the table is empty.
std::vector< wxString > GetLogicalLibs()
Return the logical library names, all of them that are pertinent to a look up done on this LIB_TABLE.
Manage LIB_TABLE_ROW records (rows), and can be searched based on library nickname.