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.

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