You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

635 lines
22 KiB

* KIWAY Milestone A): Make major modules into DLL/DSOs. ! The initial testing of this commit should be done using a Debug build so that all the wxASSERT()s are enabled. Also, be sure and keep enabled the USE_KIWAY_DLLs option. The tree won't likely build without it. Turning it off is senseless anyways. If you want stable code, go back to a prior version, the one tagged with "stable". * Relocate all functionality out of the wxApp derivative into more finely targeted purposes: a) DLL/DSO specific b) PROJECT specific c) EXE or process specific d) configuration file specific data e) configuration file manipulations functions. All of this functionality was blended into an extremely large wxApp derivative and that was incompatible with the desire to support multiple concurrently loaded DLL/DSO's ("KIFACE")s and multiple concurrently open projects. An amazing amount of organization come from simply sorting each bit of functionality into the proper box. * Switch to wxConfigBase from wxConfig everywhere except instantiation. * Add classes KIWAY, KIFACE, KIFACE_I, SEARCH_STACK, PGM_BASE, PGM_KICAD, PGM_SINGLE_TOP, * Remove "Return" prefix on many function names. * Remove obvious comments from CMakeLists.txt files, and from else() and endif()s. * Fix building boost for use in a DSO on linux. * Remove some of the assumptions in the CMakeLists.txt files that windows had to be the host platform when building windows binaries. * Reduce the number of wxStrings being constructed at program load time via static construction. * Pass wxConfigBase* to all SaveSettings() and LoadSettings() functions so that these functions are useful even when the wxConfigBase comes from another source, as is the case in the KICAD_MANAGER_FRAME. * Move the setting of the KIPRJMOD environment variable into class PROJECT, so that it can be moved into a project variable soon, and out of FP_LIB_TABLE. * Add the KIWAY_PLAYER which is associated with a particular PROJECT, and all its child wxFrames and wxDialogs now have a Kiway() member function which returns a KIWAY& that that window tree branch is in support of. This is like wxWindows DNA in that child windows get this member with proper value at time of construction. * Anticipate some of the needs for milestones B) and C) and make code adjustments now in an effort to reduce work in those milestones. * No testing has been done for python scripting, since milestone C) has that being largely reworked and re-thought-out.
12 years ago
* KIWAY Milestone A): Make major modules into DLL/DSOs. ! The initial testing of this commit should be done using a Debug build so that all the wxASSERT()s are enabled. Also, be sure and keep enabled the USE_KIWAY_DLLs option. The tree won't likely build without it. Turning it off is senseless anyways. If you want stable code, go back to a prior version, the one tagged with "stable". * Relocate all functionality out of the wxApp derivative into more finely targeted purposes: a) DLL/DSO specific b) PROJECT specific c) EXE or process specific d) configuration file specific data e) configuration file manipulations functions. All of this functionality was blended into an extremely large wxApp derivative and that was incompatible with the desire to support multiple concurrently loaded DLL/DSO's ("KIFACE")s and multiple concurrently open projects. An amazing amount of organization come from simply sorting each bit of functionality into the proper box. * Switch to wxConfigBase from wxConfig everywhere except instantiation. * Add classes KIWAY, KIFACE, KIFACE_I, SEARCH_STACK, PGM_BASE, PGM_KICAD, PGM_SINGLE_TOP, * Remove "Return" prefix on many function names. * Remove obvious comments from CMakeLists.txt files, and from else() and endif()s. * Fix building boost for use in a DSO on linux. * Remove some of the assumptions in the CMakeLists.txt files that windows had to be the host platform when building windows binaries. * Reduce the number of wxStrings being constructed at program load time via static construction. * Pass wxConfigBase* to all SaveSettings() and LoadSettings() functions so that these functions are useful even when the wxConfigBase comes from another source, as is the case in the KICAD_MANAGER_FRAME. * Move the setting of the KIPRJMOD environment variable into class PROJECT, so that it can be moved into a project variable soon, and out of FP_LIB_TABLE. * Add the KIWAY_PLAYER which is associated with a particular PROJECT, and all its child wxFrames and wxDialogs now have a Kiway() member function which returns a KIWAY& that that window tree branch is in support of. This is like wxWindows DNA in that child windows get this member with proper value at time of construction. * Anticipate some of the needs for milestones B) and C) and make code adjustments now in an effort to reduce work in those milestones. * No testing has been done for python scripting, since milestone C) has that being largely reworked and re-thought-out.
12 years ago
* KIWAY Milestone A): Make major modules into DLL/DSOs. ! The initial testing of this commit should be done using a Debug build so that all the wxASSERT()s are enabled. Also, be sure and keep enabled the USE_KIWAY_DLLs option. The tree won't likely build without it. Turning it off is senseless anyways. If you want stable code, go back to a prior version, the one tagged with "stable". * Relocate all functionality out of the wxApp derivative into more finely targeted purposes: a) DLL/DSO specific b) PROJECT specific c) EXE or process specific d) configuration file specific data e) configuration file manipulations functions. All of this functionality was blended into an extremely large wxApp derivative and that was incompatible with the desire to support multiple concurrently loaded DLL/DSO's ("KIFACE")s and multiple concurrently open projects. An amazing amount of organization come from simply sorting each bit of functionality into the proper box. * Switch to wxConfigBase from wxConfig everywhere except instantiation. * Add classes KIWAY, KIFACE, KIFACE_I, SEARCH_STACK, PGM_BASE, PGM_KICAD, PGM_SINGLE_TOP, * Remove "Return" prefix on many function names. * Remove obvious comments from CMakeLists.txt files, and from else() and endif()s. * Fix building boost for use in a DSO on linux. * Remove some of the assumptions in the CMakeLists.txt files that windows had to be the host platform when building windows binaries. * Reduce the number of wxStrings being constructed at program load time via static construction. * Pass wxConfigBase* to all SaveSettings() and LoadSettings() functions so that these functions are useful even when the wxConfigBase comes from another source, as is the case in the KICAD_MANAGER_FRAME. * Move the setting of the KIPRJMOD environment variable into class PROJECT, so that it can be moved into a project variable soon, and out of FP_LIB_TABLE. * Add the KIWAY_PLAYER which is associated with a particular PROJECT, and all its child wxFrames and wxDialogs now have a Kiway() member function which returns a KIWAY& that that window tree branch is in support of. This is like wxWindows DNA in that child windows get this member with proper value at time of construction. * Anticipate some of the needs for milestones B) and C) and make code adjustments now in an effort to reduce work in those milestones. * No testing has been done for python scripting, since milestone C) has that being largely reworked and re-thought-out.
12 years ago
* KIWAY Milestone A): Make major modules into DLL/DSOs. ! The initial testing of this commit should be done using a Debug build so that all the wxASSERT()s are enabled. Also, be sure and keep enabled the USE_KIWAY_DLLs option. The tree won't likely build without it. Turning it off is senseless anyways. If you want stable code, go back to a prior version, the one tagged with "stable". * Relocate all functionality out of the wxApp derivative into more finely targeted purposes: a) DLL/DSO specific b) PROJECT specific c) EXE or process specific d) configuration file specific data e) configuration file manipulations functions. All of this functionality was blended into an extremely large wxApp derivative and that was incompatible with the desire to support multiple concurrently loaded DLL/DSO's ("KIFACE")s and multiple concurrently open projects. An amazing amount of organization come from simply sorting each bit of functionality into the proper box. * Switch to wxConfigBase from wxConfig everywhere except instantiation. * Add classes KIWAY, KIFACE, KIFACE_I, SEARCH_STACK, PGM_BASE, PGM_KICAD, PGM_SINGLE_TOP, * Remove "Return" prefix on many function names. * Remove obvious comments from CMakeLists.txt files, and from else() and endif()s. * Fix building boost for use in a DSO on linux. * Remove some of the assumptions in the CMakeLists.txt files that windows had to be the host platform when building windows binaries. * Reduce the number of wxStrings being constructed at program load time via static construction. * Pass wxConfigBase* to all SaveSettings() and LoadSettings() functions so that these functions are useful even when the wxConfigBase comes from another source, as is the case in the KICAD_MANAGER_FRAME. * Move the setting of the KIPRJMOD environment variable into class PROJECT, so that it can be moved into a project variable soon, and out of FP_LIB_TABLE. * Add the KIWAY_PLAYER which is associated with a particular PROJECT, and all its child wxFrames and wxDialogs now have a Kiway() member function which returns a KIWAY& that that window tree branch is in support of. This is like wxWindows DNA in that child windows get this member with proper value at time of construction. * Anticipate some of the needs for milestones B) and C) and make code adjustments now in an effort to reduce work in those milestones. * No testing has been done for python scripting, since milestone C) has that being largely reworked and re-thought-out.
12 years ago
* KIWAY Milestone A): Make major modules into DLL/DSOs. ! The initial testing of this commit should be done using a Debug build so that all the wxASSERT()s are enabled. Also, be sure and keep enabled the USE_KIWAY_DLLs option. The tree won't likely build without it. Turning it off is senseless anyways. If you want stable code, go back to a prior version, the one tagged with "stable". * Relocate all functionality out of the wxApp derivative into more finely targeted purposes: a) DLL/DSO specific b) PROJECT specific c) EXE or process specific d) configuration file specific data e) configuration file manipulations functions. All of this functionality was blended into an extremely large wxApp derivative and that was incompatible with the desire to support multiple concurrently loaded DLL/DSO's ("KIFACE")s and multiple concurrently open projects. An amazing amount of organization come from simply sorting each bit of functionality into the proper box. * Switch to wxConfigBase from wxConfig everywhere except instantiation. * Add classes KIWAY, KIFACE, KIFACE_I, SEARCH_STACK, PGM_BASE, PGM_KICAD, PGM_SINGLE_TOP, * Remove "Return" prefix on many function names. * Remove obvious comments from CMakeLists.txt files, and from else() and endif()s. * Fix building boost for use in a DSO on linux. * Remove some of the assumptions in the CMakeLists.txt files that windows had to be the host platform when building windows binaries. * Reduce the number of wxStrings being constructed at program load time via static construction. * Pass wxConfigBase* to all SaveSettings() and LoadSettings() functions so that these functions are useful even when the wxConfigBase comes from another source, as is the case in the KICAD_MANAGER_FRAME. * Move the setting of the KIPRJMOD environment variable into class PROJECT, so that it can be moved into a project variable soon, and out of FP_LIB_TABLE. * Add the KIWAY_PLAYER which is associated with a particular PROJECT, and all its child wxFrames and wxDialogs now have a Kiway() member function which returns a KIWAY& that that window tree branch is in support of. This is like wxWindows DNA in that child windows get this member with proper value at time of construction. * Anticipate some of the needs for milestones B) and C) and make code adjustments now in an effort to reduce work in those milestones. * No testing has been done for python scripting, since milestone C) has that being largely reworked and re-thought-out.
12 years ago
* KIWAY Milestone A): Make major modules into DLL/DSOs. ! The initial testing of this commit should be done using a Debug build so that all the wxASSERT()s are enabled. Also, be sure and keep enabled the USE_KIWAY_DLLs option. The tree won't likely build without it. Turning it off is senseless anyways. If you want stable code, go back to a prior version, the one tagged with "stable". * Relocate all functionality out of the wxApp derivative into more finely targeted purposes: a) DLL/DSO specific b) PROJECT specific c) EXE or process specific d) configuration file specific data e) configuration file manipulations functions. All of this functionality was blended into an extremely large wxApp derivative and that was incompatible with the desire to support multiple concurrently loaded DLL/DSO's ("KIFACE")s and multiple concurrently open projects. An amazing amount of organization come from simply sorting each bit of functionality into the proper box. * Switch to wxConfigBase from wxConfig everywhere except instantiation. * Add classes KIWAY, KIFACE, KIFACE_I, SEARCH_STACK, PGM_BASE, PGM_KICAD, PGM_SINGLE_TOP, * Remove "Return" prefix on many function names. * Remove obvious comments from CMakeLists.txt files, and from else() and endif()s. * Fix building boost for use in a DSO on linux. * Remove some of the assumptions in the CMakeLists.txt files that windows had to be the host platform when building windows binaries. * Reduce the number of wxStrings being constructed at program load time via static construction. * Pass wxConfigBase* to all SaveSettings() and LoadSettings() functions so that these functions are useful even when the wxConfigBase comes from another source, as is the case in the KICAD_MANAGER_FRAME. * Move the setting of the KIPRJMOD environment variable into class PROJECT, so that it can be moved into a project variable soon, and out of FP_LIB_TABLE. * Add the KIWAY_PLAYER which is associated with a particular PROJECT, and all its child wxFrames and wxDialogs now have a Kiway() member function which returns a KIWAY& that that window tree branch is in support of. This is like wxWindows DNA in that child windows get this member with proper value at time of construction. * Anticipate some of the needs for milestones B) and C) and make code adjustments now in an effort to reduce work in those milestones. * No testing has been done for python scripting, since milestone C) has that being largely reworked and re-thought-out.
12 years ago
  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 <dick@softplc.com>
  5. * Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
  6. * Copyright (C) 2012-2015 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. #ifndef FP_LIB_TABLE_H_
  26. #define FP_LIB_TABLE_H_
  27. #include <macros.h>
  28. #include <vector>
  29. #include <map>
  30. #include <io_mgr.h>
  31. #include <project.h>
  32. #include <boost/interprocess/exceptions.hpp>
  33. #define FP_LATE_ENVVAR 1 ///< late=1/early=0 environment variable expansion
  34. class wxFileName;
  35. class OUTPUTFORMATTER;
  36. class MODULE;
  37. class FP_LIB_TABLE_LEXER;
  38. class FPID;
  39. /**
  40. * Class FP_LIB_TABLE
  41. * holds FP_LIB_TABLE::ROW records (rows), and can be searched based on library nickName.
  42. * <p>
  43. * This class owns the <b>footprint library table</b>, which is like fstab in concept and maps
  44. * logical library name to the library URI, type, and options. It is heavily based on the SWEET
  45. * parser work done by Dick Hollenbeck and can be seen in new/sch_lib_table.h. A footprint
  46. * library table had the following columns:
  47. * <ul>
  48. * <li> Logical Library Name (Nickname)
  49. * <li> Library Type, used to determine which plugin to load to access the library.
  50. * <li> Library URI. The full URI to the library source, form dependent on Type.
  51. * <li> Options, used for as yet to be defined information such as user names or passwords
  52. * </ul>
  53. * <p>
  54. * The Library Type can be one of:
  55. * <ul>
  56. * <li> "file"
  57. * <li> "ftp"
  58. * <li> "http"
  59. * </ul>
  60. * <p>
  61. * For now, the Library URI types needed to support the various types can be one of those
  62. * shown below, which are typical of each type:
  63. * <ul>
  64. * <li> "file://C:/mylibdir"
  65. * <li> "ftp://kicad.org/partlib/trunk"
  66. * <li> "http://kicad.org/partlib"
  67. * </ul>
  68. * <p>
  69. * The footprint library table is built up from several additive entries (table fragments),
  70. * and the final table is a (conceptual) merging of the table fragments. Two
  71. * anticipated sources of the entries are a personal table saved in the KiCad configuration
  72. * and a project resident table that resides in project file. The project footprint table
  73. * entries are considered a higher priority in the final dynamically assembled library table.
  74. * An row in the project file contribution to the library table takes precedence over the
  75. * personal table if there is a collision of logical library names. Otherwise, the entries
  76. * simply combine without issue to make up the applicable library table.
  77. *
  78. * @author Wayne Stambaugh
  79. */
  80. class FP_LIB_TABLE : public PROJECT::_ELEM
  81. {
  82. friend class DIALOG_FP_LIB_TABLE;
  83. public:
  84. /**
  85. * Class ROW
  86. * holds a record identifying a footprint library accessed by the appropriate #PLUGIN
  87. * object in the #FP_LIB_TABLE.
  88. */
  89. class ROW
  90. {
  91. friend class FP_LIB_TABLE;
  92. friend class DIALOG_FP_LIB_TABLE;
  93. public:
  94. typedef IO_MGR::PCB_FILE_T LIB_T;
  95. ROW() :
  96. type( IO_MGR::KICAD ),
  97. properties( 0 )
  98. {
  99. }
  100. ROW( const wxString& aNick, const wxString& aURI, const wxString& aType,
  101. const wxString& aOptions, const wxString& aDescr = wxEmptyString ) :
  102. nickName( aNick ),
  103. description( aDescr ),
  104. properties( 0 )
  105. {
  106. SetOptions( aOptions ),
  107. SetFullURI( aURI );
  108. SetType( aType );
  109. }
  110. ROW( const ROW& a );
  111. ~ROW()
  112. {
  113. delete properties;
  114. }
  115. ROW& operator=( const ROW& r );
  116. /// Used in DIALOG_FP_LIB_TABLE for detecting an edit.
  117. bool operator==( const ROW& r ) const;
  118. bool operator!=( const ROW& r ) const { return !( *this == r ); }
  119. //-----<accessors>------------------------------------------------------
  120. /**
  121. * Function GetNickName
  122. * returns the short name of this library table row.
  123. */
  124. const wxString& GetNickName() const { return nickName; }
  125. /**
  126. * Function SetNickName
  127. * changes the logical name of this library, useful for an editor.
  128. */
  129. void SetNickName( const wxString& aNickName ) { nickName = aNickName; }
  130. /**
  131. * Function GetType
  132. * returns the type of LIB represented by this row.
  133. */
  134. const wxString GetType() const { return IO_MGR::ShowType( type ); }
  135. /**
  136. * Function SetType
  137. * changes the type represented by this row.
  138. */
  139. void SetType( const wxString& aType );
  140. /**
  141. * Function GetFullURI
  142. * returns the full location specifying URI for the LIB, either in original
  143. * UI form or in environment variable expanded form.
  144. *
  145. * @param aSubstituted Tells if caller wanted the substituted form, else not.
  146. */
  147. const wxString GetFullURI( bool aSubstituted = false ) const;
  148. /**
  149. * Function SetFullURI
  150. * changes the full URI for the library.
  151. */
  152. void SetFullURI( const wxString& aFullURI );
  153. /**
  154. * Function GetOptions
  155. * returns the options string, which may hold a password or anything else needed to
  156. * instantiate the underlying LIB_SOURCE.
  157. */
  158. const wxString& GetOptions() const { return options; }
  159. /**
  160. * Function SetOptions
  161. */
  162. void SetOptions( const wxString& aOptions )
  163. {
  164. options = aOptions;
  165. // set PROPERTIES* from options
  166. setProperties( ParseOptions( TO_UTF8( aOptions ) ) );
  167. }
  168. /**
  169. * Function GetDescr
  170. * returns the description of the library referenced by this row.
  171. */
  172. const wxString& GetDescr() const { return description; }
  173. /**
  174. * Function SetDescr
  175. * changes the description of the library referenced by this row.
  176. */
  177. void SetDescr( const wxString& aDescr ) { description = aDescr; }
  178. /**
  179. * Function GetProperties
  180. * returns the constant PROPERTIES for this library (ROW). These are
  181. * the "options" in a table.
  182. */
  183. const PROPERTIES* GetProperties() const { return properties; }
  184. //-----</accessors>-----------------------------------------------------
  185. /**
  186. * Function Format
  187. * serializes this object as utf8 text to an OUTPUTFORMATTER, and tries to
  188. * make it look good using multiple lines and indentation.
  189. * @param out is an #OUTPUTFORMATTER
  190. * @param nestLevel is the indentation level to base all lines of the output.
  191. * Actual indentation will be 2 spaces for each nestLevel.
  192. */
  193. void Format( OUTPUTFORMATTER* out, int nestLevel ) const
  194. throw( IO_ERROR, boost::interprocess::lock_exception );
  195. private:
  196. /**
  197. * Function setProperties
  198. * sets this ROW's PROPERTIES by taking ownership of @a aProperties.
  199. * @param aProperties ownership is given over to this ROW.
  200. */
  201. void setProperties( const PROPERTIES* aProperties )
  202. {
  203. delete properties;
  204. properties = aProperties;
  205. }
  206. void setPlugin( PLUGIN* aPlugin )
  207. {
  208. plugin.set( aPlugin );
  209. }
  210. wxString nickName;
  211. wxString uri_user; ///< what user entered from UI or loaded from disk
  212. #if !FP_LATE_ENVVAR
  213. wxString uri_expanded; ///< from ExpandSubstitutions()
  214. #endif
  215. LIB_T type;
  216. wxString options;
  217. wxString description;
  218. const PROPERTIES* properties;
  219. PLUGIN::RELEASER plugin;
  220. };
  221. /**
  222. * Constructor FP_LIB_TABLE
  223. * builds a library table by pre-pending this table fragment in front of
  224. * @a aFallBackTable. Loading of this table fragment is done by using Parse().
  225. *
  226. * @param aFallBackTable is another FP_LIB_TABLE which is searched only when
  227. * a row is not found in this table. No ownership is
  228. * taken of aFallBackTable.
  229. */
  230. FP_LIB_TABLE( FP_LIB_TABLE* aFallBackTable = NULL );
  231. ~FP_LIB_TABLE();
  232. /// Delete all rows.
  233. void Clear()
  234. {
  235. rows.clear();
  236. nickIndex.clear();
  237. }
  238. bool operator==( const FP_LIB_TABLE& r ) const
  239. {
  240. if( rows.size() == r.rows.size() )
  241. {
  242. unsigned i;
  243. for( i = 0; i < rows.size() && rows[i] == r.rows[i]; ++i )
  244. ;
  245. if( i == rows.size() )
  246. return true;
  247. }
  248. return false;
  249. }
  250. bool operator!=( const FP_LIB_TABLE& r ) const { return !( *this == r ); }
  251. int GetCount() { return rows.size(); }
  252. ROW& At( int aIndex ) { return rows[aIndex]; }
  253. /**
  254. * Function Parse
  255. * fills this table fragment from information in the input stream \a aParser, which
  256. * is a DSNLEXER customized for the grammar needed to describe instances of this object.
  257. * The entire textual element spec is <br>
  258. *
  259. * <pre>
  260. * (fp_lib_table
  261. * (lib (name LOGICAL)(descr DESCRIPTION)(uri FULL_URI)(type TYPE)(options OPTIONS))
  262. * (lib (name LOGICAL)(descr DESCRIPTION)(uri FULL_URI)(type TYPE)(options OPTIONS))
  263. * (lib (name LOGICAL)(descr DESCRIPTION)(uri FULL_URI)(type TYPE)(options OPTIONS))
  264. * )
  265. * </pre>
  266. *
  267. * When this function is called, the input token stream given by \a aParser
  268. * is assumed to be positioned at the '^' in the following example, i.e. just
  269. * after the identifying keyword and before the content specifying stuff.
  270. * <br>
  271. * (lib_table ^ (....) )
  272. *
  273. * @param aParser is the input token stream of keywords and symbols.
  274. */
  275. void Parse( FP_LIB_TABLE_LEXER* aParser ) throw( IO_ERROR, PARSE_ERROR );
  276. /**
  277. * Function ParseOptions
  278. * parses @a aOptionsList and places the result into a PROPERTIES object
  279. * which is returned. If the options field is empty, then the returned PROPERTIES
  280. * will be a NULL pointer.
  281. * <p>
  282. * Typically aOptionsList comes from the "options" field within a ROW and
  283. * the format is simply a comma separated list of name value pairs. e.g.:
  284. * [name1[=value1][|name2[=value2]]] etc. When using the UI to create or edit
  285. * a fp lib table, this formatting is handled for you.
  286. */
  287. static PROPERTIES* ParseOptions( const std::string& aOptionsList );
  288. /**
  289. * Function FormatOptions
  290. * returns a list of options from the aProperties parameter. The name=value
  291. * pairs will be separted with the '|' character. The =value portion may not
  292. * be present. You might expect something like "name1=value1|name2=value2|flag_me".
  293. * Notice that flag_me does not have a value. This is ok.
  294. *
  295. * @param aProperties is the PROPERTIES to format or NULL. If NULL the returned
  296. * string will be empty.
  297. */
  298. static UTF8 FormatOptions( const PROPERTIES* aProperties );
  299. /**
  300. * Function Format
  301. * serializes this object as utf8 text to an #OUTPUTFORMATTER, and tries to
  302. * make it look good using multiple lines and indentation.
  303. *
  304. * @param out is an #OUTPUTFORMATTER
  305. * @param nestLevel is the indentation level to base all lines of the output.
  306. * Actual indentation will be 2 spaces for each nestLevel.
  307. */
  308. void Format( OUTPUTFORMATTER* out, int nestLevel ) const
  309. throw( IO_ERROR, boost::interprocess::lock_exception );
  310. /**
  311. * Function GetLogicalLibs
  312. * returns the logical library names, all of them that are pertinent to
  313. * a lookup done on this FP_LIB_TABLE.
  314. */
  315. std::vector<wxString> GetLogicalLibs();
  316. //-----<PLUGIN API SUBSET, REBASED ON aNickname>---------------------------
  317. /**
  318. * Function FootprintEnumerate
  319. * returns a list of footprint names contained within the library given by
  320. * @a aNickname.
  321. *
  322. * @param aNickname is a locator for the "library", it is a "name"
  323. * in FP_LIB_TABLE::ROW
  324. *
  325. * @return wxArrayString - is the array of available footprint names inside
  326. * a library
  327. *
  328. * @throw IO_ERROR if the library cannot be found, or footprint cannot be loaded.
  329. */
  330. wxArrayString FootprintEnumerate( const wxString& aNickname );
  331. /**
  332. * Function FootprintLoad
  333. * loads a footprint having @a aFootprintName from the library given by @a aNickname.
  334. *
  335. * @param aNickname is a locator for the "library", it is a "name"
  336. * in FP_LIB_TABLE::ROW
  337. *
  338. * @param aFootprintName is the name of the footprint to load.
  339. *
  340. * @return MODULE* - if found caller owns it, else NULL if not found.
  341. *
  342. * @throw IO_ERROR if the library cannot be found or read. No exception
  343. * is thrown in the case where aFootprintName cannot be found.
  344. */
  345. MODULE* FootprintLoad( const wxString& aNickname, const wxString& aFootprintName );
  346. /**
  347. * Enum SAVE_T
  348. * is the set of return values from FootprintSave() below.
  349. */
  350. enum SAVE_T
  351. {
  352. SAVE_OK,
  353. SAVE_SKIPPED,
  354. };
  355. /**
  356. * Function FootprintSave
  357. * will write @a aFootprint to an existing library given by @a aNickname.
  358. * If a footprint by the same name already exists, it is replaced.
  359. *
  360. * @param aNickname is a locator for the "library", it is a "name"
  361. * in FP_LIB_TABLE::ROW
  362. *
  363. * @param aFootprint is what to store in the library. The caller continues
  364. * to own the footprint after this call.
  365. *
  366. * @param aOverwrite when true means overwrite any existing footprint by the
  367. * same name, else if false means skip the write and return SAVE_SKIPPED.
  368. *
  369. * @return SAVE_T - SAVE_OK or SAVE_SKIPPED. If error saving, then IO_ERROR is thrown.
  370. *
  371. * @throw IO_ERROR if there is a problem saving.
  372. */
  373. SAVE_T FootprintSave( const wxString& aNickname, const MODULE* aFootprint, bool aOverwrite = true );
  374. /**
  375. * Function FootprintDelete
  376. * deletes the @a aFootprintName from the library given by @a aNickname.
  377. *
  378. * @param aNickname is a locator for the "library", it is a "name"
  379. * in FP_LIB_TABLE::ROW
  380. *
  381. * @param aFootprintName is the name of a footprint to delete from the specified library.
  382. *
  383. * @throw IO_ERROR if there is a problem finding the footprint or the library, or deleting it.
  384. */
  385. void FootprintDelete( const wxString& aNickname, const wxString& aFootprintName );
  386. /**
  387. * Function IsFootprintLibWritable
  388. * returns true iff the library given by @a aNickname is writable. (Often
  389. * system libraries are read only because of where they are installed.)
  390. *
  391. * @throw IO_ERROR if no library at aLibraryPath exists.
  392. */
  393. bool IsFootprintLibWritable( const wxString& aNickname );
  394. void FootprintLibDelete( const wxString& aNickname );
  395. void FootprintLibCreate( const wxString& aNickname );
  396. //-----</PLUGIN API SUBSET, REBASED ON aNickname>---------------------------
  397. /**
  398. * Function FootprintLoadWithOptionalNickname
  399. * loads a footprint having @a aFootprintId with possibly an empty nickname.
  400. *
  401. * @param aFootprintId the [nickname] & fooprint name of the footprint to load.
  402. *
  403. * @return MODULE* - if found caller owns it, else NULL if not found.
  404. *
  405. * @throw IO_ERROR if the library cannot be found or read. No exception
  406. * is thrown in the case where aFootprintName cannot be found.
  407. * @throw PARSE_ERROR if @a aFootprintId is not parsed OK.
  408. */
  409. MODULE* FootprintLoadWithOptionalNickname( const FPID& aFootprintId )
  410. throw( IO_ERROR, PARSE_ERROR, boost::interprocess::lock_exception );
  411. /**
  412. * Function GetDescription
  413. * returns the library desicription from @a aNickname, or an empty string
  414. * if aNickname does not exist.
  415. */
  416. const wxString GetDescription( const wxString& aNickname );
  417. /**
  418. * Function InsertRow
  419. * adds aRow if it does not already exist or if doReplace is true. If doReplace
  420. * is not true and the key for aRow already exists, the function fails and returns false.
  421. * The key for the table is the nickName, and all in this table must be unique.
  422. * @param aRow is the new row to insert, or to forcibly add if doReplace is true.
  423. * @param doReplace if true, means insert regardless of whether aRow's key already
  424. * exists. If false, then fail if the key already exists.
  425. * @return bool - true if the operation succeeded.
  426. */
  427. bool InsertRow( const ROW& aRow, bool doReplace = false );
  428. /**
  429. * Function FindRow
  430. * returns a ROW if aNickName is found in this table or in any chained
  431. * fallBack table fragment. The PLUGIN is loaded and attached
  432. * to the "plugin" field of the ROW if not already loaded.
  433. *
  434. * @throw IO_ERROR if aNickName cannot be found.
  435. */
  436. const ROW* FindRow( const wxString& aNickName ) throw( IO_ERROR );
  437. /**
  438. * Function FindRowByURI
  439. * returns a #FP_LIB_TABLE::ROW if aURE is found in this table or in any chained
  440. * fallBack table fragments, else NULL.
  441. */
  442. const ROW* FindRowByURI( const wxString& aURI );
  443. /**
  444. * Function IsEmpty
  445. * @param aIncludeFallback is used to determine if the fallback table should be
  446. * included in the test.
  447. * @return true if the footprint library table is empty.
  448. */
  449. bool IsEmpty( bool aIncludeFallback = true );
  450. /**
  451. * Function ExpandSubstitutions
  452. * replaces any environment variable references with their values and is
  453. * here to fully embellish the ROW::uri in a platform independent way.
  454. * This enables (fp_lib_table)s to have platform dependent environment
  455. * variables in them, allowing for a uniform table across platforms.
  456. */
  457. static const wxString ExpandSubstitutions( const wxString& aString );
  458. /**
  459. * Function LoadGlobalTable
  460. * loads the global footprint library table into \a aTable.
  461. *
  462. * This probably should be move into the application object when KiCad is changed
  463. * to a single process application. This is the least painful solution for the
  464. * time being.
  465. *
  466. * @param aTable the #FP_LIB_TABLE object to load.
  467. * @return true if the global library table exists and is loaded properly.
  468. * @throw IO_ERROR if an error occurs attempting to load the footprint library
  469. * table.
  470. */
  471. static bool LoadGlobalTable( FP_LIB_TABLE& aTable )
  472. throw (IO_ERROR, PARSE_ERROR, boost::interprocess::lock_exception );
  473. /**
  474. * Function GetGlobalTableFileName
  475. * @return the platform specific global footprint library path and file name.
  476. */
  477. static wxString GetGlobalTableFileName();
  478. #if 0
  479. /**
  480. * Function GetFileName
  481. * @return the footprint library file name.
  482. */
  483. static const wxString GetFileName();
  484. #endif
  485. /**
  486. * Function GlobalPathEnvVarVariableName
  487. * returns the name of the environment variable used to hold the directory of
  488. * locally installed "KiCad sponsored" system footprint libraries. These can
  489. * be either legacy or pretty format. The only thing special about this
  490. * particular environment variable is that it is set automatically by
  491. * KiCad on program startup, <b>iff</b> it is not set already in the environment.
  492. */
  493. static const wxString GlobalPathEnvVariableName();
  494. /**
  495. * Function Load
  496. * loads the footprint library table using the path defined in \a aFileName with
  497. * \a aFallBackTable.
  498. *
  499. * @param aFileName contains the full path to the s-expression file.
  500. *
  501. * @throw IO_ERROR if an error occurs attempting to load the footprint library
  502. * table.
  503. */
  504. void Load( const wxString& aFileName ) throw( IO_ERROR );
  505. /**
  506. * Function Save
  507. * writes this table to aFileName in s-expression form.
  508. * @param aFileName is the name of the file to write to.
  509. */
  510. void Save( const wxString& aFileName ) const
  511. throw( IO_ERROR, boost::interprocess::lock_exception );
  512. protected:
  513. /**
  514. * Function findRow
  515. * returns a ROW if aNickname is found in this table or in any chained
  516. * fallBack table fragment, else NULL.
  517. */
  518. ROW* findRow( const wxString& aNickname ) const;
  519. void reindex()
  520. {
  521. nickIndex.clear();
  522. for( ROWS_CITER it = rows.begin(); it != rows.end(); ++it )
  523. nickIndex.insert( INDEX_VALUE( it->nickName, it - rows.begin() ) );
  524. }
  525. void ensureIndex()
  526. {
  527. // The dialog lib table editor may not maintain the nickIndex.
  528. // Lazy indexing may be required. To handle lazy indexing, we must enforce
  529. // that "nickIndex" is either empty or accurate, but never inaccurate.
  530. if( !nickIndex.size() )
  531. reindex();
  532. }
  533. typedef std::vector<ROW> ROWS;
  534. typedef ROWS::iterator ROWS_ITER;
  535. typedef ROWS::const_iterator ROWS_CITER;
  536. ROWS rows;
  537. /// this is a non-owning index into the ROWS table
  538. typedef std::map<wxString,int> INDEX; // "int" is std::vector array index
  539. typedef INDEX::iterator INDEX_ITER;
  540. typedef INDEX::const_iterator INDEX_CITER;
  541. typedef INDEX::value_type INDEX_VALUE;
  542. /// this particular key is the nickName within each row.
  543. INDEX nickIndex;
  544. FP_LIB_TABLE* fallBack;
  545. };
  546. extern FP_LIB_TABLE GFootprintTable; // KIFACE scope.
  547. #endif // FP_LIB_TABLE_H_