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.

475 lines
18 KiB

  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) 2011 Wayne Stambaugh <stambaughw@verizon.net>
  6. * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version 2
  11. * of the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, you may find one here:
  20. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  21. * or you may search the http://www.gnu.org website for the version 2 license,
  22. * or you may write to the Free Software Foundation, Inc.,
  23. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  24. */
  25. /**
  26. * @file sch_sheet_path.h
  27. * @brief Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
  28. */
  29. #ifndef CLASS_DRAWSHEET_PATH_H
  30. #define CLASS_DRAWSHEET_PATH_H
  31. #include <base_struct.h>
  32. /** Info about complex hierarchies handling:
  33. * A hierarchical schematic uses sheets (hierarchical sheets) included in a
  34. * given sheet. Each sheet corresponds to a schematic drawing handled by a
  35. * SCH_SCREEN structure. A SCH_SCREEN structure contains drawings, and have
  36. * a filename to write it's data. Also a SCH_SCREEN display a sheet number
  37. * and the name of the sheet.
  38. *
  39. * In simple (and flat) hierarchies a sheet is linked to a SCH_SCREEN,
  40. * and a SCH_SCREEN is used by only one hierarchical sheet.
  41. *
  42. * In complex hierarchies the same SCH_SCREEN (and its data) is shared between
  43. * more than one sheet. Therefore subsheets (like subsheets in a SCH_SCREEN
  44. * shared by many sheets) can be also shared. So the same SCH_SCREEN must
  45. * handle different components references and parts selection depending on
  46. * which sheet is currently selected, and how a given subsheet is selected.
  47. * 2 sheets share the same SCH_SCREEN (the same drawings) if they have the
  48. * same filename.
  49. *
  50. * In KiCad each component and sheet receives (when created) an unique
  51. * identification called Time Stamp. So each sheet has 2 ids: its time stamp
  52. * (that cannot change) and its name ( that can be edited and therefore is
  53. * not reliable for strong identification). KiCad uses Time Stamp ( a unique
  54. * 32 bit id), to identify sheets in hierarchies.
  55. * A given sheet in a hierarchy is fully labeled by its path (or sheet path)
  56. * that is the list of time stamp found to access it through the hierarchy
  57. * the root sheet is /. All other sheets have a path like /1234ABCD or
  58. * /4567FEDC/AA2233DD/. This path can be displayed as human readable sheet
  59. * name like: / or /sheet1/include_sheet/ or /sheet2/include_sheet/
  60. *
  61. * So to know for a given SCH_SCREEN (a given schematic drawings) we must:
  62. * 1) Handle all references possibilities.
  63. * 2) When acceded by a given selected sheet, display (update) the
  64. * corresponding references and sheet path
  65. *
  66. * The class SCH_SHEET_PATH handles paths used to access a sheet. The class
  67. * SCH_SHEET_LIST allows to handle the full (or partial) list of sheets and
  68. * their paths in a complex hierarchy. The class EDA_ScreenList allow to
  69. * handle the list of SCH_SCREEN. It is useful to clear or save data,
  70. * but is not suitable to handle the full complex hierarchy possibilities
  71. * (usable in flat and simple hierarchies).
  72. */
  73. class wxFindReplaceData;
  74. class SCH_SCREEN;
  75. class SCH_MARKER;
  76. class SCH_SHEET;
  77. class SCH_ITEM;
  78. class SCH_REFERENCE_LIST;
  79. class PART_LIBS;
  80. /**
  81. * Class SCH_SHEET_PATH
  82. * handles access to a sheet by way of a path.
  83. * <p>
  84. * The member m_sheets stores the list of sheets from the first (usually
  85. * g_RootSheet) to a given sheet in last position.
  86. * The _last_ sheet is usually the sheet we want to select or reach (which is
  87. * what the function Last() returns).
  88. * Others sheets constitute the "path" from the first to the last sheet.
  89. * </p>
  90. */
  91. class SCH_SHEET_PATH
  92. {
  93. #define DSLSZ 32 // Max number of levels for a sheet path
  94. SCH_SHEET* m_sheets[ DSLSZ ];
  95. unsigned m_numSheets;
  96. public:
  97. SCH_SHEET_PATH();
  98. void Clear()
  99. {
  100. m_numSheets = 0;
  101. }
  102. unsigned GetSheetsCount()
  103. {
  104. return m_numSheets;
  105. }
  106. /**
  107. * Function Cmp
  108. * Compare if this is the same sheet path as aSheetPathToTest
  109. * @param aSheetPathToTest = sheet path to compare
  110. * @return -1 if different, 0 if same
  111. */
  112. int Cmp( const SCH_SHEET_PATH& aSheetPathToTest ) const;
  113. /**
  114. * Function Last
  115. * returns a pointer to the last sheet of the list
  116. * One can see the others sheet as the "path" to reach this last sheet
  117. */
  118. SCH_SHEET* Last() const;
  119. /**
  120. * Function LastScreen
  121. * @return the SCH_SCREEN relative to the last sheet in list
  122. */
  123. SCH_SCREEN* LastScreen() const;
  124. /**
  125. * Function LastDrawList
  126. * @return a pointer to the first schematic item handled by the
  127. * SCH_SCREEN relative to the last sheet in list
  128. */
  129. SCH_ITEM* LastDrawList() const;
  130. /**
  131. * Get the last schematic item relative to the first sheet in the list.
  132. *
  133. * @return Last schematic item relative to the first sheet in the list if list
  134. * is not empty. Otherwise NULL.
  135. */
  136. SCH_ITEM* FirstDrawList() const;
  137. /**
  138. * Function Push
  139. * store (push) aSheet in list
  140. * @param aSheet = pointer to the SCH_SHEET to store in list
  141. * Push is used when entered a sheet to select or analyze it
  142. * This is like cd &ltdirectory&gt in directories navigation
  143. */
  144. void Push( SCH_SHEET* aSheet );
  145. /**
  146. * Function Pop
  147. * retrieves (pop) the last entered sheet and remove it from list
  148. * @return a SCH_SHEET* pointer to the removed sheet in list
  149. * Pop is used when leaving a sheet after a selection or analyze
  150. * This is like cd .. in directories navigation
  151. */
  152. SCH_SHEET* Pop();
  153. /**
  154. * Function Path
  155. * the path uses the time stamps which do not changes even when editing
  156. * sheet parameters
  157. * a path is something like / (root) or /34005677 or /34005677/00AE4523
  158. */
  159. wxString Path() const;
  160. /**
  161. * Function PathHumanReadable
  162. * returns the sheet path in a human readable form, i.e. as a path made
  163. * from sheet names. The the "normal" path instead uses the time
  164. * stamps in the path. (Time stamps do not change even when editing
  165. * sheet parameters).
  166. */
  167. wxString PathHumanReadable() const;
  168. /**
  169. * Function BuildSheetPathInfoFromSheetPathValue
  170. * Fill this with data to access to the hierarchical sheet known by its path \a aPath
  171. * @param aPath = path of the sheet to reach (in non human readable format)
  172. * @param aFound - Please document me.
  173. * @return true if success else false
  174. */
  175. bool BuildSheetPathInfoFromSheetPathValue( const wxString& aPath, bool aFound = false );
  176. /**
  177. * Function UpdateAllScreenReferences
  178. * updates the reference and the m_Multi parameter (part selection) for all
  179. * components on a screen depending on the actual sheet path.
  180. * Mandatory in complex hierarchies because sheets use the same screen
  181. * (basic schematic)
  182. * but with different references and part selections according to the
  183. * displayed sheet
  184. */
  185. void UpdateAllScreenReferences();
  186. /**
  187. * Function AnnotatePowerSymbols
  188. * annotates the power symbols only starting at \a aReference in the sheet path.
  189. * @param aLibs the library list to use
  190. * @param aReference A pointer to the number for the reference designator of the
  191. * first power symbol to be annotated. If the pointer is NULL
  192. * the annotation starts at 1. The number is incremented for
  193. * each power symbol annotated.
  194. */
  195. void AnnotatePowerSymbols( PART_LIBS* aLibs, int* aReference );
  196. /**
  197. * Function GetComponents
  198. * adds a SCH_REFERENCE() object to \a aReferences for each component in the sheet.
  199. * @param aLibs the library list to use
  200. * @param aReferences List of references to populate.
  201. * @param aIncludePowerSymbols : false to only get normal components.
  202. */
  203. void GetComponents( PART_LIBS* aLibs, SCH_REFERENCE_LIST& aReferences,
  204. bool aIncludePowerSymbols = true );
  205. /**
  206. * Function SetFootprintField
  207. * searches last sheet in the path for a component with \a aReference and set the footprint
  208. * field to \a aFootPrint if found.
  209. *
  210. * @param aReference The reference designator of the component.
  211. * @param aFootPrint The value to set the footprint field.
  212. * @param aSetVisible The value to set the field visibility flag.
  213. * @return True if \a aReference was found otherwise false.
  214. */
  215. bool SetComponentFootprint( const wxString& aReference, const wxString& aFootPrint,
  216. bool aSetVisible );
  217. /**
  218. * Find the next schematic item in this sheet object.
  219. *
  220. * @param aType - The type of schematic item object to search for.
  221. * @param aLastItem - Start search from aLastItem. If no aLastItem, search from
  222. * the beginning of the list.
  223. * @param aWrap - Wrap around the end of the list to find the next item if aLastItem
  224. * is defined.
  225. * @return - The next schematic item if found. Otherwise, NULL is returned.
  226. */
  227. SCH_ITEM* FindNextItem( KICAD_T aType, SCH_ITEM* aLastItem = NULL, bool aWrap = false ) const;
  228. /**
  229. * Find the previous schematic item in this sheet path object.
  230. *
  231. * @param aType - The type of schematic item object to search for.
  232. * @param aLastItem - Start search from aLastItem. If no aLastItem, search from
  233. * the end of the list.
  234. * @param aWrap - Wrap around the beginning of the list to find the next item if aLastItem
  235. * is defined.
  236. * @return - The previous schematic item if found. Otherwise, NULL is returned.
  237. */
  238. SCH_ITEM* FindPreviousItem( KICAD_T aType, SCH_ITEM* aLastItem = NULL, bool aWrap = false ) const;
  239. SCH_SHEET_PATH& operator=( const SCH_SHEET_PATH& d1 );
  240. bool operator==( const SCH_SHEET_PATH& d1 ) const;
  241. bool operator!=( const SCH_SHEET_PATH& d1 ) const { return !( *this == d1 ) ; }
  242. };
  243. /**
  244. * Class SCH_SHEET_LIST
  245. * handles the list of Sheets in a hierarchy.
  246. * Sheets are not unique, there can be many sheets with the same
  247. * filename and the same SCH_SCREEN reference.
  248. * The schematic (SCH_SCREEN) is shared between these sheets,
  249. * and component references are specific to a sheet path.
  250. * When a sheet is entered, component references and sheet number are updated.
  251. */
  252. class SCH_SHEET_LIST
  253. {
  254. private:
  255. SCH_SHEET_PATH* m_List;
  256. int m_count; /* Number of sheets included in hierarchy,
  257. * starting at the given sheet in constructor .
  258. * the given sheet is counted
  259. */
  260. int m_index; /* internal variable to handle GetNext(): cleared by
  261. * GetFirst() and incremented by GetNext() after
  262. * returning the next item in m_List. Also used for
  263. * internal calculations in BuildSheetList()
  264. */
  265. bool m_isRootSheet;
  266. SCH_SHEET_PATH m_currList;
  267. public:
  268. /**
  269. * Constructor
  270. * builds the list of sheets from aSheet.
  271. * If aSheet == NULL (default) build the whole list of sheets in hierarchy.
  272. * So usually call it with no parameter.
  273. */
  274. SCH_SHEET_LIST( SCH_SHEET* aSheet = NULL );
  275. ~SCH_SHEET_LIST()
  276. {
  277. if( m_List )
  278. delete[] m_List;
  279. m_List = NULL;
  280. }
  281. /**
  282. * Function GetCount
  283. * @return the number of sheets in list:
  284. * usually the number of sheets found in the whole hierarchy
  285. */
  286. int GetCount() const { return m_count; }
  287. /**
  288. * Function GetFirst
  289. * @return the first item (sheet) in m_List and prepare calls to GetNext()
  290. */
  291. SCH_SHEET_PATH* GetFirst();
  292. /**
  293. * Function GetNext
  294. * @return the next item (sheet) in m_List or NULL if no more item in
  295. * sheet list
  296. */
  297. SCH_SHEET_PATH* GetNext();
  298. /**
  299. * Function GetLast
  300. * returns the last sheet in the sheet list.
  301. *
  302. * @return Last sheet in the list or NULL if sheet list is empty.
  303. */
  304. SCH_SHEET_PATH* GetLast();
  305. /**
  306. * Function GetPrevious
  307. * returns the previous sheet in the sheet list.
  308. *
  309. * @return The previous sheet in the sheet list or NULL if already at the
  310. * beginning of the list.
  311. */
  312. SCH_SHEET_PATH* GetPrevious();
  313. /**
  314. * Function GetSheet
  315. *
  316. * @param aIndex A index in sheet list to get the sheet.
  317. * @return the sheet at \a aIndex position in m_List or NULL if \a aIndex is
  318. * outside the bounds of the index list.
  319. */
  320. SCH_SHEET_PATH* GetSheet( int aIndex );
  321. /**
  322. * Function GetSheet
  323. * returns a sheet matching the path name in \a aPath.
  324. *
  325. * @param aPath A wxString object containing path of the sheet to get.
  326. * @param aHumanReadable True uses the human readable path for comparison.
  327. * False uses the timestamp generated path.
  328. * @return The sheet that matches \a aPath or NULL if no sheet matching
  329. * \a aPath is found.
  330. */
  331. SCH_SHEET_PATH* GetSheet( const wxString aPath, bool aHumanReadable = true );
  332. /**
  333. * Function IsModified
  334. * checks the entire hierarchy for any modifications.
  335. * @returns True if the hierarchy is modified otherwise false.
  336. */
  337. bool IsModified();
  338. /**
  339. * Function IsAutoSaveRequired
  340. * checks the entire hierarchy for any modifications that require auto save.
  341. * @return True if the hierarchy is modified otherwise false.
  342. */
  343. bool IsAutoSaveRequired();
  344. void ClearModifyStatus();
  345. /**
  346. * Function AnnotatePowerSymbols
  347. * clear and annotates the entire hierarchy of the sheet path list.
  348. * @param aLib the library list to use
  349. */
  350. void AnnotatePowerSymbols( PART_LIBS* aLib );
  351. /**
  352. * Function GetComponents
  353. * adds a SCH_REFERENCE() object to \a aReferences for each component in the list
  354. * of sheets.
  355. * @param aLibs the library list to use
  356. * @param aReferences List of references to populate.
  357. * @param aIncludePowerSymbols Set to false to only get normal components.
  358. */
  359. void GetComponents( PART_LIBS* aLibs, SCH_REFERENCE_LIST& aReferences, bool aIncludePowerSymbols = true );
  360. /**
  361. * Function FindNextItem
  362. * searches the entire schematic for the next schematic object.
  363. *
  364. * @param aType - The type of schematic item to find.
  365. * @param aSheetFound - The sheet the item was found in. NULL if the next item
  366. * is not found.
  367. * @param aLastItem - Find next item after aLastItem if not NULL.
  368. * @param aWrap - Wrap past around the end of the list of sheets.
  369. * @return If found, Returns the next schematic item. Otherwise, returns NULL.
  370. */
  371. SCH_ITEM* FindNextItem( KICAD_T aType, SCH_SHEET_PATH** aSheetFound = NULL,
  372. SCH_ITEM* aLastItem = NULL, bool aWrap = true );
  373. /**
  374. * Function FindPreviousItem
  375. * searches the entire schematic for the previous schematic item.
  376. *
  377. * @param aType - The type of schematic item to find.
  378. * @param aSheetFound - The sheet the item was found in. NULL if the previous item
  379. * is not found.
  380. * @param aLastItem - Find the previous item before aLastItem if not NULL.
  381. * @param aWrap - Wrap past around the beginning of the list of sheets.
  382. * @return If found, the previous schematic item. Otherwise, NULL.
  383. */
  384. SCH_ITEM* FindPreviousItem( KICAD_T aType, SCH_SHEET_PATH** aSheetFound = NULL,
  385. SCH_ITEM* aLastItem = NULL, bool aWrap = true );
  386. /**
  387. * Function SetFootprintField
  388. * searches all the sheets for a component with \a aReference and set the footprint
  389. * field to \a aFootPrint if found.
  390. *
  391. * @param aReference The reference designator of the component.
  392. * @param aFootPrint The value to set the footprint field.
  393. * @param aSetVisible The value to set the field visibility flag.
  394. * @return True if \a aReference was found otherwise false.
  395. */
  396. bool SetComponentFootprint( const wxString& aReference, const wxString& aFootPrint,
  397. bool aSetVisible );
  398. /**
  399. * Function IsComplexHierarchy
  400. * searches all of the sheets for duplicate files names which indicates a complex
  401. * hierarchy.
  402. *
  403. * @return true if the #SCH_SHEET_LIST is a complex hierarchy.
  404. */
  405. bool IsComplexHierarchy();
  406. private:
  407. /**
  408. * Function BuildSheetList
  409. * builds the list of sheets and their sheet path from \a aSheet.
  410. * If \a aSheet is the root sheet, the full sheet path and sheet list are built.
  411. *
  412. * @param aSheet is the starting sheet from which the list is built, or NULL
  413. * indicating that g_RootSheet should be used.
  414. * @throw std::bad_alloc if the memory for the sheet path list could not be allocated.
  415. */
  416. void BuildSheetList( SCH_SHEET* aSheet );
  417. };
  418. #endif // CLASS_DRAWSHEET_PATH_H