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.

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