1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2004-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
6  * Copyright (C) 2004-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 CLASS_LIBENTRY_H
27 #define CLASS_LIBENTRY_H
28 
29 #include <general.h>
30 #include <lib_tree_item.h>
31 #include <lib_item.h>
32 #include <lib_field.h>
33 #include <vector>
34 #include <multivector.h>
35 
36 class EDA_RECT;
37 class LINE_READER;
38 class OUTPUTFORMATTER;
39 class SYMBOL_LIB;
40 class LIB_SYMBOL;
41 class LIB_FIELD;
42 class TEST_LIB_SYMBOL_FIXTURE;
43 
44 
45 typedef std::shared_ptr<LIB_SYMBOL>       LIB_SYMBOL_SPTR;      ///< shared pointer to LIB_SYMBOL
46 typedef std::weak_ptr<LIB_SYMBOL>         LIB_SYMBOL_REF;       ///< weak pointer to LIB_SYMBOL
47 typedef MULTIVECTOR<LIB_ITEM, LIB_SHAPE_T, LIB_FIELD_T> LIB_ITEMS_CONTAINER;
48 typedef LIB_ITEMS_CONTAINER::ITEM_PTR_VECTOR LIB_ITEMS;
49 
50 
51 /* values for member .m_options */
52 enum LIBRENTRYOPTIONS
53 {
54     ENTRY_NORMAL,   // Libentry is a standard symbol (real or alias)
55     ENTRY_POWER     // Libentry is a power symbol
56 };
57 
58 
59 extern bool operator<( const LIB_SYMBOL& aItem1, const LIB_SYMBOL& aItem2 );
60 
61 
62 struct LIB_SYMBOL_OPTIONS
63 {
64     TRANSFORM transform;            // Coordinate adjustment settings
65     bool draw_visible_fields;       // Whether to draw "visible" fields
66     bool draw_hidden_fields;        // Whether to draw "hidden" fields
67     bool show_elec_type;            // Whether to show the pin electrical type
68     bool show_connect_point;        // Whether to show the pin connect point marker (small circle)
69                                     // useful in dialog pin properties
70 
LIB_SYMBOL_OPTIONSLIB_SYMBOL_OPTIONS71     LIB_SYMBOL_OPTIONS()
72     {
73         transform = DefaultTransform;
74         draw_visible_fields = true;
75         draw_hidden_fields = true;
76         show_elec_type = false;
77         show_connect_point = false;
78     }
79 };
80 
81 
82 struct LIB_SYMBOL_UNIT
83 {
84     int m_unit;                       ///< The unit number.
85     int m_convert;                    ///< The alternate body style of the unit.
86     std::vector<LIB_ITEM*> m_items;   ///< The items unique to this unit and alternate body style.
87 };
88 
89 
90 /**
91  * Define a library symbol object.
92  *
93  * A library symbol object is typically saved and loaded in a symbol library file (.lib).
94  * Library symbols are different from schematic symbols.
95  */
96 class LIB_SYMBOL : public EDA_ITEM, public LIB_TREE_ITEM
97 {
98 public:
99     LIB_SYMBOL( const wxString& aName, LIB_SYMBOL* aParent = nullptr,
100                 SYMBOL_LIB* aLibrary = nullptr );
101 
102     LIB_SYMBOL( const LIB_SYMBOL& aSymbol, SYMBOL_LIB* aLibrary = nullptr );
103 
104     virtual ~LIB_SYMBOL();
105 
106     ///< http://www.boost.org/doc/libs/1_55_0/libs/smart_ptr/sp_techniques.html#weak_without_shared
SharedPtr()107     LIB_SYMBOL_SPTR SharedPtr() const { return m_me; }
108 
109     /**
110      * Create a copy of a LIB_SYMBOL and assigns unique KIIDs to the copy and its children.
111      */
Duplicate()112     virtual LIB_SYMBOL* Duplicate() const
113     {
114         LIB_SYMBOL* dupe = new LIB_SYMBOL( *this, m_library );
115         const_cast<KIID&>( dupe->m_Uuid ) = KIID();
116 
117         for( LIB_ITEM& item : dupe->m_drawings )
118             const_cast<KIID&>( item.m_Uuid ) = KIID();
119 
120         return dupe;
121     }
122 
123     void SetParent( LIB_SYMBOL* aParent = nullptr );
GetParent()124     LIB_SYMBOL_REF& GetParent() { return m_parent; }
GetParent()125     const LIB_SYMBOL_REF& GetParent() const { return m_parent; }
126 
GetClass()127     virtual wxString GetClass() const override
128     {
129         return wxT( "LIB_SYMBOL" );
130     }
131 
132     virtual void SetName( const wxString& aName );
GetName()133     wxString GetName() const override { return m_name; }
134 
GetLibId()135     LIB_ID GetLibId() const override { return m_libId; }
SetLibId(const LIB_ID & aLibId)136     void SetLibId( const LIB_ID& aLibId ) { m_libId = aLibId; }
137 
GetLibNickname()138     wxString GetLibNickname() const override { return GetLibraryName(); }
139 
SetDescription(const wxString & aDescription)140     void SetDescription( const wxString& aDescription ) { m_description = aDescription; }
141 
GetDescription()142     wxString GetDescription() override
143     {
144         if( m_description.IsEmpty() && IsAlias() )
145         {
146             if( LIB_SYMBOL_SPTR parent = m_parent.lock() )
147                 return parent->GetDescription();
148         }
149 
150         return m_description;
151     }
152 
SetKeyWords(const wxString & aKeyWords)153     void SetKeyWords( const wxString& aKeyWords ) { m_keyWords = aKeyWords; }
154 
GetKeyWords()155     wxString GetKeyWords() const
156     {
157         if( m_keyWords.IsEmpty() && IsAlias() )
158         {
159             if( LIB_SYMBOL_SPTR parent = m_parent.lock() )
160                 return parent->GetKeyWords();
161         }
162 
163         return m_keyWords;
164     }
165 
166     wxString GetSearchText() override;
167 
168     /**
169      * For symbols derived from other symbols, IsRoot() indicates no derivation.
170      */
IsRoot()171     bool IsRoot() const override { return m_parent.use_count() == 0; }
IsAlias()172     bool IsAlias() const { return !m_parent.expired() && m_parent.use_count() > 0; }
173 
174     const wxString GetLibraryName() const;
175 
GetLib()176     SYMBOL_LIB* GetLib() const          { return m_library; }
SetLib(SYMBOL_LIB * aLibrary)177     void SetLib( SYMBOL_LIB* aLibrary ) { m_library = aLibrary; }
178 
GetLastModDate()179     timestamp_t GetLastModDate() const { return m_lastModDate; }
180 
SetFPFilters(const wxArrayString & aFilters)181     void SetFPFilters( const wxArrayString& aFilters ) { m_fpFilters = aFilters; }
182 
GetFPFilters()183     wxArrayString GetFPFilters() const
184     {
185         if( m_fpFilters.IsEmpty() && IsAlias() )
186         {
187             if( LIB_SYMBOL_SPTR parent = m_parent.lock() )
188                 return parent->GetFPFilters();
189         }
190 
191         return m_fpFilters;
192     }
193 
194     void ViewGetLayers( int aLayers[], int& aCount ) const override;
195 
196     /**
197      * Get the bounding box for the symbol.
198      *
199      * @return the symbol bounding box ( in user coordinates )
200      * @param aUnit = unit selection = 0, or 1..n
201      * @param aConvert = 0, 1 or 2
202      *  If aUnit == 0, unit is not used
203      *  if aConvert == 0 Convert is non used
204      *  Invisible fields are not taken in account
205      **/
206     const EDA_RECT GetUnitBoundingBox( int aUnit, int aConvert ) const;
207 
208     /**
209      * Get the symbol bounding box excluding fields.
210      *
211      * @return the symbol bounding box ( in user coordinates ) without fields
212      * @param aUnit = unit selection = 0, or 1..n
213      * @param aConvert = 0, 1 or 2
214      *  If aUnit == 0, unit is not used
215      *  if aConvert == 0 Convert is non used
216      *  Fields are not taken in account
217      **/
218     const EDA_RECT GetBodyBoundingBox( int aUnit, int aConvert, bool aIncludePins ) const;
219 
GetBoundingBox()220     const EDA_RECT GetBoundingBox() const override
221     {
222         return GetUnitBoundingBox( 0, 0 );
223     }
224 
225     bool IsPower() const;
226     bool IsNormal() const;
227 
228     void SetPower();
229     void SetNormal();
230 
231     /**
232      * Set interchangeable the property for symbol units.
233      * @param aLockUnits when true then units are set as not interchangeable.
234      */
LockUnits(bool aLockUnits)235     void LockUnits( bool aLockUnits ) { m_unitsLocked = aLockUnits; }
236 
237     /**
238      * Check whether symbol units are interchangeable.
239      * @return False when interchangeable, true otherwise.
240      */
UnitsLocked()241     bool UnitsLocked() const { return m_unitsLocked; }
242 
243     /**
244      * Overwrite all the existing fields in this symbol with fields supplied
245      * in \a aFieldsList.
246      *
247      * The only known caller of this function is the library symbol field editor, and it
248      * establishes needed behavior.
249      *
250      * @param aFieldsList is a set of fields to import, removing all previous fields.
251      */
252     void SetFields( const std::vector <LIB_FIELD>& aFieldsList );
253 
254     /**
255      * Return a list of fields within this symbol.
256      *
257      * @param aList - List to add fields to
258      */
259     void GetFields( std::vector<LIB_FIELD*>& aList );
260     void GetFields( std::vector<LIB_FIELD>& aList );
261 
262     /**
263      * Add a field.  Takes ownership of the pointer.
264      */
265     void AddField( LIB_FIELD* aField );
266 
267     /**
268      * Find a field within this symbol matching \a aFieldName and returns it
269      * or NULL if not found.
270      */
271     LIB_FIELD* FindField( const wxString& aFieldName );
272 
273     const LIB_FIELD* FindField( const wxString& aFieldName ) const;
274 
275     /**
276      * Return pointer to the requested field.
277      *
278      * @param aId - Id of field to return.
279      * @return The field if found, otherwise NULL.
280      */
281     LIB_FIELD* GetFieldById( int aId ) const;
282 
283     /** Return reference to the value field. */
284     LIB_FIELD& GetValueField();
285 
286     /** Return reference to the reference designator field. */
287     LIB_FIELD& GetReferenceField();
288 
289     /** Return reference to the footprint field */
290     LIB_FIELD& GetFootprintField();
291 
292     /** Return reference to the datasheet field. */
293     LIB_FIELD& GetDatasheetField();
294 
295     /**
296      * Order optional field indices.
297      *
298      * It's possible when calling #LIB_SYMBOL::Flatten that there can be gaps and/or duplicate
299      * optional field indices.  This method correctly orders the indices so there are no gaps
300      * and/or duplicate indices.
301      */
302     int UpdateFieldOrdinals();
303 
304     int GetNextAvailableFieldId() const;
305 
306     /**
307      * Print symbol.
308      *
309      * @param aOffset - Position of symbol.
310      * @param aMulti - unit if multiple units per symbol.
311      * @param aConvert - Symbol conversion (DeMorgan) if available.
312      * @param aOpts - Drawing options
313      */
314     void Print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset,
315                 int aMulti, int aConvert, const LIB_SYMBOL_OPTIONS& aOpts );
316 
317     /**
318      * Plot lib symbol to plotter.
319      * Lib Fields not are plotted here, because this plot function
320      * is used to plot schematic items, which have they own fields
321      *
322      * @param aPlotter - Plotter object to plot to.
323      * @param aUnit - Symbol symbol to plot.
324      * @param aConvert - Symbol alternate body style to plot.
325      * @param aOffset - Distance to shift the plot coordinates.
326      * @param aTransform - Symbol plot transform matrix.
327      */
328     void Plot( PLOTTER* aPlotter, int aUnit, int aConvert, const wxPoint& aOffset,
329                const TRANSFORM& aTransform ) const;
330 
331     /**
332      * Plot Lib Fields only of the symbol to plotter.
333      * is used to plot the full lib symbol, outside the schematic
334      *
335      * @param aPlotter - Plotter object to plot to.
336      * @param aUnit - Symbol to plot.
337      * @param aConvert - Symbol alternate body style to plot.
338      * @param aOffset - Distance to shift the plot coordinates.
339      * @param aTransform - Symbol plot transform matrix.
340      */
341     void PlotLibFields( PLOTTER* aPlotter, int aUnit, int aConvert, const wxPoint& aOffset,
342                         const TRANSFORM& aTransform );
343 
344     /**
345      * Add a new draw \a aItem to the draw object list and sort according to \a aSort.
346      *
347      * @param aItem is the new draw object to add to the symbol.
348      * @param aSort is the flag to determine if the newly added item should be sorted.
349      */
350     void AddDrawItem( LIB_ITEM* aItem, bool aSort = true );
351 
352     /**
353      * Remove draw \a aItem from list.
354      *
355      * @param aItem - Draw item to remove from list.
356      */
357     void RemoveDrawItem( LIB_ITEM* aItem );
358 
359     /**
360      * Return the next draw object pointer.
361      *
362      * @param aItem - Pointer to the current draw item.  Setting item NULL
363      *                with return the first item of type in the list.
364      * @param aType - type of searched item (filter).
365      *                if TYPE_NOT_INIT search for all items types
366      * @return - The next drawing object in the list if found, otherwise NULL.
367      */
368     LIB_ITEM* GetNextDrawItem( const LIB_ITEM* aItem = nullptr, KICAD_T aType = TYPE_NOT_INIT );
369 
GetPinCount()370     size_t GetPinCount() const { return m_drawings.size( LIB_PIN_T ); }
371 
GetFieldCount()372     size_t GetFieldCount() const { return m_drawings.size( LIB_FIELD_T ); }
373 
374     /**
375      * Return the next pin object from the draw list.
376      *
377      * This is just a pin object specific version of GetNextDrawItem().
378      *
379      * @param aItem - Pointer to the previous pin item, or NULL to get the
380      *                first pin in the draw object list.
381      * @return - The next pin object in the list if found, otherwise NULL.
382      */
383     LIB_PIN* GetNextPin( LIB_PIN* aItem = nullptr )
384     {
385         return (LIB_PIN*) GetNextDrawItem( (LIB_ITEM*) aItem, LIB_PIN_T );
386     }
387 
388     /**
389      * Return a list of pin object pointers from the draw item list.
390      *
391      * Note pin objects are owned by the draw list of the symbol.
392      * Deleting any of the objects will leave list in a unstable state
393      * and will likely segfault when the list is destroyed.
394      *
395      * @param aList - Pin list to place pin object pointers into.
396      * @param aUnit - Unit number of pin to add to list.  Set to 0 to
397      *                get pins from any symbol unit.
398      * @param aConvert - Convert number of pin to add to list.  Set to 0 to
399      *                   get pins from any convert of symbol.
400      */
401     void GetPins( LIB_PINS& aList, int aUnit = 0, int aConvert = 0 ) const;
402 
403     /**
404      * Return pin object with the requested pin \a aNumber.
405      *
406      * @param aNumber - Number of the pin to find.
407      * @param aUnit - Unit of the symbol to find.  Set to 0 if a specific
408      *                unit number is not required.
409      * @param aConvert - Alternate body style filter (DeMorgan).  Set to 0 if
410      *                   no alternate body style is required.
411      * @return The pin object if found.  Otherwise NULL.
412      */
413     LIB_PIN* GetPin( const wxString& aNumber, int aUnit = 0, int aConvert = 0 ) const;
414 
415     /**
416      * Return true if this symbol's pins do not match another symbol's pins. This
417      * is used to detect whether the project cache is out of sync with the
418      * system libs.
419      *
420      * @param aOtherSymbol - The other library symbol to test
421      * @param aTestNums - Whether two pins at the same point must have the same number.
422      * @param aTestNames - Whether two pins at the same point must have the same name.
423      * @param aTestType - Whether two pins at the same point must have the same electrical type.
424      * @param aTestOrientation - Whether two pins at the same point must have the same orientation.
425      * @param aTestLength - Whether two pins at the same point must have the same length.
426      */
427     bool PinsConflictWith( const LIB_SYMBOL& aOtherSymbol, bool aTestNums, bool aTestNames,
428                            bool aTestType, bool aTestOrientation, bool aTestLength ) const;
429 
430     /**
431      * Move the symbol \a aOffset.
432      *
433      * @param aOffset - Offset displacement.
434      */
435     void SetOffset( const wxPoint& aOffset );
436 
437     /**
438      * Remove duplicate draw items from list.
439      */
440     void RemoveDuplicateDrawItems();
441 
442     /**
443      * Test if symbol has more than one body conversion type (DeMorgan).
444      *
445      * @return True if symbol has more than one conversion.
446      */
447     bool HasConversion() const;
448 
449     /**
450      * Clears the status flag all draw objects in this symbol.
451      */
452     void ClearTempFlags();
453     void ClearEditFlags();
454 
455     /**
456      * Locate a draw object.
457      *
458      * @param aUnit - Unit number of draw item.
459      * @param aConvert - Body style of draw item.
460      * @param aType - Draw object type, set to 0 to search for any type.
461      * @param aPoint - Coordinate for hit testing.
462      * @return The draw object if found.  Otherwise NULL.
463      */
464     LIB_ITEM* LocateDrawItem( int aUnit, int aConvert, KICAD_T aType, const wxPoint& aPoint );
465 
466     /**
467      * Locate a draw object (overlaid)
468      *
469      * @param aUnit - Unit number of draw item.
470      * @param aConvert - Body style of draw item.
471      * @param aType - Draw object type, set to 0 to search for any type.
472      * @param aPoint - Coordinate for hit testing.
473      * @param aTransform = the transform matrix
474      * @return The draw object if found.  Otherwise NULL.
475      */
476     LIB_ITEM* LocateDrawItem( int aUnit, int aConvert, KICAD_T aType, const wxPoint& aPoint,
477                               const TRANSFORM& aTransform );
478 
479     /**
480      * Return a reference to the draw item list.
481      *
482      * @return LIB_ITEMS_CONTAINER& - Reference to the draw item object container.
483      */
GetDrawItems()484     LIB_ITEMS_CONTAINER& GetDrawItems() { return m_drawings; }
GetDrawItems()485     const LIB_ITEMS_CONTAINER& GetDrawItems() const { return m_drawings; }
486 
487     SEARCH_RESULT Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] ) override;
488 
489     /**
490      * Set the units per symbol count.
491      *
492      * If the count is greater than the current count, then the all of the
493      * current draw items are duplicated for each additional symbol.  If the
494      * count is less than the current count, all draw objects for units
495      * greater that count are removed from the symbol.
496      *
497      * @param aCount - Number of units per package.
498      * @param aDuplicateDrawItems Create duplicate draw items of unit 1 for each additionl unit.
499      */
500     void SetUnitCount( int aCount, bool aDuplicateDrawItems = true );
501     int GetUnitCount() const override;
502 
503     /**
504      * Return an identifier for \a aUnit for symbols with units.
505      */
506     wxString GetUnitReference( int aUnit ) override;
507 
508     /**
509      * @return true if the symbol has multiple units per symbol.
510      * When true, the reference has a sub reference to identify symbol.
511      */
IsMulti()512     bool IsMulti() const { return m_unitCount > 1; }
513 
514     /**
515      * @return the sub reference for symbol having multiple units per symbol.
516      * The sub reference identify the symbol (or unit)
517      * @param aUnit = the symbol identifier ( 1 to max count)
518      * @param aAddSeparator = true (default) to prepend the sub ref
519      *    by the separator symbol (if any)
520      * Note: this is a static function.
521      */
522     static wxString SubReference( int aUnit, bool aAddSeparator = true );
523 
524     // Accessors to sub ref parameters
GetSubpartIdSeparator()525     static int GetSubpartIdSeparator() { return m_subpartIdSeparator; }
526 
527     /**
528      * Return a reference to m_subpartIdSeparator, only for read/save setting functions.
529      */
SubpartIdSeparatorPtr()530     static int* SubpartIdSeparatorPtr() { return &m_subpartIdSeparator; }
GetSubpartFirstId()531     static int GetSubpartFirstId() { return m_subpartFirstId; }
532 
533     /**
534      * Return a reference to m_subpartFirstId, only for read/save setting functions.
535      */
SubpartFirstIdPtr()536     static int* SubpartFirstIdPtr() { return &m_subpartFirstId; }
537 
538     /**
539      * Set the separator char between the subpart id and the reference
540      * 0 (no separator) or '.' , '-' and '_'
541      * and the ascii char value to calculate the subpart symbol id from the symbol number:
542      * 'A' or '1' only are allowed. (to print U1.A or U1.1)
543      * if this is a digit, a number is used as id symbol
544      * Note also if the subpart symbol is a digit, the separator cannot be null.
545      * @param aSep = the separator symbol (0 (no separator) or '.' , '-' and '_')
546      * @param aFirstId = the Id of the first symbol ('A' or '1')
547      */
548     static void SetSubpartIdNotation( int aSep, int aFirstId );
549 
550     /**
551      * Set or clear the alternate body style (DeMorgan) for the symbol.
552      *
553      * If the symbol already has an alternate body style set and a
554      * asConvert if false, all of the existing draw items for the alternate
555      * body style are remove.  If the alternate body style is not set and
556      * asConvert is true, than the base draw items are duplicated and
557      * added to the symbol.
558      *
559      * @param aSetConvert - Set or clear the symbol alternate body style.
560      * @param aDuplicatePins - Duplicate all pins from original body style if true.
561      */
562     void SetConversion( bool aSetConvert, bool aDuplicatePins = true );
563 
564     /**
565      * Set the offset in mils of the pin name text from the pin symbol.
566      *
567      * Set the offset to 0 to draw the pin name above the pin symbol.
568      *
569      * @param aOffset - The offset in mils.
570      */
SetPinNameOffset(int aOffset)571     void SetPinNameOffset( int aOffset ) { m_pinNameOffset = aOffset; }
GetPinNameOffset()572     int GetPinNameOffset() const { return m_pinNameOffset; }
573 
574     /**
575      * Set or clear the pin name visibility flag.
576      *
577      * @param aShow - True to make the symbol pin names visible.
578      */
SetShowPinNames(bool aShow)579     void SetShowPinNames( bool aShow ) { m_showPinNames = aShow; }
ShowPinNames()580     bool ShowPinNames() const { return m_showPinNames; }
581 
582     /**
583      * Set or clear the pin number visibility flag.
584      *
585      * @param aShow - True to make the symbol pin numbers visible.
586      */
SetShowPinNumbers(bool aShow)587     void SetShowPinNumbers( bool aShow ) { m_showPinNumbers = aShow; }
ShowPinNumbers()588     bool ShowPinNumbers() const { return m_showPinNumbers; }
589 
590     /**
591      * Set or clear the include in schematic bill of materials flag.
592      *
593      * @param aIncludeInBom true to include symbol in schematic bill of material
594      */
SetIncludeInBom(bool aIncludeInBom)595     void SetIncludeInBom( bool aIncludeInBom ) { m_includeInBom = aIncludeInBom; }
GetIncludeInBom()596     bool GetIncludeInBom() const { return m_includeInBom; }
597 
598     /**
599      * Set or clear include in board netlist flag.
600      *
601      * @param aIncludeOnBoard true to include symbol in the board netlist
602      */
SetIncludeOnBoard(bool aIncludeOnBoard)603     void SetIncludeOnBoard( bool aIncludeOnBoard ) { m_includeOnBoard = aIncludeOnBoard; }
GetIncludeOnBoard()604     bool GetIncludeOnBoard() const { return m_includeOnBoard; }
605 
606     /**
607      * Comparison test that can be used for operators.
608      *
609      * @param aRhs is the right hand side symbol used for comparison.
610      *
611      * @return -1 if this symbol is less than \a aRhs
612      *         1 if this symbol is greater than \a aRhs
613      *         0 if this symbol is the same as \a aRhs
614      */
615     int Compare( const LIB_SYMBOL& aRhs,
616                  LIB_ITEM::COMPARE_FLAGS aCompareFlags = LIB_ITEM::COMPARE_FLAGS::NORMAL ) const;
617 
618     bool operator==( const LIB_SYMBOL* aSymbol ) const { return this == aSymbol; }
619     bool operator==( const LIB_SYMBOL& aSymbol ) const
620     {
621         return Compare( aSymbol, LIB_ITEM::COMPARE_FLAGS::EQUALITY ) == 0;
622     }
623 
624     bool operator!=( const LIB_SYMBOL& aSymbol ) const
625     {
626         return Compare( aSymbol, LIB_ITEM::COMPARE_FLAGS::EQUALITY ) != 0;
627     }
628 
629     const LIB_SYMBOL& operator=( const LIB_SYMBOL& aSymbol );
630 
631     /**
632      * Return a flattened symbol inheritance to the caller.
633      *
634      * If the symbol does not inherit from another symbol, a copy of the symbol is returned.
635      *
636      * @return a flattened symbol on the heap
637      */
638     std::unique_ptr< LIB_SYMBOL > Flatten() const;
639 
640     /**
641      * Return a list of LIB_ITEM objects separated by unit and convert number.
642      *
643      * @note This does not include LIB_FIELD objects since they are not associated with
644      *       unit and/or convert numbers.
645      */
646     std::vector<struct LIB_SYMBOL_UNIT> GetUnitDrawItems();
647 
648     /**
649      * Return a list of unit numbers that are unique to this symbol.
650      *
651      * If the symbol is inherited (alias), the unique units of the parent symbol are returned.
652      * When comparing pins, the pin number is ignored.
653      *
654      * @return a list of unique unit numbers and their associated draw items.
655      */
656     std::vector<struct LIB_SYMBOL_UNIT> GetUniqueUnits();
657 
658     /**
659      * Return a list of item pointers for \a aUnit and \a aConvert for this symbol.
660      *
661      * @note #LIB_FIELD objects are not included.
662      *
663      * @param aUnit is the unit number of the item, -1 includes all units.
664      * @param aConvert is the alternate body styple of the item, -1 includes all body styles.
665      *
666      * @return a list of unit items.
667      */
668     std::vector<LIB_ITEM*> GetUnitDrawItems( int aUnit, int aConvert );
669 
670 #if defined(DEBUG)
Show(int nestLevel,std::ostream & os)671     void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
672 #endif
673 
674 private:
675     // We create a different set parent function for this class, so we hide the inherited one.
676     using EDA_ITEM::SetParent;
677 
678     void deleteAllFields();
679 
680 private:
681     LIB_SYMBOL_SPTR     m_me;
682     LIB_SYMBOL_REF      m_parent;           ///< Use for inherited symbols.
683     LIB_ID              m_libId;
684     timestamp_t         m_lastModDate;
685 
686     int                 m_unitCount;        ///< Number of units (parts) per package.
687     bool                m_unitsLocked;      ///< True if symbol has multiple units and changing one
688                                             ///< unit does not automatically change another unit.
689 
690     int                 m_pinNameOffset;    ///< The offset in mils to draw the pin name.  Set to
691                                             ///< 0 to draw the pin name above the pin.
692     bool                m_showPinNames;
693     bool                m_showPinNumbers;
694 
695     bool                m_includeInBom;
696     bool                m_includeOnBoard;
697     LIBRENTRYOPTIONS    m_options;          ///< Special symbol features such as POWER or NORMAL.)
698 
699     LIB_ITEMS_CONTAINER m_drawings;
700 
701     SYMBOL_LIB*         m_library;
702     wxString            m_name;
703     wxString            m_description;
704     wxString            m_keyWords;         ///< Search keywords
705     wxArrayString       m_fpFilters;        ///< List of suitable footprint names for the
706                                             ///<  symbol (wild card names accepted).
707 
708     static int  m_subpartIdSeparator;       ///< the separator char between
709                                             ///< the subpart id and the reference like U1A
710                                             ///< ( m_subpartIdSeparator = 0 ) or U1.A or U1-A
711     static int  m_subpartFirstId;           ///< the ASCII char value to calculate the subpart
712                                             ///< symbol id from the symbol number: only 'A', 'a'
713                                             ///< or '1' can be used, other values have no sense.
714 };
715 
716 #endif  //  CLASS_LIBENTRY_H
717