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.

519 lines
16 KiB

8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
16 years ago
8 years ago
16 years ago
8 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
  5. * Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
  6. * Copyright (C) 2004-2017 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. * @file class_library.h
  27. * @brief Definition for part library class.
  28. */
  29. #ifndef CLASS_LIBRARY_H
  30. #define CLASS_LIBRARY_H
  31. #include <wx/filename.h>
  32. #include <class_libentry.h>
  33. #include <sch_io_mgr.h>
  34. #include <project.h>
  35. #include <map>
  36. class LIB_ID;
  37. class LINE_READER;
  38. class OUTPUTFORMATTER;
  39. class SCH_LEGACY_PLUGIN;
  40. class SCH_PLUGIN;
  41. #define DOC_EXT "dcm"
  42. /*
  43. * Part Library version and file header macros.
  44. */
  45. #define LIB_VERSION_MAJOR 2
  46. #define LIB_VERSION_MINOR 4
  47. /* Must be the first line of part library (.lib) files. */
  48. #define LIBFILE_IDENT "EESchema-LIBRARY Version"
  49. #define LIB_VERSION( major, minor ) ( major * 100 + minor )
  50. #define IS_LIB_CURRENT_VERSION( major, minor ) \
  51. ( \
  52. LIB_VERSION( major1, minor1 ) == \
  53. LIB_VERSION( LIB_VERSION_MAJOR, LIB_VERSION_MINOR) \
  54. )
  55. /*
  56. * Library versions 2.4 and lower use the old separate library (.lib) and
  57. * document (.dcm) files. Part libraries after 2.4 merged the library
  58. * and document files into a single library file. This macro checks if the
  59. * library version supports the old format
  60. */
  61. #define USE_OLD_DOC_FILE_FORMAT( major, minor ) \
  62. ( LIB_VERSION( major, minor ) <= LIB_VERSION( 2, 4 ) )
  63. // Helper class to filter a list of libraries, and/or a list of PART_LIB
  64. // in dialogs
  65. class SCHLIB_FILTER
  66. {
  67. wxArrayString m_allowedLibs; ///< a list of lib names to list some libraries
  68. ///< if empty: no filter
  69. bool m_filterPowerParts; ///< true to filter (show only) power parts
  70. bool m_forceLoad; // When true, load a part lib from the lib
  71. // which is given in m_allowedLibs[0]
  72. public:
  73. SCHLIB_FILTER()
  74. {
  75. m_filterPowerParts = false;
  76. m_forceLoad = false;
  77. }
  78. /**
  79. * add a lib name to the allowed libraries
  80. */
  81. void AddLib( const wxString& aLibName )
  82. {
  83. m_allowedLibs.Add( aLibName );
  84. m_forceLoad = false;
  85. }
  86. /**
  87. * add a lib name to the allowed libraries
  88. */
  89. void LoadFrom( const wxString& aLibName )
  90. {
  91. m_allowedLibs.Clear();
  92. m_allowedLibs.Add( aLibName );
  93. m_forceLoad = true;
  94. }
  95. /**
  96. * Clear the allowed libraries list (allows all libs)
  97. */
  98. void ClearLibList()
  99. {
  100. m_allowedLibs.Clear();
  101. m_forceLoad = false;
  102. }
  103. /**
  104. * set the filtering of power parts
  105. */
  106. void FilterPowerParts( bool aFilterEnable )
  107. {
  108. m_filterPowerParts = aFilterEnable;
  109. }
  110. // Accessors
  111. /**
  112. * @return true if the filtering of power parts is on
  113. */
  114. bool GetFilterPowerParts() const { return m_filterPowerParts; }
  115. /**
  116. * @return am wxArrayString of the names of allowed libs
  117. */
  118. const wxArrayString& GetAllowedLibList() const { return m_allowedLibs; }
  119. /**
  120. * @return the name of the lib to use to load a part, or an a empty string
  121. * Useful to load (in lib editor or lib viewer) a part from a given library
  122. */
  123. const wxString& GetLibSource() const
  124. {
  125. static wxString dummy;
  126. if( m_forceLoad && m_allowedLibs.GetCount() > 0 )
  127. return m_allowedLibs[0];
  128. else
  129. return dummy;
  130. }
  131. };
  132. /* Helpers for creating a list of part libraries. */
  133. class PART_LIB;
  134. class wxRegEx;
  135. /**
  136. * LIB_ALIAS map sorting.
  137. */
  138. struct AliasMapSort
  139. {
  140. bool operator() ( const wxString& aItem1, const wxString& aItem2 ) const
  141. {
  142. return aItem1 < aItem2;
  143. }
  144. };
  145. /// Alias map used by part library object.
  146. typedef std::map< wxString, LIB_ALIAS*, AliasMapSort > LIB_ALIAS_MAP;
  147. typedef std::vector< LIB_ALIAS* > LIB_ALIASES;
  148. typedef boost::ptr_vector< PART_LIB > PART_LIBS_BASE;
  149. /**
  150. * A collection of #PART_LIB objects.
  151. *
  152. * It extends from PROJECT::_ELEM so it can be hung in the PROJECT. It does not use any
  153. * UI calls, but rather simply throws an IO_ERROR when there is a problem.
  154. */
  155. class PART_LIBS : public PART_LIBS_BASE, public PROJECT::_ELEM
  156. {
  157. public:
  158. KICAD_T Type() override { return PART_LIBS_T; }
  159. static int s_modify_generation; ///< helper for GetModifyHash()
  160. PART_LIBS()
  161. {
  162. ++s_modify_generation;
  163. }
  164. /// Return the modification hash for all libraries. The value returned
  165. /// changes on every library modification.
  166. int GetModifyHash();
  167. /**
  168. * Allocate and adds a part library to the library list.
  169. *
  170. * @param aFileName - File name object of part library.
  171. * @throw IO_ERROR if there's any problem loading.
  172. */
  173. PART_LIB* AddLibrary( const wxString& aFileName );
  174. /**
  175. * Insert a part library into the library list.
  176. *
  177. * @param aFileName - File name object of part library.
  178. * @param aIterator - Iterator to insert library in front of.
  179. * @return PART_LIB* - the new PART_LIB, which remains owned by this PART_LIBS container.
  180. * @throw IO_ERROR if there's any problem loading.
  181. */
  182. PART_LIB* AddLibrary( const wxString& aFileName, PART_LIBS::iterator& aIterator );
  183. /**
  184. * Load all of the project's libraries into this container, which should
  185. * be cleared before calling it.
  186. *
  187. * @note This method is only to be used when loading legacy projects. All further symbol
  188. * library access should be done via the symbol library table.
  189. */
  190. void LoadAllLibraries( PROJECT* aProject, bool aShowProgress=true );
  191. /**
  192. * Save or load the names of the currently configured part libraries (without paths).
  193. */
  194. static void LibNamesAndPaths( PROJECT* aProject, bool doSave,
  195. wxString* aPaths, wxArrayString* aNames=NULL );
  196. /**
  197. * Return the name of the cache library after potentially fixing it from
  198. * an older naming scheme. That is, the old file is renamed if needed.
  199. *
  200. * @param aFullProjectFilename - the *.pro filename with absolute path.
  201. */
  202. static const wxString CacheName( const wxString& aFullProjectFilename );
  203. /**
  204. * Find a part library by \a aName.
  205. *
  206. * @param aName - Library file name without path or extension to find.
  207. * @return Part library if found, otherwise NULL.
  208. */
  209. PART_LIB* FindLibrary( const wxString& aName );
  210. PART_LIB* FindLibraryByFullFileName( const wxString& aFullFileName );
  211. PART_LIB* GetCacheLibrary();
  212. /**
  213. * Return the list of part library file names without path and extension.
  214. *
  215. * @param aSorted - Sort the list of name if true. Otherwise use the library load order.
  216. * @return The list of library names.
  217. */
  218. wxArrayString GetLibraryNames( bool aSorted = true );
  219. /**
  220. * Search all libraries in the list for a part.
  221. *
  222. * A part object will always be returned. If the entry found
  223. * is an alias. The root part will be found and returned.
  224. *
  225. * @param aLibId - The #LIB_ID of the symbol to search for.
  226. * @param aLibraryName - Name of the library to search for part.
  227. * @return LIB_PART* - The part object if found, otherwise NULL.
  228. */
  229. LIB_PART* FindLibPart( const LIB_ID& aLibId, const wxString& aLibraryName = wxEmptyString );
  230. /**
  231. * Function FindLibraryEntry
  232. * searches all libraries in the list for an entry.
  233. *
  234. * The object can be either a part or an alias.
  235. *
  236. * @param aLibId - The library indentifaction of entry to search for (case sensitive).
  237. * @param aLibraryName - Name of the library to search.
  238. * @return The entry object if found, otherwise NULL.
  239. */
  240. LIB_ALIAS* FindLibraryAlias( const LIB_ID& aLibId,
  241. const wxString& aLibraryName = wxEmptyString );
  242. /**
  243. * Function FindLibraryNearEntries
  244. * Searches all libraries in the list for an entry, using a case insensitive comparison.
  245. * Helper function used in dialog to find all candidates.
  246. * During a long time, eeschema was using a case insensitive search.
  247. * Therefore, for old schematics (<= 2013), or libs, for some components,
  248. * the chip name (name of alias in lib) can be broken.
  249. * This function can be used to display a list of candidates, in component properties dialog.
  250. *
  251. * @param aEntryName - Name of entries to search for (case insensitive).
  252. * @param aLibraryName - Name of the library to search.
  253. * @param aCandidates - a std::vector to store candidates
  254. */
  255. void FindLibraryNearEntries( std::vector<LIB_ALIAS*>& aCandidates, const wxString& aEntryName,
  256. const wxString& aLibraryName = wxEmptyString );
  257. int GetLibraryCount() { return size(); }
  258. };
  259. /**
  260. * Object used to load, save, search, and otherwise manipulate symbol library files.
  261. */
  262. class PART_LIB
  263. {
  264. int type; ///< Library type indicator.
  265. wxFileName fileName; ///< Library file name.
  266. wxDateTime timeStamp; ///< Library save time and date.
  267. int versionMajor; ///< Library major version number.
  268. int versionMinor; ///< Library minor version number.
  269. wxString header; ///< first line of loaded library.
  270. bool isModified; ///< Library modification status.
  271. int m_mod_hash; ///< incremented each time library is changed.
  272. SCH_IO_MGR::SCH_FILE_T m_pluginType;
  273. std::unique_ptr< SCH_PLUGIN > m_plugin;
  274. std::unique_ptr< PROPERTIES > m_properties; ///< Library properties
  275. public:
  276. PART_LIB( int aType, const wxString& aFileName,
  277. SCH_IO_MGR::SCH_FILE_T aPluginType = SCH_IO_MGR::SCH_LEGACY );
  278. ~PART_LIB();
  279. /**
  280. * @return a magic number that changes if the library has changed
  281. */
  282. int GetModHash() const { return m_mod_hash; }
  283. SCH_IO_MGR::SCH_FILE_T GetPluginType() const { return m_pluginType; }
  284. void SetPluginType( SCH_IO_MGR::SCH_FILE_T aPluginType );
  285. void Create( const wxString& aFileName = wxEmptyString );
  286. void SetFileName( const wxString& aFileName ) { fileName = aFileName; }
  287. /**
  288. * Get library entry status.
  289. *
  290. * @return True if there are no entries in the library.
  291. */
  292. bool IsEmpty() const
  293. {
  294. return m_plugin->GetSymbolLibCount( fileName.GetFullPath() ) == 0;
  295. }
  296. /**
  297. * Return the number of entries in the library.
  298. *
  299. * @return The number of part and alias entries.
  300. */
  301. int GetCount() const
  302. {
  303. return (int) m_plugin->GetSymbolLibCount( fileName.GetFullPath() );
  304. }
  305. bool IsModified() const
  306. {
  307. return isModified;
  308. }
  309. bool IsCache() const;
  310. void SetCache();
  311. bool IsBuffering() const;
  312. void EnableBuffering( bool aEnable = true );
  313. void Save( bool aSaveDocFile = true );
  314. /**
  315. * @return true if current user does not have write access to the library file.
  316. */
  317. bool IsReadOnly() const { return !fileName.IsFileWritable(); }
  318. /**
  319. * Load a string array with the names of all the entries in this library.
  320. *
  321. * @param aNames - String array to place entry names into.
  322. */
  323. void GetAliasNames( wxArrayString& aNames ) const;
  324. /**
  325. * Load a vector with all the entries in this library.
  326. *
  327. * @param aAliases - vector to receive the aliases.
  328. */
  329. void GetAliases( std::vector<LIB_ALIAS*>& aAliases ) const;
  330. /**
  331. * Load a string array with the names of entries of type POWER in this library.
  332. *
  333. * @param aNames - String array to place entry names into.
  334. */
  335. void GetEntryTypePowerNames( wxArrayString& aNames ) const;
  336. /**
  337. * Find #LIB_ALIAS by \a aName.
  338. *
  339. * @param aName - Name of entry, case sensitive.
  340. * @return #LIB_ALIAS* if found. NULL if not found.
  341. */
  342. LIB_ALIAS* FindAlias( const wxString& aName ) const;
  343. LIB_ALIAS* FindAlias( const LIB_ID& aLibId ) const;
  344. /**
  345. * Find part by \a aName.
  346. *
  347. * This is a helper for FindEntry so casting a LIB_ALIAS pointer to
  348. * a LIB_PART pointer is not required.
  349. *
  350. * @param aName - Name of part, case sensitive.
  351. * @return LIB_PART* - part if found, else NULL.
  352. */
  353. LIB_PART* FindPart( const wxString& aName ) const;
  354. LIB_PART* FindPart( const LIB_ID& aLibId ) const;
  355. /**
  356. * Add \a aPart entry to library.
  357. *
  358. * @note A #LIB_PART can have an alias list so these alias will be added in library.
  359. * and the any existing duplicate aliases will be removed from the library.
  360. *
  361. * @param aPart - Part to add, caller retains ownership, a clone is added.
  362. */
  363. void AddPart( LIB_PART* aPart );
  364. /**
  365. * Safely remove \a aEntry from the library and return the next entry.
  366. *
  367. * The next entry returned depends on the entry being removed. If the entry being
  368. * remove also removes the part, then the next entry from the list is returned.
  369. * If the entry being used only removes an alias from a part, then the next alias
  370. * of the part is returned.
  371. *
  372. * @param aEntry - Entry to remove from library.
  373. * @return The next entry in the library or NULL if the library is empty.
  374. */
  375. LIB_ALIAS* RemoveAlias( LIB_ALIAS* aEntry );
  376. /**
  377. * Replace an existing part entry in the library.
  378. * Note a part can have an alias list,
  379. * so these alias will be added in library (and previously existing alias removed)
  380. * @param aOldPart - The part to replace.
  381. * @param aNewPart - The new part.
  382. */
  383. LIB_PART* ReplacePart( LIB_PART* aOldPart, LIB_PART* aNewPart );
  384. /**
  385. * Return the file name without path or extension.
  386. *
  387. * @return Name of library file.
  388. */
  389. const wxString GetName() const { return fileName.GetName(); }
  390. /**
  391. * Return the full file library name with path and extension.
  392. *
  393. * @return wxString - Full library file name with path and extension.
  394. */
  395. wxString GetFullFileName() const { return fileName.GetFullPath(); }
  396. /**
  397. * Return the logical name of the library.
  398. *
  399. * @return wxString - The logical name of this library.
  400. */
  401. const wxString GetLogicalName() const
  402. {
  403. /* for now is the filename without path or extension.
  404. Technically the library should not know its logical name!
  405. This will eventually come out of a pair of lookup tables using a
  406. reverse lookup using the full name or library pointer as a key.
  407. Search will be by project lookup table and then user lookup table if
  408. not found.
  409. */
  410. return fileName.GetName();
  411. }
  412. /**
  413. * Allocate and load a symbol library file.
  414. *
  415. * @param aFileName - File name of the part library to load.
  416. * @return PART_LIB* - the allocated and loaded PART_LIB, which is owned by the caller.
  417. * @throw IO_ERROR if there's any problem loading the library.
  418. */
  419. static PART_LIB* LoadLibrary( const wxString& aFileName );
  420. /**
  421. * @return true if at least one power part is found in lib
  422. * Useful to select or list only libs containing power parts
  423. */
  424. bool HasPowerParts() const;
  425. };
  426. /**
  427. * Case insensitive library name comparison.
  428. */
  429. bool operator==( const PART_LIB& aLibrary, const wxString& aName );
  430. bool operator!=( const PART_LIB& aLibrary, const wxString& aName );
  431. #endif // CLASS_LIBRARY_H