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.

576 lines
18 KiB

17 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) 1992-2019 KiCad Developers, see AUTHORS.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. /**
  25. * @file sch_sheet.h
  26. * @brief Definition of the SCH_SHEET class for Eeschema.
  27. */
  28. #ifndef SCH_SHEEET_H
  29. #define SCH_SHEEET_H
  30. #include <boost/ptr_container/ptr_vector.hpp>
  31. #include <sch_text.h>
  32. class LINE_READER;
  33. class SCH_SCREEN;
  34. class SCH_SHEET;
  35. class SCH_SHEET_PIN;
  36. class SCH_SHEET_PATH;
  37. class DANGLING_END_ITEM;
  38. class SCH_EDIT_FRAME;
  39. class NETLIST_OBJECT_LIST;
  40. #define MIN_SHEET_WIDTH 500
  41. #define MIN_SHEET_HEIGHT 150
  42. /**
  43. * Define a sheet pin (label) used in sheets to create hierarchical schematics.
  44. *
  45. * A SCH_SHEET_PIN is used to create a hierarchical sheet in the same way a
  46. * pin is used in a component. It connects the objects in the sheet object
  47. * to the objects in the schematic page to the objects in the page that is
  48. * represented by the sheet. In a sheet object, a SCH_SHEET_PIN must be
  49. * connected to a wire, bus, or label. In the schematic page represented by
  50. * the sheet, it corresponds to a hierarchical label.
  51. */
  52. class SCH_SHEET_PIN : public SCH_HIERLABEL
  53. {
  54. public:
  55. /**
  56. * Defines the edge of the sheet that the sheet pin is positioned
  57. * SHEET_LEFT_SIDE = 0: pin on left side
  58. * SHEET_RIGHT_SIDE = 1: pin on right side
  59. * SHEET_TOP_SIDE = 2: pin on top side
  60. * SHEET_BOTTOM_SIDE =3: pin on bottom side
  61. *
  62. * For compatibility reasons, this does not follow same values as text orientation.
  63. */
  64. enum SHEET_SIDE
  65. {
  66. SHEET_LEFT_SIDE = 0,
  67. SHEET_RIGHT_SIDE,
  68. SHEET_TOP_SIDE,
  69. SHEET_BOTTOM_SIDE,
  70. SHEET_UNDEFINED_SIDE
  71. };
  72. private:
  73. int m_number; ///< Label number use for saving sheet label to file.
  74. ///< Sheet label numbering begins at 2.
  75. ///< 0 is reserved for the sheet name.
  76. ///< 1 is reserve for the sheet file name.
  77. SHEET_SIDE m_edge;
  78. public:
  79. SCH_SHEET_PIN( SCH_SHEET* parent,
  80. const wxPoint& pos = wxPoint( 0, 0 ),
  81. const wxString& text = wxEmptyString );
  82. // Do not create a copy constructor. The one generated by the compiler is adequate.
  83. ~SCH_SHEET_PIN() { }
  84. wxString GetClass() const override
  85. {
  86. return wxT( "SCH_SHEET_PIN" );
  87. }
  88. bool operator ==( const SCH_SHEET_PIN* aPin ) const;
  89. /**
  90. * Return true for items which are moved with the anchor point at mouse cursor
  91. * and false for items moved with no reference to anchor (usually large items)
  92. *
  93. * @return true for a hierarchical sheet pin
  94. */
  95. bool IsMovableFromAnchorPoint() override { return true; }
  96. void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset ) override;
  97. /**
  98. * Calculate the graphic shape (a polygon) associated to the text.
  99. *
  100. * @param aPoints = a buffer to fill with polygon corners coordinates
  101. * @param aPos = Position of the shape
  102. */
  103. void CreateGraphicShape( std::vector <wxPoint>& aPoints, const wxPoint& aPos ) override;
  104. void SwapData( SCH_ITEM* aItem ) override;
  105. int GetPenSize() const override;
  106. /**
  107. * Get the sheet label number.
  108. *
  109. * @return Number of the sheet label.
  110. */
  111. int GetNumber() const { return m_number; }
  112. /**
  113. * Set the sheet label number.
  114. *
  115. * @param aNumber - New sheet number label.
  116. */
  117. void SetNumber( int aNumber );
  118. void SetEdge( SHEET_SIDE aEdge );
  119. SHEET_SIDE GetEdge() const;
  120. /**
  121. * Adjust label position to edge based on proximity to vertical or horizontal edge
  122. * of the parent sheet.
  123. */
  124. void ConstrainOnEdge( wxPoint Pos );
  125. /**
  126. * Get the parent sheet object of this sheet pin.
  127. *
  128. * @return The sheet that is the parent of this sheet pin or NULL if it does
  129. * not have a parent.
  130. */
  131. SCH_SHEET* GetParent() const { return (SCH_SHEET*) m_Parent; }
  132. #if defined(DEBUG)
  133. void Show( int nestLevel, std::ostream& os ) const override;
  134. #endif
  135. // Geometric transforms (used in block operations):
  136. void Move( const wxPoint& aMoveVector ) override
  137. {
  138. Offset( aMoveVector );
  139. }
  140. void MirrorY( int aYaxis_position ) override;
  141. void Rotate( wxPoint aPosition ) override;
  142. void MirrorX( int aXaxis_position ) override;
  143. bool Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation ) override;
  144. bool Replace( wxFindReplaceData& aSearchData, void* aAuxData = NULL ) override
  145. {
  146. return EDA_ITEM::Replace( aSearchData, m_Text );
  147. }
  148. bool IsReplaceable() const override { return true; }
  149. void GetEndPoints( std::vector< DANGLING_END_ITEM >& aItemList ) override;
  150. bool IsConnectable() const override { return true; }
  151. wxString GetSelectMenuText( EDA_UNITS_T aUnits ) const override;
  152. BITMAP_DEF GetMenuImage() const override;
  153. void SetPosition( const wxPoint& aPosition ) override { ConstrainOnEdge( aPosition ); }
  154. bool HitTest( const wxPoint& aPosition, int aAccuracy ) const override;
  155. EDA_ITEM* Clone() const override;
  156. };
  157. typedef boost::ptr_vector<SCH_SHEET_PIN> SCH_SHEET_PINS;
  158. /**
  159. * Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
  160. */
  161. class SCH_SHEET : public SCH_ITEM
  162. {
  163. friend class SCH_SHEET_PIN;
  164. /// Screen that contains the physical data for the sheet. In complex hierarchies
  165. /// multiple sheets can share a common screen.
  166. SCH_SCREEN* m_screen;
  167. /// The list of sheet connection points.
  168. SCH_SHEET_PINS m_pins;
  169. /// The file name is also in the #SCH_SCREEN object associated with the sheet. It is
  170. /// also needed here for loading after reading the sheet description from file.
  171. wxString m_fileName;
  172. /// This is equivalent to the reference designator for components and is stored in F0
  173. /// sheet pin in the schematic file.
  174. wxString m_name;
  175. /// The height of the text used to draw the sheet name.
  176. int m_sheetNameSize;
  177. /// The height of the text used to draw the file name.
  178. int m_fileNameSize;
  179. /// The position of the sheet.
  180. wxPoint m_pos;
  181. /// The size of the sheet.
  182. wxSize m_size;
  183. public:
  184. SCH_SHEET( const wxPoint& pos = wxPoint( 0, 0 ) );
  185. /**
  186. * Copy \a aSheet into a new object. All sheet pins are copied as is except and
  187. * the SCH_SHEET_PIN's #m_Parent pointers are set to the new copied parent object.
  188. */
  189. SCH_SHEET( const SCH_SHEET& aSheet );
  190. ~SCH_SHEET();
  191. wxString GetClass() const override
  192. {
  193. return wxT( "SCH_SHEET" );
  194. }
  195. /**
  196. * Return true for items which are moved with the anchor point at mouse cursor
  197. * and false for items moved with no reference to anchor.
  198. *
  199. * Usually return true for small items (labels, junctions) and false for
  200. * items which can be large (hierarchical sheets, compoments)
  201. *
  202. * @return false for a hierarchical sheet
  203. */
  204. bool IsMovableFromAnchorPoint() override { return false; }
  205. wxString GetName() const { return m_name; }
  206. void SetName( const wxString& aName ) { m_name = aName; }
  207. int GetSheetNameSize() const { return m_sheetNameSize; }
  208. void SetSheetNameSize( int aSize ) { m_sheetNameSize = aSize; }
  209. int GetFileNameSize() const { return m_fileNameSize; }
  210. void SetFileNameSize( int aSize ) { m_fileNameSize = aSize; }
  211. SCH_SCREEN* GetScreen() { return m_screen; }
  212. wxSize GetSize() { return m_size; }
  213. void SetSize( const wxSize& aSize ) { m_size = aSize; }
  214. /**
  215. * Return the root sheet of this SCH_SHEET object.
  216. *
  217. * The root (top level) sheet can be found by walking up the parent links until the only
  218. * sheet that has no parent is found. The root sheet can be found from any sheet without
  219. * having to maintain a global root sheet pointer.
  220. *
  221. * @return a SCH_SHEET pointer to the root sheet.
  222. */
  223. SCH_SHEET* GetRootSheet();
  224. /**
  225. * Set the #SCH_SCREEN associated with this sheet to \a aScreen.
  226. *
  227. * The screen reference counting is performed by SetScreen. If \a aScreen is not
  228. * the same as the current screen, the current screen reference count is decremented
  229. * and \a aScreen becomes the screen for the sheet. If the current screen reference
  230. * count reaches zero, the current screen is deleted. NULL is a valid value for
  231. * \a aScreen.
  232. *
  233. * @param aScreen The new screen to associate with the sheet.
  234. */
  235. void SetScreen( SCH_SCREEN* aScreen );
  236. /**
  237. * Return the number of times the associated screen for the sheet is being used.
  238. *
  239. * If no screen is associated with the sheet, then zero is returned.
  240. */
  241. int GetScreenCount() const;
  242. void GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& aList ) override;
  243. /* there is no member for orientation in sch_sheet, to preserve file
  244. * format, we detect orientation based on pin edges
  245. */
  246. bool IsVerticalOrientation() const;
  247. /**
  248. * Add aSheetPin to the sheet.
  249. *
  250. * Note: Once a sheet pin is added to the sheet, it is owned by the sheet.
  251. * Do not delete the sheet pin object or you will likely get a segfault
  252. * when the sheet is destroyed.
  253. *
  254. * @param aSheetPin The sheet pin item to add to the sheet.
  255. */
  256. void AddPin( SCH_SHEET_PIN* aSheetPin );
  257. SCH_SHEET_PINS& GetPins() { return m_pins; }
  258. SCH_SHEET_PINS& GetPins() const
  259. {
  260. return const_cast< SCH_SHEET_PINS& >( m_pins );
  261. }
  262. /**
  263. * Remove \a aSheetPin from the sheet.
  264. *
  265. * @param aSheetPin The sheet pin item to remove from the sheet.
  266. */
  267. void RemovePin( SCH_SHEET_PIN* aSheetPin );
  268. /**
  269. * Delete sheet label which do not have a corresponding hierarchical label.
  270. *
  271. * Note: Make sure you save a copy of the sheet in the undo list before calling
  272. * CleanupSheet() otherwise any unreferenced sheet labels will be lost.
  273. */
  274. void CleanupSheet();
  275. /**
  276. * Return the sheet pin item found at \a aPosition in the sheet.
  277. *
  278. * @param aPosition The position to check for a sheet pin.
  279. *
  280. * @return The sheet pin found at \a aPosition or NULL if no sheet pin is found.
  281. */
  282. SCH_SHEET_PIN* GetPin( const wxPoint& aPosition );
  283. /**
  284. * Checks if the sheet already has a sheet pin named \a aName.
  285. *
  286. * @param aName Name of the sheet pin to search for.
  287. *
  288. * @return True if sheet pin with \a aName is found, otherwise false.
  289. */
  290. bool HasPin( const wxString& aName );
  291. bool HasPins() { return !m_pins.empty(); }
  292. /**
  293. * Check all sheet labels against schematic for undefined hierarchical labels.
  294. *
  295. * @return True if there are any undefined labels.
  296. */
  297. bool HasUndefinedPins();
  298. /**
  299. * Return the minimum width of the sheet based on the widths of the sheet pin text.
  300. *
  301. * The minimum sheet width is determined by the width of the bounding box of each
  302. * hierarchical sheet pin. If two pins are horizontally adjacent ( same Y position )
  303. * to each other, the sum of the bounding box widths is used. If at some point in
  304. * the future sheet objects can be rotated or pins can be placed in the vertical
  305. * orientation, this function will need to be changed.
  306. *
  307. * @return The minimum width the sheet can be resized.
  308. */
  309. int GetMinWidth() const;
  310. /**
  311. * Return the minimum height that the sheet can be resized based on the sheet pin positions.
  312. *
  313. * The minimum width of a sheet is determined by the Y axis location of the bottom
  314. * most sheet pin. If at some point in the future sheet objects can be rotated or
  315. * pins can be placed in the vertical orientation, this function will need to be
  316. * changed.
  317. *
  318. * @return The minimum height the sheet can be resized.
  319. */
  320. int GetMinHeight() const;
  321. int GetPenSize() const override;
  322. void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset ) override;
  323. EDA_RECT const GetBoundingBox() const override;
  324. /**
  325. * Return the position of the lower right corner of the sheet in drawing units.
  326. *
  327. * @return A wxPoint containing lower right corner of the sheet in drawing units.
  328. */
  329. wxPoint GetResizePosition() const;
  330. void SwapData( SCH_ITEM* aItem ) override;
  331. /**
  332. * Count our own components, without the power components.
  333. *
  334. * @return the component count.
  335. */
  336. int ComponentCount();
  337. /**
  338. * Search the existing hierarchy for an instance of screen loaded from \a aFileName.
  339. *
  340. * @param aFilename = the filename to find
  341. * @param aScreen = a location to return a pointer to the screen (if found)
  342. * @return bool if found, and a pointer to the screen
  343. */
  344. bool SearchHierarchy( const wxString& aFilename, SCH_SCREEN** aScreen );
  345. /**
  346. * Search the existing hierarchy for an instance of screen loaded from \a aFileName.
  347. *
  348. * Don't bother looking at the root sheet, it must be unique. No other references to
  349. * its m_screen otherwise there would be loops in the hierarchy.
  350. *
  351. * @param aScreen = the SCH_SCREEN* screen that we search for
  352. * @param aList = the SCH_SHEET_PATH* that must be used
  353. * @return true if found
  354. */
  355. bool LocatePathOfScreen( SCH_SCREEN* aScreen, SCH_SHEET_PATH* aList );
  356. /**
  357. * Count the number of sheets found in "this" sheet includeing all of the subsheets.
  358. *
  359. * @return the full count of sheets+subsheets contained by "this"
  360. */
  361. int CountSheets();
  362. /**
  363. * Return the filename corresponding to this sheet.
  364. *
  365. * @return a wxString containing the filename
  366. */
  367. wxString GetFileName( void ) const;
  368. // Set a new filename without changing anything else
  369. void SetFileName( const wxString& aFilename )
  370. {
  371. m_fileName = aFilename;
  372. // Filenames are stored using unix notation
  373. m_fileName.Replace( wxT("\\"), wxT("/") );
  374. }
  375. bool ChangeFileName( SCH_EDIT_FRAME* aFrame, const wxString& aFileName );
  376. // Geometric transforms (used in block operations):
  377. void Move( const wxPoint& aMoveVector ) override
  378. {
  379. m_pos += aMoveVector;
  380. for( SCH_SHEET_PIN& pin : m_pins )
  381. {
  382. pin.Move( aMoveVector );
  383. }
  384. }
  385. void MirrorY( int aYaxis_position ) override;
  386. void MirrorX( int aXaxis_position ) override;
  387. void Rotate( wxPoint aPosition ) override;
  388. bool Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation ) override;
  389. bool Replace( wxFindReplaceData& aSearchData, void* aAuxData = NULL ) override;
  390. bool IsReplaceable() const override { return true; }
  391. /**
  392. * Resize this sheet to aSize and adjust all of the labels accordingly.
  393. *
  394. * @param aSize - The new size for this sheet.
  395. */
  396. void Resize( const wxSize& aSize );
  397. /**
  398. * @return the position of the anchor of sheet name text
  399. */
  400. wxPoint GetSheetNamePosition();
  401. /**
  402. * @return the position of the anchor of filename text
  403. */
  404. wxPoint GetFileNamePosition();
  405. void GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList ) override;
  406. bool UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList ) override;
  407. bool IsSelectStateChanged( const wxRect& aRect ) override;
  408. bool IsConnectable() const override { return true; }
  409. bool CanConnect( const SCH_ITEM* aItem ) const override
  410. {
  411. return ( aItem->Type() == SCH_LINE_T && aItem->GetLayer() == LAYER_WIRE ) ||
  412. ( aItem->Type() == SCH_LINE_T && aItem->GetLayer() == LAYER_BUS ) ||
  413. ( aItem->Type() == SCH_NO_CONNECT_T );
  414. }
  415. void GetConnectionPoints( std::vector< wxPoint >& aPoints ) const override;
  416. SEARCH_RESULT Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] ) override;
  417. wxString GetSelectMenuText( EDA_UNITS_T aUnits ) const override;
  418. BITMAP_DEF GetMenuImage() const override;
  419. void GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems,
  420. SCH_SHEET_PATH* aSheetPath ) override;
  421. SCH_ITEM& operator=( const SCH_ITEM& aSheet );
  422. void ViewGetLayers( int aLayers[], int& aCount ) const override;
  423. wxPoint GetPosition() const override { return m_pos; }
  424. void SetPosition( const wxPoint& aPosition ) override;
  425. bool HitTest( const wxPoint& aPosition, int aAccuracy ) const override;
  426. bool HitTest( const EDA_RECT& aRect, bool aContained = false, int aAccuracy = 0 ) const override;
  427. void Plot( PLOTTER* aPlotter ) override;
  428. EDA_ITEM* Clone() const override;
  429. #if defined(DEBUG)
  430. void Show( int nestLevel, std::ostream& os ) const override;
  431. #endif
  432. protected:
  433. /**
  434. * Renumber the sheet pins in the sheet.
  435. *
  436. * This method is used internally by SCH_SHEET to update the pin numbering
  437. * when the pin list changes. Make sure you call this method any time a
  438. * sheet pin is added or removed.
  439. */
  440. void renumberPins();
  441. };
  442. //typedef std::vector< SCH_SHEET* > SCH_SHEETS; // no ownership over contained SCH_SHEETs
  443. #endif // SCH_SHEEET_H