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.

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