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.

509 lines
16 KiB

7 years ago
18 years ago
7 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) 2004-2020 KiCad Developers, see change_log.txt for contributors.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, you may find one here:
  19. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  20. * or you may search the http://www.gnu.org website for the version 2 license,
  21. * or you may write to the Free Software Foundation, Inc.,
  22. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  23. */
  24. #ifndef SCH_ITEM_H
  25. #define SCH_ITEM_H
  26. #include <unordered_map>
  27. #include <unordered_set>
  28. #include <vector>
  29. #include <eda_item.h>
  30. #include <plotter.h> // for PLOT_DASH_TYPE definition
  31. #include <gal/color4d.h>
  32. #include <default_values.h>
  33. #include <sch_sheet_path.h>
  34. #include <render_settings.h>
  35. #include <netclass.h>
  36. class CONNECTION_GRAPH;
  37. class SCH_CONNECTION;
  38. class SCH_SHEET_PATH;
  39. class SCHEMATIC;
  40. class LINE_READER;
  41. class SCH_EDIT_FRAME;
  42. class wxFindReplaceData;
  43. class PLOTTER;
  44. class NETLIST_OBJECT;
  45. class NETLIST_OBJECT_LIST;
  46. using KIGFX::RENDER_SETTINGS;
  47. enum FIELDS_AUTOPLACED
  48. {
  49. FIELDS_AUTOPLACED_NO = 0,
  50. FIELDS_AUTOPLACED_AUTO,
  51. FIELDS_AUTOPLACED_MANUAL
  52. };
  53. enum DANGLING_END_T
  54. {
  55. UNKNOWN = 0,
  56. WIRE_START_END,
  57. WIRE_END_END,
  58. BUS_START_END,
  59. BUS_END_END,
  60. JUNCTION_END,
  61. PIN_END,
  62. LABEL_END,
  63. BUS_ENTRY_END,
  64. WIRE_ENTRY_END,
  65. SHEET_LABEL_END,
  66. NO_CONNECT_END,
  67. };
  68. /**
  69. * Helper class used to store the state of schematic items that can be connected to
  70. * other schematic items.
  71. */
  72. class DANGLING_END_ITEM
  73. {
  74. private:
  75. /// A pointer to the connectable object.
  76. EDA_ITEM* m_item;
  77. /// The position of the connection point.
  78. wxPoint m_pos;
  79. /// The type of connection of #m_item.
  80. DANGLING_END_T m_type;
  81. /// A pointer to the parent object (in the case of pins)
  82. const EDA_ITEM* m_parent;
  83. public:
  84. DANGLING_END_ITEM( DANGLING_END_T aType, EDA_ITEM* aItem, const wxPoint& aPosition )
  85. {
  86. m_item = aItem;
  87. m_type = aType;
  88. m_pos = aPosition;
  89. m_parent = aItem;
  90. }
  91. DANGLING_END_ITEM( DANGLING_END_T aType, EDA_ITEM* aItem,
  92. const wxPoint& aPosition, const EDA_ITEM* aParent )
  93. {
  94. m_item = aItem;
  95. m_type = aType;
  96. m_pos = aPosition;
  97. m_parent = aParent;
  98. }
  99. bool operator==( const DANGLING_END_ITEM& aB )
  100. {
  101. return GetItem() == aB.GetItem()
  102. && GetPosition() == aB.GetPosition()
  103. && GetType() == aB.GetType()
  104. && GetParent() == aB.GetParent();
  105. }
  106. bool operator!=( const DANGLING_END_ITEM& aB )
  107. {
  108. return GetItem() != aB.GetItem()
  109. || GetPosition() != aB.GetPosition()
  110. || GetType() != aB.GetType()
  111. || GetParent() != aB.GetParent();;
  112. }
  113. bool operator<( const DANGLING_END_ITEM& rhs ) const
  114. {
  115. return( m_pos.x < rhs.m_pos.x || ( m_pos.x == rhs.m_pos.x && m_pos.y < rhs.m_pos.y )
  116. || ( m_pos == rhs.m_pos && m_item < rhs.m_item ) );
  117. }
  118. wxPoint GetPosition() const { return m_pos; }
  119. EDA_ITEM* GetItem() const { return m_item; }
  120. const EDA_ITEM* GetParent() const { return m_parent; }
  121. DANGLING_END_T GetType() const { return m_type; }
  122. };
  123. typedef std::unordered_set<SCH_ITEM*> SCH_ITEM_SET;
  124. /**
  125. * Simple container to manage line stroke parameters.
  126. */
  127. class STROKE_PARAMS
  128. {
  129. int m_width;
  130. PLOT_DASH_TYPE m_plotstyle;
  131. COLOR4D m_color;
  132. public:
  133. STROKE_PARAMS( int aWidth = Mils2iu( DEFAULT_LINE_THICKNESS ),
  134. PLOT_DASH_TYPE aPlotStyle = PLOT_DASH_TYPE::DEFAULT,
  135. const COLOR4D& aColor = COLOR4D::UNSPECIFIED ) :
  136. m_width( aWidth ),
  137. m_plotstyle( aPlotStyle ),
  138. m_color( aColor )
  139. {
  140. }
  141. int GetWidth() const { return m_width; }
  142. void SetWidth( int aWidth ) { m_width = aWidth; }
  143. PLOT_DASH_TYPE GetPlotStyle() const { return m_plotstyle; }
  144. void SetPlotStyle( PLOT_DASH_TYPE aPlotStyle ) { m_plotstyle = aPlotStyle; }
  145. COLOR4D GetColor() const { return m_color; }
  146. void SetColor( const COLOR4D& aColor ) { m_color = aColor; }
  147. bool operator!=( const STROKE_PARAMS& aOther )
  148. {
  149. return m_width != aOther.m_width
  150. || m_plotstyle != aOther.m_plotstyle
  151. || m_color != aOther.m_color;
  152. }
  153. };
  154. /**
  155. * Base class for any item which can be embedded within the #SCHEMATIC container class,
  156. * and therefore instances of derived classes should only be found in EESCHEMA or other
  157. * programs that use class SCHEMATIC and its contents.
  158. *
  159. * The corresponding class in Pcbnew is #BOARD_ITEM.
  160. */
  161. class SCH_ITEM : public EDA_ITEM
  162. {
  163. friend class CONNECTION_GRAPH;
  164. protected:
  165. SCH_LAYER_ID m_Layer;
  166. EDA_ITEMS m_connections; // List of items connected to this item.
  167. FIELDS_AUTOPLACED m_fieldsAutoplaced; // indicates status of field autoplacement
  168. wxPoint m_storedPos; // a temporary variable used in some move commands
  169. // to store a initial pos of the item or mouse cursor
  170. /// Stores pointers to other items that are connected to this one, per sheet
  171. std::unordered_map<SCH_SHEET_PATH, SCH_ITEM_SET> m_connected_items;
  172. /// Stores connectivity information, per sheet
  173. std::unordered_map<SCH_SHEET_PATH, SCH_CONNECTION*> m_connection_map;
  174. /// True if connectivity info might be out of date
  175. bool m_connectivity_dirty;
  176. public:
  177. SCH_ITEM( EDA_ITEM* aParent, KICAD_T aType );
  178. SCH_ITEM( const SCH_ITEM& aItem );
  179. ~SCH_ITEM();
  180. virtual wxString GetClass() const override
  181. {
  182. return wxT( "SCH_ITEM" );
  183. }
  184. /**
  185. * Swap the internal data structures \a aItem with the schematic item.
  186. * Obviously, aItem must have the same type than me
  187. * @param aItem The item to swap the data structures with.
  188. */
  189. virtual void SwapData( SCH_ITEM* aItem );
  190. /**
  191. * Routine to create a new copy of given item.
  192. * The new object is not put in draw list (not linked).
  193. *
  194. * @param doClone (default = false) indicates unique values (such as timestamp and
  195. * sheet name) should be duplicated. Use only for undo/redo operations.
  196. */
  197. SCH_ITEM* Duplicate( bool doClone = false ) const;
  198. /**
  199. * @return true for items which are moved with the anchor point at mouse cursor
  200. * and false for items moved with no reference to anchor
  201. * Usually return true for small items (labels, junctions) and false for
  202. * items which can be large (hierarchical sheets, compoments)
  203. */
  204. virtual bool IsMovableFromAnchorPoint() { return true; }
  205. wxPoint& GetStoredPos() { return m_storedPos; }
  206. void SetStoredPos( wxPoint aPos ) { m_storedPos = aPos; }
  207. /**
  208. * Searches the item hierarchy to find a SCHEMATIC
  209. *
  210. * Every SCH_ITEM that lives on a SCH_SCREEN should be parented to either that screen
  211. * or another SCH_ITEM on the same screen (for example, pins to their components).
  212. *
  213. * Every SCH_SCREEN should be parented to the SCHEMATIC.
  214. * Note that this hierarchy is not the same as the sheet hierarchy!
  215. *
  216. * @return the parent schematic this item lives on, or nullptr
  217. */
  218. SCHEMATIC* Schematic() const;
  219. /**
  220. * @return bool - true if the object is locked, else false
  221. */
  222. virtual bool IsLocked() const { return false; }
  223. /**
  224. * Set the 'lock' status to \a aLocked for of this item.
  225. */
  226. virtual void SetLocked( bool aLocked ) {}
  227. /**
  228. * Return the layer this item is on.
  229. */
  230. SCH_LAYER_ID GetLayer() const { return m_Layer; }
  231. /**
  232. * Set the layer this item is on.
  233. *
  234. * @param aLayer The layer number.
  235. */
  236. void SetLayer( SCH_LAYER_ID aLayer ) { m_Layer = aLayer; }
  237. /**
  238. * Return the layers the item is drawn on (which may be more than its "home" layer)
  239. */
  240. void ViewGetLayers( int aLayers[], int& aCount ) const override;
  241. /**
  242. * @return the size of the "pen" that be used to draw or plot this item
  243. */
  244. virtual int GetPenWidth() const { return 0; }
  245. /**
  246. * Print a schematic item.
  247. *
  248. * Each schematic item should have its own method
  249. *
  250. * @param aOffset drawing offset (usually {0,0} but can be different when moving an object)
  251. */
  252. virtual void Print( RENDER_SETTINGS* aSettings, const wxPoint& aOffset ) = 0;
  253. /**
  254. * Move the item by \a aMoveVector to a new position.
  255. *
  256. * @param aMoveVector = the displacement vector
  257. */
  258. virtual void Move( const wxPoint& aMoveVector ) = 0;
  259. /**
  260. * Mirror item relative to the Y axis about \a aYaxis_position.
  261. *
  262. * @param aYaxis_position The Y axis position to mirror around.
  263. */
  264. virtual void MirrorY( int aYaxis_position ) = 0;
  265. /**
  266. * Mirror item relative to the X axis about \a aXaxis_position.
  267. *
  268. * @param aXaxis_position The X axis position to mirror around.
  269. */
  270. virtual void MirrorX( int aXaxis_position ) = 0;
  271. /**
  272. * Rotate the item around \a aPosition 90 degrees in the clockwise direction.
  273. *
  274. * @param aPosition A reference to a wxPoint object containing the coordinates to
  275. * rotate around.
  276. */
  277. virtual void Rotate( wxPoint aPosition ) = 0;
  278. /**
  279. * Add the schematic item end points to \a aItemList if the item has end points.
  280. *
  281. * The default version doesn't do anything since many of the schematic object cannot
  282. * be tested for dangling ends. If you add a new schematic item that can have a
  283. * dangling end ( no connect ), override this method to provide the correct end
  284. * points.
  285. *
  286. * @param aItemList - List of DANGLING_END_ITEMS to add to.
  287. */
  288. virtual void GetEndPoints( std::vector< DANGLING_END_ITEM >& aItemList ) {}
  289. /**
  290. * Test the schematic item to \a aItemList to check if it's dangling state has changed.
  291. *
  292. * Note that the return value only true when the state of the test has changed. Use
  293. * the IsDangling() method to get the current dangling state of the item. Some of
  294. * the schematic objects cannot be tested for a dangling state, the default method
  295. * always returns false. Only override the method if the item can be tested for a
  296. * dangling state.
  297. *
  298. * If aSheet is passed a non-null pointer to a SCH_SHEET_PATH, the overrided method can
  299. * optionally use it to update sheet-local connectivity information
  300. *
  301. * @param aItemList - List of items to test item against.
  302. * @param aSheet - Sheet path to update connections for
  303. * @return True if the dangling state has changed from it's current setting.
  304. */
  305. virtual bool UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList,
  306. const SCH_SHEET_PATH* aPath = nullptr )
  307. {
  308. return false;
  309. }
  310. virtual bool IsDangling() const { return false; }
  311. virtual bool CanConnect( const SCH_ITEM* aItem ) const { return m_Layer == aItem->GetLayer(); }
  312. /**
  313. * @return true if the schematic item can connect to another schematic item.
  314. */
  315. virtual bool IsConnectable() const { return false; }
  316. /**
  317. * @return true if the given point can start drawing (usually means the anchor is unused/free/dangling)
  318. */
  319. virtual bool IsPointClickableAnchor( const wxPoint& aPos ) const { return false; }
  320. /**
  321. * Add all the connection points for this item to \a aPoints.
  322. *
  323. * Not all schematic items have connection points so the default method does nothing.
  324. *
  325. * @param aPoints List of connection points to add to.
  326. */
  327. virtual std::vector<wxPoint> GetConnectionPoints() const { return {}; }
  328. /**
  329. * Clears all of the connection items from the list.
  330. *
  331. * The vector release method is used to prevent the item pointers from being deleted.
  332. * Do not use the vector erase method on the connection list.
  333. */
  334. void ClearConnections() { m_connections.clear(); }
  335. /**
  336. * Test the item to see if it is connected to \a aPoint.
  337. *
  338. * @param aPoint A reference to a wxPoint object containing the coordinates to test.
  339. * @return True if connection to \a aPoint exists.
  340. */
  341. bool IsConnected( const wxPoint& aPoint ) const;
  342. /**
  343. * Retrieve the connection associated with this object in the given sheet
  344. *
  345. * @note The returned value can be nullptr.
  346. */
  347. SCH_CONNECTION* Connection( const SCH_SHEET_PATH* aSheet = nullptr ) const;
  348. /**
  349. * Retrieves the set of items connected to this item on the given sheet
  350. */
  351. SCH_ITEM_SET& ConnectedItems( const SCH_SHEET_PATH& aPath );
  352. /**
  353. * Adds a connection link between this item and another
  354. */
  355. void AddConnectionTo( const SCH_SHEET_PATH& aPath, SCH_ITEM* aItem );
  356. /**
  357. * Creates a new connection object associated with this object
  358. *
  359. * @param aPath is the sheet path to initialize
  360. */
  361. SCH_CONNECTION* InitializeConnection( const SCH_SHEET_PATH& aPath, CONNECTION_GRAPH* aGraph );
  362. /**
  363. * Returns true if this item should propagate connection info to aItem
  364. */
  365. virtual bool ConnectionPropagatesTo( const EDA_ITEM* aItem ) const { return true; }
  366. bool IsConnectivityDirty() { return m_connectivity_dirty; }
  367. void SetConnectivityDirty( bool aDirty = true ) { m_connectivity_dirty = aDirty; }
  368. NETCLASSPTR NetClass( const SCH_SHEET_PATH* aSheet = nullptr ) const;
  369. /**
  370. * Return whether the fields have been automatically placed.
  371. */
  372. FIELDS_AUTOPLACED GetFieldsAutoplaced() const { return m_fieldsAutoplaced; }
  373. /**
  374. * Set fields automatically placed flag false.
  375. */
  376. void ClearFieldsAutoplaced() { m_fieldsAutoplaced = FIELDS_AUTOPLACED_NO; }
  377. /**
  378. * Autoplace fields only if correct to do so automatically.
  379. *
  380. * Fields that have been moved by hand are not automatically placed.
  381. *
  382. * @param aScreen is the SCH_SCREEN associated with the current instance of the
  383. * component.
  384. */
  385. void AutoAutoplaceFields( SCH_SCREEN* aScreen )
  386. {
  387. if( GetFieldsAutoplaced() )
  388. AutoplaceFields( aScreen, GetFieldsAutoplaced() == FIELDS_AUTOPLACED_MANUAL );
  389. }
  390. virtual void AutoplaceFields( SCH_SCREEN* aScreen, bool aManual ) { }
  391. /**
  392. * Check if this schematic item has line stoke properties.
  393. *
  394. * @see #STROKE_PARAMS
  395. *
  396. * @return true if this schematic item support line stroke properties. Otherwise, false.
  397. */
  398. virtual bool HasLineStroke() const { return false; }
  399. virtual STROKE_PARAMS GetStroke() const { wxCHECK( false, STROKE_PARAMS() ); }
  400. virtual void SetStroke( const STROKE_PARAMS& aStroke ) { wxCHECK( false, /* void */ ); }
  401. /**
  402. * Plot the schematic item to \a aPlotter.
  403. *
  404. * @param aPlotter A pointer to a #PLOTTER object.
  405. */
  406. virtual void Plot( PLOTTER* aPlotter );
  407. virtual bool operator <( const SCH_ITEM& aItem ) const;
  408. private:
  409. /**
  410. * Provide the object specific test to see if it is connected to \a aPosition.
  411. *
  412. * @note Override this function if the derived object can be connect to another
  413. * object such as a wire, bus, or junction. Do not override this function
  414. * for objects that cannot have connections. The default will always return
  415. * false. This functions is call through the public function IsConnected()
  416. * which performs tests common to all schematic items before calling the
  417. * item specific connection testing.
  418. *
  419. * @param aPosition A reference to a wxPoint object containing the test position.
  420. * @return True if connection to \a aPosition exists.
  421. */
  422. virtual bool doIsConnected( const wxPoint& aPosition ) const { return false; }
  423. };
  424. #endif /* SCH_ITEM_H */