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.

651 lines
22 KiB

18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 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) 2014 Dick Hollenbeck, dick@softplc.com
  6. * Copyright (C) 2015 Wayne Stambaugh <stambaughw@gmail.com>
  7. * Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License
  11. * as published by the Free Software Foundation; either version 2
  12. * of the License, or (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, you may find one here:
  21. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  22. * or you may search the http://www.gnu.org website for the version 2 license,
  23. * or you may write to the Free Software Foundation, Inc.,
  24. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  25. */
  26. #ifndef COMPONENT_CLASS_H
  27. #define COMPONENT_CLASS_H
  28. #include <lib_id.h>
  29. #include <sch_field.h>
  30. #include <transform.h>
  31. #include <general.h>
  32. #include <vector>
  33. #include <set>
  34. #include <lib_item.h>
  35. #include <sch_pin.h>
  36. #include <sch_base_frame.h>
  37. class SCH_SCREEN;
  38. class SCH_SHEET_PATH;
  39. class LIB_ITEM;
  40. class LIB_PIN;
  41. class LIB_PART;
  42. class NETLIST_OBJECT_LIST;
  43. class PART_LIB;
  44. class PART_LIBS;
  45. class EE_COLLECTOR;
  46. class SCH_SCREEN;
  47. class SYMBOL_LIB_TABLE;
  48. /// A container for several SCH_PIN items
  49. typedef std::vector<SCH_PIN> SCH_PINS;
  50. /// A map from the library pin pointer to the SCH_PIN's index
  51. typedef std::unordered_map<LIB_PIN*, unsigned> SCH_PIN_MAP;
  52. /// A container for several SCH_FIELD items
  53. typedef std::vector<SCH_FIELD> SCH_FIELDS;
  54. typedef std::weak_ptr<LIB_PART> PART_REF;
  55. extern std::string toUTFTildaText( const wxString& txt );
  56. /**
  57. * Class SCH_COMPONENT
  58. * describes a real schematic component
  59. */
  60. class SCH_COMPONENT : public SCH_ITEM
  61. {
  62. public:
  63. enum AUTOPLACED { AUTOPLACED_NO = 0, AUTOPLACED_AUTO, AUTOPLACED_MANUAL };
  64. private:
  65. wxPoint m_Pos;
  66. ///< Name and library where symbol was loaded from, i.e. "74xx:74LS00".
  67. LIB_ID m_lib_id;
  68. int m_unit; ///< The unit for multiple part per package components.
  69. int m_convert; ///< The alternate body style for components that have more than
  70. ///< one body style defined. Primarily used for components that
  71. ///< have a De Morgan conversion.
  72. wxString m_prefix; ///< C, R, U, Q etc - the first character which typically indicates
  73. ///< what the component is. Determined, upon placement, from the
  74. ///< library component. Created upon file load, by the first
  75. ///< non-digits in the reference fields.
  76. TRANSFORM m_transform; ///< The rotation/mirror transformation matrix.
  77. SCH_FIELDS m_Fields; ///< Variable length list of fields.
  78. ///< A flattened copy of a LIB_PART found in the PROJECT's libraries to for this component.
  79. std::unique_ptr< LIB_PART > m_part;
  80. SCH_PINS m_pins; ///< the component's pins
  81. SCH_PIN_MAP m_pinMap; ///< the component's pins mapped by LIB_PIN*.
  82. AUTOPLACED m_fieldsAutoplaced; ///< indicates status of field autoplacement
  83. bool m_isInNetlist; ///< True if the component should appear in the netlist
  84. /**
  85. * Defines the hierarchical path and reference of the component. This allows support
  86. * for hierarchical sheets that reference the same schematic. The format for the path
  87. * is /&ltsheet time stamp&gt/&ltsheet time stamp&gt/.../&lscomponent time stamp&gt.
  88. * A single / denotes the root sheet.
  89. */
  90. wxArrayString m_PathsAndReferences;
  91. void Init( const wxPoint& pos = wxPoint( 0, 0 ) );
  92. public:
  93. SCH_COMPONENT( const wxPoint& pos = wxPoint( 0, 0 ), SCH_ITEM* aParent = NULL );
  94. /**
  95. * Create schematic component from library component object.
  96. *
  97. * @param aPart - library part to create schematic component from.
  98. * @param aLibId - libId of alias to create.
  99. * @param aSheet - Schematic sheet the component is place into.
  100. * @param unit - Part for components that have multiple parts per
  101. * package.
  102. * @param convert - Use the alternate body style for the schematic
  103. * component.
  104. * @param pos - Position to place new component.
  105. * @param setNewItemFlag - Set the component IS_NEW and IS_MOVED flags.
  106. */
  107. SCH_COMPONENT( LIB_PART& aPart, LIB_ID aLibId, SCH_SHEET_PATH* aSheet,
  108. int unit = 0, int convert = 0,
  109. const wxPoint& pos = wxPoint( 0, 0 ) );
  110. SCH_COMPONENT( LIB_PART& aPart, SCH_SHEET_PATH* aSheet,
  111. SCH_BASE_FRAME::COMPONENT_SELECTION& aSel,
  112. const wxPoint& pos = wxPoint( 0, 0 ) );
  113. /**
  114. * Clones \a aComponent into a new schematic symbol object.
  115. *
  116. * All fields are copied as is except for the linked list management pointers
  117. * which are set to NULL, and the SCH_FIELD's m_Parent pointers which are set
  118. * to the new object.
  119. *
  120. * @param aComponent is the schematic symbol to clone.
  121. */
  122. SCH_COMPONENT( const SCH_COMPONENT& aComponent );
  123. ~SCH_COMPONENT() { }
  124. static inline bool ClassOf( const EDA_ITEM* aItem )
  125. {
  126. return aItem && SCH_COMPONENT_T == aItem->Type();
  127. }
  128. wxString GetClass() const override
  129. {
  130. return wxT( "SCH_COMPONENT" );
  131. }
  132. const wxArrayString& GetPathsAndReferences() const { return m_PathsAndReferences; }
  133. void ViewGetLayers( int aLayers[], int& aCount ) const override;
  134. /**
  135. * Return true for items which are moved with the anchor point at mouse cursor
  136. * and false for items moved with no reference to anchor.
  137. *
  138. * Usually return true for small items (labels, junctions) and false for items which can
  139. * be large (hierarchical sheets, components).
  140. *
  141. * Note: we used to try and be smart about this and return false for components in case
  142. * they are big. However, this annoyed some users and we now have a preference which
  143. * controls warping on move in general, so this was switched to true for components.
  144. *
  145. * @return true for a component
  146. */
  147. bool IsMovableFromAnchorPoint() override { return true; }
  148. void SetLibId( const LIB_ID& aName, PART_LIBS* aLibs=NULL );
  149. void SetLibId( const LIB_ID& aLibId, SYMBOL_LIB_TABLE* aSymLibTable, PART_LIB* aCacheLib );
  150. const LIB_ID& GetLibId() const { return m_lib_id; }
  151. std::unique_ptr< LIB_PART >& GetPartRef() { return m_part; }
  152. /**
  153. * Return information about the aliased parts
  154. */
  155. wxString GetDescription() const;
  156. /**
  157. * Return the documentation text for the given part alias
  158. */
  159. wxString GetDatasheet() const;
  160. /**
  161. * Assigns the current #LIB_PART from \a aLibs which this symbol is based on.
  162. *
  163. * @param aLibs is the current set of LIB_PARTs to choose from.
  164. */
  165. bool Resolve( PART_LIBS* aLibs );
  166. bool Resolve( SYMBOL_LIB_TABLE& aLibTable, PART_LIB* aCacheLib = NULL );
  167. static void ResolveAll( const EE_COLLECTOR& aComponents, SYMBOL_LIB_TABLE& aLibTable,
  168. PART_LIB* aCacheLib = NULL );
  169. int GetUnit() const { return m_unit; }
  170. /**
  171. * Update the pin cache for all components in \a aComponents
  172. *
  173. * @param aComponents collector of components in screen
  174. */
  175. static void UpdatePins( const EE_COLLECTOR& aComponents );
  176. /**
  177. * Updates the local cache of SCH_PIN_CONNECTION objects for each pin
  178. */
  179. void UpdatePins( SCH_SHEET_PATH* aSheet = nullptr );
  180. /**
  181. * Retrieves the connection for a given pin of the component
  182. */
  183. SCH_CONNECTION* GetConnectionForPin( LIB_PIN* aPin, const SCH_SHEET_PATH& aSheet );
  184. /**
  185. * Change the unit number to \a aUnit
  186. *
  187. * This has meaning only for symbols made up of multiple units per package.
  188. *
  189. * @note This also set the modified flag bit
  190. *
  191. * @param aUnit is the new unit to select.
  192. */
  193. void SetUnit( int aUnit );
  194. /**
  195. * Change the unit number to \a aUnit without setting any internal flags.
  196. * This has meaning only for symbols made up of multiple units per package.
  197. *
  198. * @note This also set the modified flag bit
  199. *
  200. * @param aUnit is the new unit to select.
  201. */
  202. void UpdateUnit( int aUnit );
  203. int GetConvert() const { return m_convert; }
  204. void SetConvert( int aConvert );
  205. wxString GetPrefix() const { return m_prefix; }
  206. void SetPrefix( const wxString& aPrefix ) { m_prefix = aPrefix; }
  207. TRANSFORM& GetTransform() const { return const_cast< TRANSFORM& >( m_transform ); }
  208. void SetTransform( const TRANSFORM& aTransform );
  209. /**
  210. * Return the number of units per package of the symbol.
  211. *
  212. * @return the number of units per package or zero if the library entry cannot be found.
  213. */
  214. int GetUnitCount() const;
  215. /**
  216. * Compute the new transform matrix based on \a aOrientation for the symbol which is
  217. * applied to the current transform.
  218. *
  219. * @param aOrientation is the orientation to apply to the transform.
  220. */
  221. void SetOrientation( int aOrientation );
  222. /**
  223. * Get the display symbol orientation.
  224. *
  225. * Because there are different ways to have a given orientation/mirror,
  226. * the orientation/mirror is not necessary what the user does. For example:
  227. * a mirrorX then a mirrorY returns no mirror but a rotate. This function finds
  228. * a rotation and a mirror value #CMP_MIRROR_X because this is the first mirror
  229. * option tested. This can differs from the orientation made by an user. A
  230. * #CMP_MIRROR_Y is returned as a #CMP_MIRROR_X with an orientation 180 because
  231. * they are equivalent.
  232. *
  233. * @sa COMPONENT_ORIENTATION_T
  234. *
  235. * @return the orientation and mirror of the symbol.
  236. */
  237. int GetOrientation();
  238. void GetMsgPanelInfo( EDA_UNITS aUnits, std::vector<MSG_PANEL_ITEM>& aList ) override;
  239. /**
  240. * Clear exiting component annotation.
  241. *
  242. * For example, IC23 would be changed to IC? and unit number would be reset.
  243. *
  244. * @param aSheetPath is the hierarchical path of the symbol to clear or remove all
  245. * annotations for this symbol if NULL.
  246. */
  247. void ClearAnnotation( SCH_SHEET_PATH* aSheetPath );
  248. /**
  249. * Add aSheetPath in m_PathsAndReferences alternate references list,
  250. * if this entry does not exist
  251. * Do nothing if already exists.
  252. * In component lists shared by more than one sheet path, an entry for each
  253. * sheet path must exist to manage references
  254. * @param aSheetPathName is the candidate sheet path name
  255. * this sheet path is the sheet path of the sheet containing the component,
  256. * not the full component sheet path
  257. * @return false if the alternate reference was existing, true if added.
  258. */
  259. bool AddSheetPathReferenceEntryIfMissing( const wxString& aSheetPathName );
  260. /**
  261. * Change the time stamp to \a aNewTimeStamp and updates the reference path.
  262. *
  263. * @see m_PathsAndReferences
  264. *
  265. * @param aNewTimeStamp = new time stamp
  266. */
  267. void SetTimeStamp( timestamp_t aNewTimeStamp );
  268. /**
  269. * Clear the HIGHLIGHTED flag of all items of the component (fields, pins ...)
  270. */
  271. bool ClearAllHighlightFlags();
  272. const EDA_RECT GetBoundingBox() const override;
  273. /**
  274. * Return a bounding box for the symbol body but not the fields.
  275. */
  276. EDA_RECT GetBodyBoundingBox() const;
  277. //-----<Fields>-----------------------------------------------------------
  278. /**
  279. * Returns a field in this symbol.
  280. *
  281. * @param aFieldNdx is the index into the array of fields, not a field id.
  282. *
  283. * @return is the field at \a aFieldNdx or NULL if the field does not exist.
  284. */
  285. SCH_FIELD* GetField( int aFieldNdx ) const;
  286. /**
  287. * Search for a field named \a aFieldName and returns text associated with this field.
  288. *
  289. * @param aFieldName is the name of the field
  290. */
  291. wxString GetFieldText( const wxString& aFieldName, SCH_EDIT_FRAME* aFrame ) const;
  292. /**
  293. * Populates a std::vector with SCH_FIELDs.
  294. *
  295. * @param aVector is the vector to populate.
  296. * @param aVisibleOnly is used to add only the fields that are visible and contain text.
  297. */
  298. void GetFields( std::vector<SCH_FIELD*>& aVector, bool aVisibleOnly );
  299. /**
  300. * Add a field to the symbol.
  301. *
  302. * @param aField is the field to add to this symbol.
  303. *
  304. * @return the newly inserted field.
  305. */
  306. SCH_FIELD* AddField( const SCH_FIELD& aField );
  307. /**
  308. * Removes a user field from the symbol.
  309. * @param aFieldName is the user fieldName to remove. Attempts to remove a mandatory
  310. * field or a non-existant field are silently ignored.
  311. */
  312. void RemoveField( const wxString& aFieldName );
  313. /**
  314. * Search for a #SCH_FIELD with \a aFieldName
  315. *
  316. * @param aFieldName is the name of the field to find.
  317. * @param aIncludeDefaultFields searches the library symbol default fields if true.
  318. *
  319. * @return the field if found or NULL if the field was not found.
  320. */
  321. SCH_FIELD* FindField( const wxString& aFieldName, bool aIncludeDefaultFields = true );
  322. /**
  323. * Set multiple schematic fields.
  324. *
  325. * @param aFields are the fields to set in this symbol.
  326. */
  327. void SetFields( const SCH_FIELDS& aFields )
  328. {
  329. m_Fields = aFields; // vector copying, length is changed possibly
  330. }
  331. /**
  332. * Restores fields to the original library values.
  333. * @param aResetStyle selects whether fields should reset the position and text attribute.
  334. * @param aResetRef selects whether the reference field should be restored.
  335. */
  336. void UpdateFields( bool aResetStyle, bool aResetRef = false );
  337. /**
  338. * Return the number of fields in this symbol.
  339. */
  340. int GetFieldCount() const { return (int)m_Fields.size(); }
  341. /**
  342. * Return whether the fields have been automatically placed.
  343. */
  344. AUTOPLACED GetFieldsAutoplaced() const { return m_fieldsAutoplaced; }
  345. /**
  346. * Set fields automatically placed flag false.
  347. */
  348. void ClearFieldsAutoplaced() { m_fieldsAutoplaced = AUTOPLACED_NO; }
  349. /**
  350. * Automatically orient all the fields in the component.
  351. *
  352. * @param aScreen is the SCH_SCREEN associated with the current instance of the
  353. * component. This can be NULL when aManual is false.
  354. * @param aManual should be true if the autoplace was manually initiated (e.g. by a hotkey
  355. * or a menu item). Some more 'intelligent' routines will be used that would be
  356. * annoying if done automatically during moves.
  357. */
  358. void AutoplaceFields( SCH_SCREEN* aScreen, bool aManual );
  359. /**
  360. * Autoplace fields only if correct to do so automatically.
  361. *
  362. * Fields that have been moved by hand are not automatically placed.
  363. *
  364. * @param aScreen is the SCH_SCREEN associated with the current instance of the
  365. * component.
  366. */
  367. void AutoAutoplaceFields( SCH_SCREEN* aScreen )
  368. {
  369. if( GetFieldsAutoplaced() )
  370. AutoplaceFields( aScreen, GetFieldsAutoplaced() == AUTOPLACED_MANUAL );
  371. }
  372. //-----</Fields>----------------------------------------------------------
  373. /**
  374. * Find a symbol pin by number.
  375. *
  376. * @param number is the number of the pin to find.
  377. *
  378. * @return Pin object if found, otherwise NULL.
  379. */
  380. LIB_PIN* GetPin( const wxString& number );
  381. /**
  382. * Populate a vector with all the pins from the library object.
  383. *
  384. * @param aPinsList is the list to populate with all of the pins.
  385. */
  386. void GetPins( std::vector<LIB_PIN*>& aPinsList );
  387. SCH_PINS& GetPins() { return m_pins; }
  388. /**
  389. * Print a component
  390. *
  391. * @param aDC is the device context (can be null)
  392. * @param aOffset is the drawing offset (usually wxPoint(0,0),
  393. * but can be different when moving an object)
  394. */
  395. void Print( wxDC* aDC, const wxPoint& aOffset ) override;
  396. void SwapData( SCH_ITEM* aItem ) override;
  397. // returns a unique ID, in the form of a path.
  398. wxString GetPath( const SCH_SHEET_PATH* sheet ) const;
  399. /**
  400. * Tests for an acceptable reference string.
  401. *
  402. * An acceptable reference string must support unannotation i.e starts by letter
  403. *
  404. * @param aReferenceString is the reference string to validate
  405. *
  406. * @return true if reference string is valid.
  407. */
  408. static bool IsReferenceStringValid( const wxString& aReferenceString );
  409. /**
  410. * Return the reference for the given sheet path.
  411. *
  412. * @return the reference for the sheet.
  413. */
  414. const wxString GetRef( const SCH_SHEET_PATH* aSheet );
  415. /**
  416. * Set the reference for the given sheet path for this symbol.
  417. *
  418. * @param aSheet is the hierarchical path of the reference.
  419. * @param aReference is the new reference for the symbol.
  420. */
  421. void SetRef( const SCH_SHEET_PATH* aSheet, const wxString& aReference );
  422. /**
  423. * Checks if the component has a valid annotation (reference) for the given sheet path
  424. * @param aSheet is the sheet path to test
  425. * @return true if the component exists on that sheet and has a valid reference
  426. */
  427. bool IsAnnotated( const SCH_SHEET_PATH* aSheet );
  428. /**
  429. * Add a full hierarchical reference to this symbol.
  430. *
  431. * @param aPath is the hierarchical path (/&ltsheet timestamp&gt/&ltcomponent
  432. * timestamp&gt like /05678E50/A23EF560)
  433. * @param aRef is the local reference like C45, R56
  434. * @param aMulti is the unit selection used for symbols with multiple units per package.
  435. */
  436. void AddHierarchicalReference( const wxString& aPath,
  437. const wxString& aRef,
  438. int aMulti );
  439. // returns the unit selection, for the given sheet path.
  440. int GetUnitSelection( SCH_SHEET_PATH* aSheet );
  441. // Set the unit selection, for the given sheet path.
  442. void SetUnitSelection( SCH_SHEET_PATH* aSheet, int aUnitSelection );
  443. // Geometric transforms (used in block operations):
  444. void Move( const wxPoint& aMoveVector ) override
  445. {
  446. if( aMoveVector == wxPoint( 0, 0 ) )
  447. return;
  448. m_Pos += aMoveVector;
  449. for( int ii = 0; ii < GetFieldCount(); ii++ )
  450. GetField( ii )->Move( aMoveVector );
  451. SetModified();
  452. }
  453. void MirrorY( int aYaxis_position ) override;
  454. void MirrorX( int aXaxis_position ) override;
  455. void Rotate( wxPoint aPosition ) override;
  456. bool Matches( wxFindReplaceData& aSearchData, void* aAuxData ) override;
  457. void GetEndPoints( std::vector<DANGLING_END_ITEM>& aItemList ) override;
  458. /**
  459. * Test if the component's dangling state has changed for all pins.
  460. *
  461. * As a side effect, actually update the dangling status for all pins.
  462. *
  463. * @note This does not test for short circuits.
  464. *
  465. * @param aItemList is list of all #DANGLING_END_ITEM items to be tested.
  466. *
  467. * @return true if any pin's state has changed.
  468. */
  469. bool UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList ) override;
  470. wxPoint GetPinPhysicalPosition( const LIB_PIN* Pin ) const;
  471. bool IsConnectable() const override { return true; }
  472. bool CanConnect( const SCH_ITEM* aItem ) const override
  473. {
  474. return ( aItem->Type() == SCH_LINE_T && aItem->GetLayer() == LAYER_WIRE ) ||
  475. ( aItem->Type() == SCH_NO_CONNECT_T ) ||
  476. ( aItem->Type() == SCH_JUNCTION_T ) ||
  477. ( aItem->Type() == SCH_COMPONENT_T ) ;
  478. }
  479. /**
  480. * @return true if the component is in netlist
  481. * which means this is not a power component, or something
  482. * like a component reference starting by #
  483. */
  484. bool IsInNetlist() const;
  485. void GetConnectionPoints( std::vector<wxPoint>& aPoints ) const override;
  486. SEARCH_RESULT Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] ) override;
  487. /**
  488. * Return the component library item at \a aPosition that is part of this component.
  489. *
  490. * @param aPosition is the schematic position of the component library object.
  491. * @param aType is the type of symbol library object to find or any if set to TYPE_NOT_INIT.
  492. *
  493. * @return is the symbol library object if found otherwise NULL.
  494. */
  495. LIB_ITEM* GetDrawItem( const wxPoint& aPosition, KICAD_T aType = TYPE_NOT_INIT );
  496. wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;
  497. BITMAP_DEF GetMenuImage() const override;
  498. void GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems, SCH_SHEET_PATH* aSheetPath ) override;
  499. bool operator <( const SCH_ITEM& aItem ) const override;
  500. bool operator==( const SCH_COMPONENT& aComponent) const;
  501. bool operator!=( const SCH_COMPONENT& aComponent) const;
  502. SCH_COMPONENT& operator=( const SCH_ITEM& aItem );
  503. bool IsReplaceable() const override { return true; }
  504. wxPoint GetPosition() const override { return m_Pos; }
  505. void SetPosition( const wxPoint& aPosition ) override { Move( aPosition - m_Pos ); }
  506. bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
  507. bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
  508. void Plot( PLOTTER* aPlotter ) override;
  509. EDA_ITEM* Clone() const override;
  510. #if defined(DEBUG)
  511. void Show( int nestLevel, std::ostream& os ) const override;
  512. #endif
  513. void ClearBrightenedPins();
  514. bool HasBrightenedPins();
  515. void BrightenPin( LIB_PIN* aPin );
  516. void ClearHighlightedPins();
  517. bool HasHighlightedPins();
  518. void HighlightPin( LIB_PIN* aPin );
  519. private:
  520. bool doIsConnected( const wxPoint& aPosition ) const override;
  521. };
  522. #endif /* COMPONENT_CLASS_H */