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.

587 lines
19 KiB

11 years ago
11 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
  5. * Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
  6. * Copyright (C) 2004-2023 KiCad Developers, see AUTHORS.txt for contributors.
  7. * Copyright (C) 2017 CERN
  8. * @author Maciej Suminski <maciej.suminski@cern.ch>
  9. *
  10. * This program is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU General Public License
  12. * as published by the Free Software Foundation; either version 2
  13. * of the License, or (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, you may find one here:
  22. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  23. * or you may search the http://www.gnu.org website for the version 2 license,
  24. * or you may write to the Free Software Foundation, Inc.,
  25. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  26. */
  27. #ifndef SYMBOL_EDIT_FRAME_H
  28. #define SYMBOL_EDIT_FRAME_H
  29. #include <sch_base_frame.h>
  30. #include <sch_screen.h>
  31. #include <lib_item.h>
  32. #include <ee_collectors.h>
  33. #include <optional>
  34. class SCH_EDIT_FRAME;
  35. class SYMBOL_LIB_TABLE;
  36. class LIB_SYMBOL;
  37. class LIB_FIELD;
  38. class DIALOG_LIB_TEXT_PROPERTIES;
  39. class SYMBOL_TREE_PANE;
  40. class LIB_TREE_NODE;
  41. class LIB_ID;
  42. class LIB_SYMBOL_LIBRARY_MANAGER;
  43. class SYMBOL_EDITOR_SETTINGS;
  44. class EDA_LIST_DIALOG;
  45. /**
  46. * The symbol library editor main window.
  47. */
  48. class SYMBOL_EDIT_FRAME : public SCH_BASE_FRAME
  49. {
  50. public:
  51. SYMBOL_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent );
  52. ~SYMBOL_EDIT_FRAME() override;
  53. /**
  54. * Switch currently used canvas ( Cairo / OpenGL).
  55. */
  56. void SwitchCanvas( EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvasType ) override;
  57. /**
  58. * Get if any symbols or libraries have been modified but not saved.
  59. *
  60. * @return true if the any changes have not been saved
  61. */
  62. bool IsContentModified() const override;
  63. /**
  64. * Check if any pending libraries have been modified.
  65. *
  66. * This only checks for modified libraries. If a new symbol was created and modified
  67. * and no libraries have been modified, the return value will be false.
  68. *
  69. * @return True if there are any pending library modifications.
  70. */
  71. bool HasLibModifications() const;
  72. bool CanCloseSymbolFromSchematic( bool doClose );
  73. /**
  74. * The nickname of the current library being edited and empty string if none.
  75. */
  76. wxString GetCurLib() const;
  77. /**
  78. * Set the current library nickname and returns the old library nickname.
  79. */
  80. wxString SetCurLib( const wxString& aLibNickname );
  81. LIB_TREE_NODE* GetCurrentTreeNode() const;
  82. /**
  83. * Return the LIB_ID of the library or symbol selected in the symbol tree.
  84. */
  85. LIB_ID GetTreeLIBID( int* aUnit = nullptr ) const;
  86. int GetTreeSelectionCount() const;
  87. int GetTreeLIBIDs( std::vector<LIB_ID>& aSelection ) const;
  88. /**
  89. * Return the current symbol being edited or NULL if none selected.
  90. *
  91. * This is a LIB_SYMBOL that I own, it is at best a copy of one in a library.
  92. */
  93. LIB_SYMBOL* GetCurSymbol() const { return m_symbol; }
  94. /**
  95. * Take ownership of aSymbol and notes that it is the one currently being edited.
  96. */
  97. void SetCurSymbol( LIB_SYMBOL* aSymbol, bool aUpdateZoom );
  98. LIB_SYMBOL_LIBRARY_MANAGER& GetLibManager();
  99. SELECTION& GetCurrentSelection() override;
  100. // See comments for m_SyncPinEdit.
  101. bool SynchronizePins();
  102. /**
  103. * Create or add an existing library to the symbol library table.
  104. */
  105. wxString AddLibraryFile( bool aCreateNew );
  106. /**
  107. * Add a library dropped file to the symbol library table.
  108. */
  109. void DdAddLibrary( wxString aLibFile );
  110. /**
  111. * Create a new symbol in the selected library.
  112. *
  113. * @param newName is the name of the symbol to derive the new symbol from or empty
  114. * to create a new root symbol.
  115. */
  116. void CreateNewSymbol( const wxString& newName = wxEmptyString );
  117. void ImportSymbol();
  118. void ExportSymbol();
  119. /**
  120. * Save the selected symbol or library.
  121. */
  122. void Save();
  123. /**
  124. * Save the currently selected symbol to a new name and/or location.
  125. */
  126. void SaveSymbolAs();
  127. /**
  128. * Save the currently selected library to a new file.
  129. */
  130. void SaveLibraryAs();
  131. /**
  132. * Save all modified symbols and libraries.
  133. */
  134. void SaveAll();
  135. /**
  136. * Revert unsaved changes in a symbol, restoring to the last saved state.
  137. */
  138. void Revert( bool aConfirm = true );
  139. void RevertAll();
  140. void DeleteSymbolFromLibrary();
  141. void CopySymbolToClipboard();
  142. void LoadSymbol( const wxString& aLibrary, const wxString& aSymbol, int Unit );
  143. /**
  144. * Insert a duplicate symbol.
  145. *
  146. * If \a aFromClipboard is true then action is a paste.
  147. */
  148. void DuplicateSymbol( bool aFromClipboard );
  149. void OnSelectUnit( wxCommandEvent& event );
  150. void OnToggleSymbolTree( wxCommandEvent& event );
  151. void ToggleProperties() override;
  152. bool IsSymbolTreeShown() const;
  153. void FreezeLibraryTree();
  154. void ThawLibraryTree();
  155. void OnUpdateUnitNumber( wxUpdateUIEvent& event );
  156. void UpdateAfterSymbolProperties( wxString* aOldName = nullptr );
  157. void RebuildSymbolUnitsList();
  158. bool canCloseWindow( wxCloseEvent& aCloseEvent ) override;
  159. void doCloseWindow() override;
  160. void OnExitKiCad( wxCommandEvent& event );
  161. void ReCreateHToolbar() override;
  162. void ReCreateVToolbar() override;
  163. void ReCreateOptToolbar() override;
  164. void LoadSettings( APP_SETTINGS_BASE* aCfg ) override;
  165. void SaveSettings( APP_SETTINGS_BASE* aCfg ) override;
  166. SYMBOL_EDITOR_SETTINGS* GetSettings() const
  167. {
  168. return m_settings;
  169. }
  170. APP_SETTINGS_BASE* config() const override;
  171. COLOR_SETTINGS* GetColorSettings( bool aForceRefresh = false ) const override;
  172. /**
  173. * Trigger the wxCloseEvent, which is handled by the function given to EVT_CLOSE() macro:
  174. * <p>
  175. * EVT_CLOSE( SYMBOL_EDIT_FRAME::OnCloseWindow )
  176. * </p>
  177. */
  178. void CloseWindow( wxCommandEvent& event )
  179. {
  180. // Generate a wxCloseEvent
  181. Close( false );
  182. }
  183. /**
  184. * Must be called after a schematic change in order to set the "modify" flag of the
  185. * current symbol.
  186. */
  187. void OnModify() override;
  188. int GetUnit() const { return m_unit; }
  189. void SetUnit( int aUnit ) { m_unit = aUnit; }
  190. int GetConvert() const { return m_convert; }
  191. void SetConvert( int aConvert ) { m_convert = aConvert; }
  192. bool GetShowDeMorgan() const { return m_showDeMorgan; }
  193. void SetShowDeMorgan( bool show ) { m_showDeMorgan = show; }
  194. void ClearMsgPanel() override
  195. {
  196. UpdateSymbolMsgPanelInfo();
  197. }
  198. void UpdateMsgPanel() override
  199. {
  200. UpdateSymbolMsgPanelInfo();
  201. }
  202. /**
  203. * Update the main window title bar with the current library name and read only status
  204. * of the library.
  205. */
  206. void UpdateTitle();
  207. bool IsSymbolFromSchematic() const
  208. {
  209. // If we've already vetted closing this window, then we have no symbol anymore
  210. if( m_isClosing )
  211. return false;
  212. return m_isSymbolFromSchematic;
  213. }
  214. bool IsSymbolFromLegacyLibrary() const;
  215. /**
  216. * Display the documentation of the selected symbol.
  217. */
  218. void UpdateSymbolMsgPanelInfo();
  219. // General editing
  220. /**
  221. * Create a copy of the current symbol, and save it in the undo list.
  222. *
  223. * Because a symbol in library editor does not have a lot of primitives, the full data is
  224. * duplicated. It is not worth to try to optimize this save function.
  225. */
  226. void SaveCopyInUndoList( const wxString& aDescription, EDA_ITEM* aItem,
  227. UNDO_REDO aUndoType = UNDO_REDO::LIBEDIT );
  228. void GetSymbolFromUndoList();
  229. void GetSymbolFromRedoList();
  230. /**
  231. * Free the undo or redo list from \a aList element.
  232. *
  233. * - Wrappers are deleted.
  234. * - data pointed by wrappers are deleted if not in use in schematic
  235. * i.e. when they are copy of a schematic item or they are no more in use (DELETED)
  236. *
  237. * @param whichList = the UNDO_REDO_CONTAINER to clear
  238. * @param aItemCount = the count of items to remove. < 0 for all items
  239. * items are removed from the beginning of the list.
  240. * So this function can be called to remove old commands
  241. */
  242. void ClearUndoORRedoList( UNDO_REDO_LIST whichList, int aItemCount = -1 ) override;
  243. /**
  244. * Select the currently active library and loads the symbol from \a aLibId.
  245. *
  246. * @param aLibId is the #LIB_ID of the symbol to select.
  247. * @param aUnit the unit to show
  248. * @param aConvert the DeMorgan variant to show
  249. * @return true if the symbol defined by \a aLibId was loaded.
  250. */
  251. bool LoadSymbol( const LIB_ID& aLibId, int aUnit, int aConvert );
  252. /**
  253. * Print a page.
  254. */
  255. void PrintPage( const RENDER_SETTINGS* aSettings ) override;
  256. /**
  257. * Create the SVG print file for the current edited symbol.
  258. * @param aFullFileName is the full filename
  259. * @param aOffset is a plot offset, in iu
  260. */
  261. void SVGPlotSymbol( const wxString& aFullFileName, VECTOR2I aOffset );
  262. /**
  263. * Synchronize the library manager to the symbol library table, and then the symbol tree
  264. * to the library manager. Optionally displays a progress dialog.
  265. */
  266. void SyncLibraries( bool aShowProgress, bool aPreloadCancelled = false,
  267. const wxString& aForceRefresh = wxEmptyString );
  268. /**
  269. * Filter, sort, and redisplay the library tree.
  270. *
  271. * Does NOT synchronize it with libraries in disk.
  272. */
  273. void RegenerateLibraryTree();
  274. /**
  275. * Redisplay the library tree. Used after changing modified states, descriptions, etc.
  276. */
  277. void RefreshLibraryTree();
  278. /**
  279. * Update a symbol node in the library tree.
  280. */
  281. void UpdateLibraryTree( const wxDataViewItem& aTreeItem, LIB_SYMBOL* aSymbol );
  282. /**
  283. * Return either the symbol selected in the symbol tree (if context menu is active) or the
  284. * symbol on the editor canvas.
  285. */
  286. LIB_ID GetTargetLibId() const;
  287. /**
  288. * @return a list of selected items in the symbol tree
  289. */
  290. std::vector<LIB_ID> GetSelectedLibIds() const;
  291. void FocusOnLibId( const LIB_ID& aLibID );
  292. /**
  293. * Called after the preferences dialog is run.
  294. */
  295. void CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVarsChanged ) override;
  296. void ShowChangedLanguage() override;
  297. void SetScreen( BASE_SCREEN* aScreen ) override;
  298. const BOX2I GetDocumentExtents( bool aIncludeAllVisible = true ) const override;
  299. void RebuildView();
  300. void UpdateItem( EDA_ITEM* aItem, bool isAddOrDelete = false,
  301. bool aUpdateRtree = false ) override;
  302. /**
  303. * Rebuild the GAL and redraw the screen. Call when something went wrong.
  304. */
  305. void HardRedraw() override;
  306. void KiwayMailIn( KIWAY_EXPRESS& mail ) override;
  307. void FocusOnItem( LIB_ITEM* aItem );
  308. /**
  309. * Load a symbol from the schematic to edit in place.
  310. *
  311. * @param aSymbol the symbol to edit.
  312. */
  313. void LoadSymbolFromSchematic( SCH_SYMBOL* aSymbol );
  314. /**
  315. * Test if a symbol is loaded and can be edited.
  316. *
  317. * The following conditions are required for a symbol to be editable:
  318. * - The symbol must selected from either a library or the schematic.
  319. * - The symbol must not be from a legacy library.
  320. *
  321. * Note that many things are not editable in a non-root symbol (ie: an alias), but others
  322. * are so this routine no longer returns false for an alias.
  323. */
  324. bool IsSymbolEditable() const;
  325. bool IsSymbolAlias() const;
  326. ///< Return true if \a aLibId is an alias for the editor screen symbol.
  327. bool IsCurrentSymbol( const LIB_ID& aLibId ) const;
  328. ///< Restore the empty editor screen, without any symbol or library selected.
  329. void emptyScreen();
  330. protected:
  331. void setupUIConditions() override;
  332. void doReCreateMenuBar() override;
  333. private:
  334. // Set up the tool framework
  335. void setupTools();
  336. void saveSymbolAs();
  337. /**
  338. * Save the changes to the current library.
  339. *
  340. * A backup file of the current library is saved with the .bak extension before the
  341. * changes made to the library are saved.
  342. *
  343. * @param aLibrary is the library name.
  344. * @param aNewFile Ask for a new file name to save the library.
  345. * @return True if the library was successfully saved.
  346. */
  347. bool saveLibrary( const wxString& aLibrary, bool aNewFile );
  348. /**
  349. * Set the current active library to \a aLibrary.
  350. *
  351. * @param aLibrary the nickname of the library in the symbol library table. If empty,
  352. * display list of available libraries to select from.
  353. */
  354. void SelectActiveLibrary( const wxString& aLibrary = wxEmptyString );
  355. /**
  356. * Load a symbol from the current active library, optionally setting the selected unit
  357. * and convert.
  358. *
  359. * @param aAliasName The symbol alias name to load from the current library.
  360. * @param aUnit Unit to be selected
  361. * @param aConvert Convert to be selected
  362. * @return true if the symbol loaded correctly.
  363. */
  364. bool LoadSymbolFromCurrentLib( const wxString& aAliasName, int aUnit = 0, int aConvert = 0 );
  365. /**
  366. * Create a copy of \a aLibEntry into memory.
  367. *
  368. * @param aLibEntry A pointer to the LIB_SYMBOL object to an already loaded symbol.
  369. * @param aLibrary the path to the library file that \a aLibEntry was loaded from. This is
  370. * for error messaging purposes only.
  371. * @param aUnit the initial unit to show.
  372. * @param aConvert the initial DeMorgan variant to show.
  373. * @return True if a copy of \a aLibEntry was successfully copied.
  374. */
  375. bool LoadOneLibrarySymbolAux( LIB_SYMBOL* aLibEntry, const wxString& aLibrary, int aUnit,
  376. int aConvert );
  377. ///< Create a backup copy of a file with requested extension.
  378. bool backupFile( const wxFileName& aOriginalFile, const wxString& aBackupExt );
  379. ///< Return currently edited symbol.
  380. LIB_SYMBOL* getTargetSymbol() const;
  381. ///< Return either the library selected in the symbol tree, if context menu is active or
  382. ///< the library that is currently modified.
  383. wxString getTargetLib() const;
  384. void centerItemIdleHandler( wxIdleEvent& aEvent );
  385. /*
  386. * Return true when the operation has succeeded (all requested libraries have been saved
  387. * or none was selected and confirmed by OK).
  388. *
  389. * @param aRequireConfirmation when true, the user must be asked to confirm.
  390. */
  391. bool saveAllLibraries( bool aRequireConfirmation );
  392. ///< Save the current symbol.
  393. bool saveCurrentSymbol();
  394. ///< Store the currently modified symbol in the library manager buffer.
  395. void storeCurrentSymbol();
  396. ///< Rename LIB_SYMBOL aliases to avoid conflicts before adding a symbol to a library.
  397. void ensureUniqueName( LIB_SYMBOL* aSymbol, const wxString& aLibrary );
  398. enum TABLE_SCOPE
  399. {
  400. GLOBAL_LIB_TABLE,
  401. PROJECT_LIB_TABLE
  402. };
  403. /**
  404. * Add \a aLibFile to the symbol library table defined by \a aScope.
  405. *
  406. * @note The library defined by \a aLibFile must be a KiCad (s-expression) library.
  407. *
  408. * @param aLibFile is the full path and file name of the symbol library to add to the table.
  409. * @param aScope defines if \a aLibFile is added to the global or project library table.
  410. * @return true if successful or false if a failure occurs.
  411. */
  412. bool addLibTableEntry( const wxString& aLibFile, TABLE_SCOPE aScope = GLOBAL_LIB_TABLE );
  413. /**
  414. * Replace the file path of the symbol library table entry \a aLibNickname with \a aLibFile.
  415. *
  416. * @note The library defined by \a aLibFile must be a KiCad (s-expression) library.
  417. *
  418. * @param aLibNickmane is the nickname of an existing library table entry.
  419. * @param aLibFile is the full path and file name of the symbol library to replace in the
  420. * table.
  421. * @return true if successful or false if a failure occurs.
  422. */
  423. bool replaceLibTableEntry( const wxString& aLibNickname, const wxString& aLibFile );
  424. DECLARE_EVENT_TABLE()
  425. public:
  426. /**
  427. * Set to true to synchronize pins at the same position when editing symbols with multiple
  428. * units or multiple body styles. Deleting or moving pins will affect all pins at the same
  429. * location.
  430. * When units are interchangeable, synchronizing editing of pins is usually the best way,
  431. * because if units are interchangeable, it implies that all similar pins are at the same
  432. * location.
  433. * When units are not interchangeable, do not synchronize editing of pins, because each symbol
  434. * is specific, and there are no (or few) similar pins between units.
  435. *
  436. * Setting this to false allows editing each pin per symbol or body style regardless other
  437. * pins at the same location. This requires the user to open each symbol or body style to make
  438. * changes to the other pins at the same location.
  439. *
  440. * To know if others pins must be coupled when editing a pin, use SynchronizePins() instead
  441. * of m_syncPinEdit, because SynchronizePins() is more reliable (takes in account the fact
  442. * units are interchangeable, there are more than one unit).
  443. *
  444. * @todo Determine why this member variable is public when all the rest are private and
  445. * either make it private or document why it needs to be public.
  446. */
  447. bool m_SyncPinEdit;
  448. private:
  449. ///< Helper screen used when no symbol is loaded
  450. SCH_SCREEN* m_dummyScreen;
  451. LIB_SYMBOL* m_symbol; // a symbol I own, it is not in any library, but a
  452. // copy could be.
  453. wxComboBox* m_unitSelectBox; // a ComboBox to select a unit to edit (if the
  454. // symbol has multiple units)
  455. SYMBOL_TREE_PANE* m_treePane; // symbol search tree widget
  456. LIB_SYMBOL_LIBRARY_MANAGER* m_libMgr; // manager taking care of temporary modifications
  457. SYMBOL_EDITOR_SETTINGS* m_settings; // Handle to the settings
  458. LIB_ID m_centerItemOnIdle;
  459. // The unit number to edit and show
  460. int m_unit;
  461. // Show the normal shape ( m_convert <= 1 ) or the converted shape ( m_convert > 1 )
  462. int m_convert;
  463. ///< Flag if the symbol being edited was loaded directly from a schematic.
  464. bool m_isSymbolFromSchematic;
  465. KIID m_schematicSymbolUUID;
  466. ///< RefDes of the symbol (only valid if symbol was loaded from schematic)
  467. wxString m_reference;
  468. // True to force DeMorgan/normal tools selection enabled.
  469. // They are enabled when the loaded symbol has graphic items for converted shape
  470. // But under some circumstances (New symbol created) these tools must left enabled
  471. static bool m_showDeMorgan;
  472. };
  473. #endif // SYMBOL_EDIT_FRAME_H