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.

685 lines
23 KiB

15 years ago
15 years ago
15 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
  5. * Copyright (C) 2008-2011 Wayne Stambaugh <stambaughw@verizon.net>
  6. * Copyright (C) 2004-2011 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_libentry.h
  27. */
  28. #ifndef CLASS_LIBENTRY_H
  29. #define CLASS_LIBENTRY_H
  30. #include <general.h>
  31. #include <lib_draw_item.h>
  32. #include <lib_field.h>
  33. #include <map>
  34. class LINE_READER;
  35. class OUTPUTFORMATTER;
  36. class CMP_LIBRARY;
  37. class LIB_ALIAS;
  38. class LIB_COMPONENT;
  39. class LIB_FIELD;
  40. /**
  41. * LIB_ALIAS map sorting.
  42. */
  43. struct AliasMapSort
  44. {
  45. bool operator() ( const wxString& aItem1, const wxString& aItem2 ) const
  46. { return aItem1.CmpNoCase( aItem2 ) < 0; }
  47. };
  48. /**
  49. * Alias map used by component library object.
  50. */
  51. typedef std::map< wxString, LIB_ALIAS*, AliasMapSort > LIB_ALIAS_MAP;
  52. typedef std::vector< LIB_ALIAS* > LIB_ALIASES;
  53. /* values for member .m_options */
  54. enum LibrEntryOptions
  55. {
  56. ENTRY_NORMAL, // Libentry is a standard component (real or alias)
  57. ENTRY_POWER // Libentry is a power symbol
  58. };
  59. /**
  60. * Component library alias object definition.
  61. *
  62. * Component aliases are not really components. An alias uses the component definition
  63. * (graphic, pins...) but has its own name, keywords and documentation. Therefore, when
  64. * the component is modified, alias of this component are modified. This is a simple
  65. * method to create components that have the same physical layout with different names
  66. * such as 74LS00, 74HC00 ... and many op amps.
  67. */
  68. class LIB_ALIAS : public EDA_ITEM
  69. {
  70. /**
  71. * The actual component of the alias.
  72. *
  73. * @note - Do not delete the root component. The root component is actually shared by
  74. * all of the aliases associated with it. The component pointer will be delete
  75. * in the destructor of the last alias that shares this component is deleted.
  76. * Deleting the root component will likely cause Eeschema to crash.
  77. */
  78. LIB_COMPONENT* root;
  79. friend class LIB_COMPONENT;
  80. protected:
  81. wxString name;
  82. wxString description; ///< documentation for info
  83. wxString keyWords; ///< keyword list (used for search for components by keyword)
  84. wxString docFileName; ///< Associate doc file name
  85. public:
  86. LIB_ALIAS( const wxString& aName, LIB_COMPONENT* aRootComponent );
  87. LIB_ALIAS( const LIB_ALIAS& aAlias, LIB_COMPONENT* aRootComponent = NULL );
  88. virtual ~LIB_ALIAS();
  89. virtual wxString GetClass() const
  90. {
  91. return wxT( "LIB_ALIAS" );
  92. }
  93. /**
  94. * Get the alias root component.
  95. */
  96. LIB_COMPONENT* GetComponent() const
  97. {
  98. return root;
  99. }
  100. virtual wxString GetLibraryName();
  101. bool IsRoot() const;
  102. CMP_LIBRARY* GetLibrary();
  103. virtual const wxString& GetName() const { return name; }
  104. virtual void SetName( const wxString& aName ) { name = aName; }
  105. void SetDescription( const wxString& aDescription )
  106. {
  107. description = aDescription;
  108. }
  109. wxString GetDescription() const { return description; }
  110. void SetKeyWords( const wxString& aKeyWords )
  111. {
  112. keyWords = aKeyWords;
  113. }
  114. wxString GetKeyWords() const { return keyWords; }
  115. void SetDocFileName( const wxString& aDocFileName )
  116. {
  117. docFileName = aDocFileName;
  118. }
  119. wxString GetDocFileName() const { return docFileName; }
  120. /**
  121. * Function SaveDocs
  122. * rrite the entry document information to \a aFormatter in "*.dcm" format.
  123. *
  124. * @param aFormatter The #OUTPUTFORMATTER to write the alias documents to.
  125. * @return True if success writing else false.
  126. */
  127. bool SaveDoc( OUTPUTFORMATTER& aFormatter );
  128. /**
  129. * Case insensitive comparison of the component entry name.
  130. */
  131. bool operator==( const wxChar* aName ) const;
  132. bool operator!=( const wxChar* aName ) const
  133. {
  134. return !( *this == aName );
  135. }
  136. bool operator==( const LIB_ALIAS* aAlias ) const { return this == aAlias; }
  137. #if defined(DEBUG)
  138. void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override
  139. #endif
  140. };
  141. extern bool operator<( const LIB_ALIAS& aItem1, const LIB_ALIAS& aItem2 );
  142. extern int LibraryEntryCompare( const LIB_ALIAS* aItem1, const LIB_ALIAS* aItem2 );
  143. /**
  144. * Class LIB_COMPONENT
  145. * defines a library component object.
  146. *
  147. * A library component object is typically saved and loaded in a component library file (.lib).
  148. * Library components are different from schematic components.
  149. */
  150. class LIB_COMPONENT : public EDA_ITEM
  151. {
  152. wxString m_name;
  153. int m_pinNameOffset; ///< The offset in mils to draw the pin name. Set to 0
  154. ///< to draw the pin name above the pin.
  155. bool m_unitsLocked; ///< True if component has multiple parts and changing
  156. ///< one part does not automatically change another part.
  157. bool m_showPinNames; ///< Determines if component pin names are visible.
  158. bool m_showPinNumbers; ///< Determines if component pin numbers are visible.
  159. long m_dateModified; ///< Date the component was last modified.
  160. LibrEntryOptions m_options; ///< Special component features such as POWER or NORMAL.)
  161. int m_unitCount; ///< Number of units (parts) per package.
  162. LIB_ITEMS drawings; ///< How to draw this part.
  163. wxArrayString m_FootprintList; /**< List of suitable footprint names for the
  164. component (wild card names accepted). */
  165. LIB_ALIASES m_aliases; ///< List of alias object pointers associated with the
  166. ///< component.
  167. CMP_LIBRARY* m_library; ///< Library the component belongs to if any.
  168. void deleteAllFields();
  169. friend class CMP_LIBRARY;
  170. friend class LIB_ALIAS;
  171. public:
  172. LIB_COMPONENT( const wxString& aName, CMP_LIBRARY* aLibrary = NULL );
  173. LIB_COMPONENT( LIB_COMPONENT& aComponent, CMP_LIBRARY* aLibrary = NULL );
  174. virtual ~LIB_COMPONENT();
  175. virtual wxString GetClass() const
  176. {
  177. return wxT( "LIB_COMPONENT" );
  178. }
  179. virtual void SetName( const wxString& aName );
  180. wxString GetName() { return m_name; }
  181. wxString GetLibraryName();
  182. CMP_LIBRARY* GetLibrary() { return m_library; }
  183. wxArrayString GetAliasNames( bool aIncludeRoot = true ) const;
  184. size_t GetAliasCount() const { return m_aliases.size(); }
  185. LIB_ALIAS* GetAlias( size_t aIndex );
  186. LIB_ALIAS* GetAlias( const wxString& aName );
  187. /**
  188. * Function AddAlias
  189. *
  190. * Add an alias \a aName to the component.
  191. *
  192. * Duplicate alias names are not added to the alias list. Debug builds will raise an
  193. * assertion. Release builds will fail silently.
  194. *
  195. * @param aName - Name of alias to add.
  196. */
  197. void AddAlias( const wxString& aName );
  198. /**
  199. * Test if alias \a aName is in component alias list.
  200. *
  201. * Alias name comparisons are case insensitive.
  202. *
  203. * @param aName - Name of alias.
  204. * @return True if alias name in alias list.
  205. */
  206. bool HasAlias( const wxString& aName ) const;
  207. void SetAliases( const wxArrayString& aAliasList );
  208. void RemoveAlias( const wxString& aName );
  209. LIB_ALIAS* RemoveAlias( LIB_ALIAS* aAlias );
  210. void RemoveAllAliases();
  211. wxArrayString& GetFootPrints() { return m_FootprintList; }
  212. /**
  213. * Function GetBoundingBox
  214. * @return the component boundary box ( in user coordinates )
  215. * @param aUnit = unit selection = 0, or 1..n
  216. * @param aConvert = 0, 1 or 2
  217. * If aUnit == 0, unit is not used
  218. * if aConvert == 0 Convert is non used
  219. * Invisible fields are not taken in account
  220. **/
  221. EDA_RECT GetBoundingBox( int aUnit, int aConvert ) const;
  222. /**
  223. * Function GetBodyBoundingBox
  224. * @return the component boundary box ( in user coordinates ) without fields
  225. * @param aUnit = unit selection = 0, or 1..n
  226. * @param aConvert = 0, 1 or 2
  227. * If aUnit == 0, unit is not used
  228. * if aConvert == 0 Convert is non used
  229. * Fields are not taken in account
  230. **/
  231. EDA_RECT GetBodyBoundingBox( int aUnit, int aConvert ) const;
  232. /**
  233. * Function SaveDateAndTime
  234. * write the date and time of component to \a aFile in the format:
  235. * "Ti yy/mm/jj hh:mm:ss"
  236. *
  237. * @param aFormatter A reference to an #OUTPUTFORMATTER object containing the
  238. * output format to write to.
  239. * @return True if the date and time were successfully written to \a aFormatter.
  240. */
  241. bool SaveDateAndTime( OUTPUTFORMATTER& aFormatter );
  242. bool LoadDateAndTime( char* aLine );
  243. /**
  244. * Function Save
  245. * writes the data structures out to \a aFormatter in the component library "*.lib"
  246. * format.
  247. *
  248. * @param aFormatter A reference to an OUTPUTFORMATTER to write to.
  249. * @return True if success writing else false.
  250. */
  251. bool Save( OUTPUTFORMATTER& aFormatter );
  252. /**
  253. * Load component definition from \a aReader.
  254. *
  255. * @param aReader A LINE_READER object to load file from.
  256. * @param aErrorMsg - Description of error on load failure.
  257. * @return True if the load was successful, false if there was an error.
  258. */
  259. bool Load( LINE_READER& aReader, wxString& aErrorMsg );
  260. bool LoadField( LINE_READER& aReader, wxString& aErrorMsg );
  261. bool LoadDrawEntries( LINE_READER& aReader, wxString& aErrorMsg );
  262. bool LoadAliases( char* aLine, wxString& aErrorMsg );
  263. bool LoadFootprints( LINE_READER& aReader, wxString& aErrorMsg );
  264. bool IsPower() { return m_options == ENTRY_POWER; }
  265. bool IsNormal() { return m_options == ENTRY_NORMAL; }
  266. void SetPower() { m_options = ENTRY_POWER; }
  267. void SetNormal() { m_options = ENTRY_NORMAL; }
  268. void LockUnits( bool aLockUnits ) { m_unitsLocked = aLockUnits; }
  269. bool UnitsLocked() { return m_unitsLocked; }
  270. /**
  271. * Function SetFields
  272. * overwrites all the existing in this component with fields supplied
  273. * in \a aFieldsList. The only known caller of this function is the
  274. * library component field editor, and it establishes needed behavior.
  275. *
  276. ` * @param aFieldsList is a set of fields to import, removing all previous fields.
  277. */
  278. void SetFields( const std::vector <LIB_FIELD>& aFieldsList );
  279. /**
  280. * Function GetFields
  281. * returns a list of fields withing this component. The only known caller of
  282. * this function is the library component field editor, and it establishes
  283. * needed behavior.
  284. *
  285. * @param aList - List to add fields to
  286. */
  287. void GetFields( LIB_FIELDS& aList );
  288. /**
  289. * Function FindField
  290. * finds a field within this component matching \a aFieldName and returns
  291. * it or NULL if not found.
  292. */
  293. LIB_FIELD* FindField( const wxString& aFieldName );
  294. /**
  295. * Return pointer to the requested field.
  296. *
  297. * @param aId - Id of field to return.
  298. * @return The field if found, otherwise NULL.
  299. */
  300. LIB_FIELD* GetField( int aId );
  301. /** Return reference to the value field. */
  302. LIB_FIELD& GetValueField();
  303. /** Return reference to the reference designator field. */
  304. LIB_FIELD& GetReferenceField();
  305. /**
  306. * Draw component.
  307. *
  308. * @param aPanel - Window to draw on.
  309. * @param aDc - Device context to draw on.
  310. * @param aOffset - Position to component.
  311. * @param aMulti - Component unit if multiple parts per component.
  312. * @param aConvert - Component conversion (DeMorgan) if available.
  313. * @param aDrawMode - Device context drawing mode, see wxDC.
  314. * @param aColor - Color to draw component.
  315. * @param aTransform - Coordinate adjustment settings.
  316. * @param aShowPinText - Show pin text if true.
  317. * @param aDrawFields - Draw field text if true otherwise just draw
  318. * body items (useful to draw a body in schematic,
  319. * because fields of schematic components replace
  320. * the lib component fields).
  321. * @param aOnlySelected - Draws only the body items that are selected.
  322. * Used for block move redraws.
  323. */
  324. void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDc, const wxPoint& aOffset,
  325. int aMulti, int aConvert, int aDrawMode, int aColor = -1,
  326. const TRANSFORM& aTransform = DefaultTransform,
  327. bool aShowPinText = true, bool aDrawFields = true,
  328. bool aOnlySelected = false );
  329. /**
  330. * Plot component to plotter.
  331. *
  332. * @param aPlotter - Plotter object to plot to.
  333. * @param aUnit - Component part to plot.
  334. * @param aConvert - Component alternate body style to plot.
  335. * @param aOffset - Distance to shift the plot coordinates.
  336. * @param aTransform - Component plot transform matrix.
  337. */
  338. void Plot( PLOTTER* aPlotter, int aUnit, int aConvert, const wxPoint& aOffset,
  339. const TRANSFORM& aTransform );
  340. /**
  341. * Add a new draw \a aItem to the draw object list.
  342. *
  343. * @param aItem - New draw object to add to component.
  344. */
  345. void AddDrawItem( LIB_ITEM* aItem );
  346. /**
  347. * Remove draw \a aItem from list.
  348. *
  349. * @param aItem - Draw item to remove from list.
  350. * @param aPanel - Panel to remove part from.
  351. * @param aDc - Device context to remove part from.
  352. */
  353. void RemoveDrawItem( LIB_ITEM* aItem, EDA_DRAW_PANEL* aPanel = NULL, wxDC* aDc = NULL );
  354. /**
  355. * Return the next draw object pointer.
  356. *
  357. * @param aItem - Pointer to the current draw item. Setting item NULL
  358. * with return the first item of type in the list.
  359. * @param aType - type of searched item (filter).
  360. * if TYPE_NOT_INIT search for all items types
  361. * @return - The next drawing object in the list if found, otherwise NULL.
  362. */
  363. LIB_ITEM* GetNextDrawItem( LIB_ITEM* aItem = NULL, KICAD_T aType = TYPE_NOT_INIT );
  364. /**
  365. * Return the next pin object from the draw list.
  366. *
  367. * This is just a pin object specific version of GetNextDrawItem().
  368. *
  369. * @param aItem - Pointer to the previous pin item, or NULL to get the
  370. * first pin in the draw object list.
  371. * @return - The next pin object in the list if found, otherwise NULL.
  372. */
  373. LIB_PIN* GetNextPin( LIB_PIN* aItem = NULL )
  374. {
  375. return (LIB_PIN*) GetNextDrawItem( (LIB_ITEM*) aItem, LIB_PIN_T );
  376. }
  377. /**
  378. * Return a list of pin object pointers from the draw item list.
  379. *
  380. * Note pin objects are owned by the draw list of the component.
  381. * Deleting any of the objects will leave list in a unstable state
  382. * and will likely segfault when the list is destroyed.
  383. *
  384. * @param aList - Pin list to place pin object pointers into.
  385. * @param aUnit - Unit number of pin to add to list. Set to 0 to
  386. * get pins from any component part.
  387. * @param aConvert - Convert number of pin to add to list. Set to 0 to
  388. * get pins from any convert of component.
  389. */
  390. void GetPins( LIB_PINS& aList, int aUnit = 0, int aConvert = 0 );
  391. /**
  392. * Return pin object with the requested pin \a aNumber.
  393. *
  394. * @param aNumber - Number of the pin to find.
  395. * @param aUnit - Unit of the component to find. Set to 0 if a specific
  396. * unit number is not required.
  397. * @param aConvert - Alternate body style filter (DeMorgan). Set to 0 if
  398. * no alternate body style is required.
  399. * @return The pin object if found. Otherwise NULL.
  400. */
  401. LIB_PIN* GetPin( const wxString& aNumber, int aUnit = 0, int aConvert = 0 );
  402. /**
  403. * Move the component \a aOffset.
  404. *
  405. * @param aOffset - Offset displacement.
  406. */
  407. void SetOffset( const wxPoint& aOffset );
  408. /**
  409. * Remove duplicate draw items from list.
  410. */
  411. void RemoveDuplicateDrawItems();
  412. /**
  413. * Test if component has more than one body conversion type (DeMorgan).
  414. *
  415. * @return True if component has more than one conversion.
  416. */
  417. bool HasConversion() const;
  418. /**
  419. * Clears the status flag all draw objects in this component.
  420. */
  421. void ClearStatus();
  422. /**
  423. * Checks all draw objects of component to see if they are with block.
  424. *
  425. * Use this method to mark draw objects as selected during block
  426. * functions.
  427. *
  428. * @param aRect - The bounding rectangle to test in draw items are inside.
  429. * @param aUnit - The current unit number to test against.
  430. * @param aConvert - Are the draw items being selected a conversion.
  431. * @param aEditPinByPin - Used to ignore pin selections when in edit pin
  432. * by pin mode is enabled.
  433. * @return The number of draw objects found inside the block select
  434. * rectangle.
  435. */
  436. int SelectItems( EDA_RECT& aRect, int aUnit, int aConvert, bool aEditPinByPin );
  437. /**
  438. * Clears all the draw items marked by a block select.
  439. */
  440. void ClearSelectedItems();
  441. /**
  442. * Deletes the select draw items marked by a block select.
  443. *
  444. * The name and reference field will not be deleted. They are the
  445. * minimum drawing items required for any component. Their properties
  446. * can be changed but the cannot be removed.
  447. */
  448. void DeleteSelectedItems();
  449. /**
  450. * Move the selected draw items marked by a block select.
  451. */
  452. void MoveSelectedItems( const wxPoint& aOffset );
  453. /**
  454. * Make a copy of the selected draw items marked by a block select.
  455. *
  456. * Fields are not copied. Only component body items are copied.
  457. * Copying fields would result in duplicate fields which does not
  458. * make sense in this context.
  459. */
  460. void CopySelectedItems( const wxPoint& aOffset );
  461. /**
  462. * Horizontally (X axis) mirror selected draw items about a point.
  463. *
  464. * @param aCenter - Center point to mirror around.
  465. */
  466. void MirrorSelectedItemsH( const wxPoint& aCenter );
  467. /**
  468. * Vertically (Y axis) mirror selected draw items about a point.
  469. *
  470. * @param aCenter - Center point to mirror around.
  471. */
  472. void MirrorSelectedItemsV( const wxPoint& aCenter );
  473. /**
  474. * Rotate CCW selected draw items about a point.
  475. *
  476. * @param aCenter - Center point to mirror around.
  477. */
  478. void RotateSelectedItems( const wxPoint& aCenter );
  479. /**
  480. * Locate a draw object.
  481. *
  482. * @param aUnit - Unit number of draw item.
  483. * @param aConvert - Body style of draw item.
  484. * @param aType - Draw object type, set to 0 to search for any type.
  485. * @param aPoint - Coordinate for hit testing.
  486. * @return The draw object if found. Otherwise NULL.
  487. */
  488. LIB_ITEM* LocateDrawItem( int aUnit, int aConvert, KICAD_T aType, const wxPoint& aPoint );
  489. /**
  490. * Locate a draw object (overlaid)
  491. *
  492. * @param aUnit - Unit number of draw item.
  493. * @param aConvert - Body style of draw item.
  494. * @param aType - Draw object type, set to 0 to search for any type.
  495. * @param aPoint - Coordinate for hit testing.
  496. * @param aTransform = the transform matrix
  497. * @return The draw object if found. Otherwise NULL.
  498. */
  499. LIB_ITEM* LocateDrawItem( int aUnit, int aConvert, KICAD_T aType,
  500. const wxPoint& aPoint, const TRANSFORM& aTransform );
  501. /**
  502. * Return a reference to the draw item list.
  503. *
  504. * @return LIB_ITEMS& - Reference to the draw item object list.
  505. */
  506. LIB_ITEMS& GetDrawItemList() { return drawings; }
  507. /**
  508. * Set the part per package count.
  509. *
  510. * If the count is greater than the current count, then the all of the
  511. * current draw items are duplicated for each additional part. If the
  512. * count is less than the current count, all draw objects for parts
  513. * greater that count are removed from the component.
  514. *
  515. * @param count - Number of parts per package.
  516. */
  517. void SetPartCount( int count );
  518. int GetPartCount() { return m_unitCount; }
  519. /**
  520. * Function IsMulti
  521. * @return true if the component has multiple parts per package.
  522. * When happens, the reference has a sub reference ti identify part
  523. */
  524. bool IsMulti() { return m_unitCount > 1; }
  525. /**
  526. * Function ReturnSubReference
  527. * @return the sub reference for component having multiple parts per package.
  528. * The sub reference identify the part (or unit)
  529. * @param aUnit = the part identifier ( 1 to max count)
  530. * Note: this is a static function.
  531. */
  532. static wxString ReturnSubReference( int aUnit );
  533. /**
  534. * Set or clear the alternate body style (DeMorgan) for the component.
  535. *
  536. * If the component already has an alternate body style set and a
  537. * asConvert if false, all of the existing draw items for the alternate
  538. * body style are remove. If the alternate body style is not set and
  539. * asConvert is true, than the base draw items are duplicated and
  540. * added to the component.
  541. *
  542. * @param aSetConvert - Set or clear the component alternate body style.
  543. */
  544. void SetConversion( bool aSetConvert );
  545. /**
  546. * Set the offset in mils of the pin name text from the pin symbol.
  547. *
  548. * Set the offset to 0 to draw the pin name above the pin symbol.
  549. *
  550. * @param aOffset - The offset in mils.
  551. */
  552. void SetPinNameOffset( int aOffset ) { m_pinNameOffset = aOffset; }
  553. int GetPinNameOffset() { return m_pinNameOffset; }
  554. /**
  555. * Set or clear the pin name visibility flag.
  556. *
  557. * @param aShow - True to make the component pin names visible.
  558. */
  559. void SetShowPinNames( bool aShow ) { m_showPinNames = aShow; }
  560. bool ShowPinNames() { return m_showPinNames; }
  561. /**
  562. * Set or clear the pin number visibility flag.
  563. *
  564. * @param aShow - True to make the component pin numbers visible.
  565. */
  566. void SetShowPinNumbers( bool aShow ) { m_showPinNumbers = aShow; }
  567. bool ShowPinNumbers() { return m_showPinNumbers; }
  568. bool operator==( const LIB_COMPONENT* aComponent ) const { return this == aComponent; }
  569. #if defined(DEBUG)
  570. void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override
  571. #endif
  572. };
  573. #endif // CLASS_LIBENTRY_H