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.

387 lines
11 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2015 Chris Pavlina <pavlina.chris@gmail.com>
  5. * Copyright (C) 2015-2022 KiCad Developers, see change_log.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. #ifndef _LIB_CACHE_RESCUE_H_
  25. #define _LIB_CACHE_RESCUE_H_
  26. /* This code handles the case where an old schematic was made before
  27. * various changes were made, either to KiCad or to the libraries, and
  28. * the project needs to be recovered. The function of note is a member
  29. * of SCH_EDIT_FRAME, defined thus:
  30. *
  31. * bool SCH_EDIT_FRAME::RescueProject( bool aSilentIfNone );
  32. *
  33. * When this is called, a list of problematic symbols is compiled. If
  34. * this list is empty, then the function displays a notification and returns
  35. * (if aSilentIfNone is true, the notification is silenced).
  36. */
  37. #include <vector>
  38. #include <wx/string.h>
  39. #include <boost/ptr_container/ptr_vector.hpp>
  40. #include <properties.h>
  41. #include <lib_symbol.h>
  42. #include <sch_plugins/legacy/sch_legacy_plugin.h>
  43. #include <class_draw_panel_gal.h>
  44. class LIB_SYMBOL;
  45. class SCH_SYMBOL;
  46. class RESCUER;
  47. class SCH_EDIT_FRAME;
  48. class SCH_LEGACY_PLUGIN;
  49. class SCH_SHEET_PATH;
  50. class SCHEMATIC;
  51. enum RESCUE_TYPE
  52. {
  53. RESCUE_CONFLICT,
  54. RESCUE_CASE,
  55. };
  56. class RESCUE_CANDIDATE
  57. {
  58. public:
  59. virtual ~RESCUE_CANDIDATE() {}
  60. /**
  61. * Get the name that was originally requested in the schematic
  62. */
  63. virtual wxString GetRequestedName() const { return m_requested_name; }
  64. /**
  65. * Get the name we're proposing changing it to
  66. */
  67. virtual wxString GetNewName() const { return m_new_name; }
  68. /**
  69. * Get the part that can be loaded from the project cache, if possible, or
  70. * else NULL.
  71. */
  72. virtual LIB_SYMBOL* GetCacheCandidate() const { return nullptr; }
  73. /**
  74. * Get the part the would be loaded from the libraries, if possible, or else
  75. * NULL.
  76. */
  77. virtual LIB_SYMBOL* GetLibCandidate() const { return m_lib_candidate; }
  78. int GetUnit() const { return m_unit; }
  79. int GetConvert() const { return m_convert; }
  80. /**
  81. * Get a description of the action proposed, for displaying in the UI.
  82. */
  83. virtual wxString GetActionDescription() const = 0;
  84. /**
  85. * Perform the actual rescue action. If successful, this must log the rescue using
  86. * RESCUER::LogRescue to allow it to be reversed.
  87. * @return True on success.
  88. */
  89. virtual bool PerformAction( RESCUER* aRescuer ) = 0;
  90. protected:
  91. wxString m_requested_name;
  92. wxString m_new_name;
  93. LIB_SYMBOL* m_lib_candidate;
  94. int m_unit;
  95. int m_convert;
  96. };
  97. class RESCUE_CASE_CANDIDATE : public RESCUE_CANDIDATE
  98. {
  99. public:
  100. /**
  101. * Grab all possible RESCUE_CASE_CANDIDATE objects into a vector.
  102. *
  103. * @param aRescuer is the working RESCUER instance.
  104. * @param aCandidates is the vector the will hold the candidates.
  105. */
  106. static void FindRescues( RESCUER& aRescuer, boost::ptr_vector<RESCUE_CANDIDATE>& aCandidates );
  107. /**
  108. * Create a RESCUE_CANDIDATE.
  109. *
  110. * @param aRequestedName us the name the schematic asks for.
  111. * @param aNewName is the name we want to change it to.
  112. * @param aLibCandidate is the part that will give us.
  113. * @param aUnit is the unit of the rescued symbol.
  114. * @param aConvert is the body style of the rescued symbol.
  115. */
  116. RESCUE_CASE_CANDIDATE( const wxString& aRequestedName, const wxString& aNewName,
  117. LIB_SYMBOL* aLibCandidate, int aUnit = 0, int aConvert = 0 );
  118. RESCUE_CASE_CANDIDATE() { m_lib_candidate = nullptr; }
  119. virtual wxString GetActionDescription() const override;
  120. virtual bool PerformAction( RESCUER* aRescuer ) override;
  121. };
  122. class RESCUE_CACHE_CANDIDATE: public RESCUE_CANDIDATE
  123. {
  124. LIB_SYMBOL* m_cache_candidate;
  125. public:
  126. /**
  127. * Grab all possible #RESCUE_CACHE_CANDIDATE objects into a vector.
  128. *
  129. * @param aRescuer is the working RESCUER instance.
  130. * @param aCandidates is the vector the will hold the candidates.
  131. */
  132. static void FindRescues( RESCUER& aRescuer, boost::ptr_vector<RESCUE_CANDIDATE>& aCandidates );
  133. /**
  134. * Create a RESCUE_CACHE_CANDIDATE.
  135. *
  136. * @param aRequestedName is the name the schematic asks for.
  137. * @param aNewName is the name we want to change it to.
  138. * @param aCacheCandidate is the part from the cache.
  139. * @param aLibCandidate is the part that would be loaded from the library.
  140. * @param aUnit is the unit of the rescued symbol.
  141. * @param aConvert is the body style of the rescued symbol.
  142. */
  143. RESCUE_CACHE_CANDIDATE( const wxString& aRequestedName, const wxString& aNewName,
  144. LIB_SYMBOL* aCacheCandidate, LIB_SYMBOL* aLibCandidate,
  145. int aUnit = 0, int aConvert = 0 );
  146. RESCUE_CACHE_CANDIDATE();
  147. virtual LIB_SYMBOL* GetCacheCandidate() const override { return m_cache_candidate; }
  148. virtual wxString GetActionDescription() const override;
  149. virtual bool PerformAction( RESCUER* aRescuer ) override;
  150. };
  151. class RESCUE_SYMBOL_LIB_TABLE_CANDIDATE : public RESCUE_CANDIDATE
  152. {
  153. public:
  154. /**
  155. * Grab all possible RESCUE_SYMBOL_LIB_TABLE_CANDIDATE objects into a vector.
  156. *
  157. * @param aRescuer is the working #RESCUER instance.
  158. * @param aCandidates is the vector the will hold the candidates.
  159. */
  160. static void FindRescues( RESCUER& aRescuer, boost::ptr_vector<RESCUE_CANDIDATE>& aCandidates );
  161. /**
  162. * Create RESCUE_CANDIDATE.
  163. *
  164. * @param aRequestedName is the name the schematic asks for.
  165. * @param aNewName is the name we want to change it to.
  166. * @param aCacheCandidate is the part from the cache.
  167. * @param aLibCandidate is the part that would be loaded from the library.
  168. * @param aUnit is the unit of the rescued symbol.
  169. * @param aConvert is the body style of the rescued symbol.
  170. */
  171. RESCUE_SYMBOL_LIB_TABLE_CANDIDATE( const LIB_ID& aRequestedId, const LIB_ID& aNewId,
  172. LIB_SYMBOL* aCacheCandidate, LIB_SYMBOL* aLibCandidate,
  173. int aUnit = 0, int aConvert = 0 );
  174. RESCUE_SYMBOL_LIB_TABLE_CANDIDATE();
  175. virtual LIB_SYMBOL* GetCacheCandidate() const override { return m_cache_candidate; }
  176. virtual wxString GetActionDescription() const override;
  177. virtual bool PerformAction( RESCUER* aRescuer ) override;
  178. private:
  179. LIB_ID m_requested_id;
  180. LIB_ID m_new_id;
  181. LIB_SYMBOL* m_cache_candidate;
  182. };
  183. class RESCUE_LOG
  184. {
  185. public:
  186. SCH_SYMBOL* symbol;
  187. wxString old_name;
  188. wxString new_name;
  189. };
  190. class RESCUER
  191. {
  192. public:
  193. RESCUER( PROJECT& aProject, SCHEMATIC* aSchematic, SCH_SHEET_PATH* aCurrentSheet,
  194. EDA_DRAW_PANEL_GAL::GAL_TYPE aGalBackeEndType );
  195. virtual ~RESCUER()
  196. {
  197. }
  198. /**
  199. * Write the rescue library.
  200. *
  201. * Called after successful PerformAction()s. If this fails, undo the actions.
  202. *
  203. * @return True on success.
  204. */
  205. virtual bool WriteRescueLibrary( wxWindow *aParent ) = 0;
  206. virtual void OpenRescueLibrary() = 0;
  207. /**
  208. * Populate the RESCUER with all possible candidates.
  209. */
  210. virtual void FindCandidates() = 0;
  211. virtual void AddSymbol( LIB_SYMBOL* aNewSymbol ) = 0;
  212. /**
  213. * Display a dialog to allow the user to select rescues.
  214. *
  215. * @param aAskShowAgain - whether the "Never Show Again" button should be visible
  216. */
  217. virtual void InvokeDialog( wxWindow* aParent, bool aAskShowAgain ) = 0;
  218. /**
  219. * Filter out duplicately named rescue candidates.
  220. */
  221. void RemoveDuplicates();
  222. /**
  223. * Return the number of rescue candidates found.
  224. */
  225. size_t GetCandidateCount() { return m_all_candidates.size(); }
  226. /**
  227. * Get the number of rescue candidates chosen by the user.
  228. */
  229. size_t GetChosenCandidateCount() { return m_chosen_candidates.size(); }
  230. /**
  231. * Get the list of symbols that need rescued.
  232. */
  233. std::vector<SCH_SYMBOL*>* GetSymbols() { return &m_symbols; }
  234. /**
  235. * Return the #SCH_PROJECT object for access to the symbol libraries.
  236. */
  237. PROJECT* GetPrj() { return m_prj; }
  238. SCHEMATIC* Schematic() { return m_schematic; }
  239. /**
  240. * Used by individual #RESCUE_CANDIDATE objects to log a rescue for undoing.
  241. */
  242. void LogRescue( SCH_SYMBOL *aSymbol, const wxString& aOldName, const wxString& aNewName );
  243. /**
  244. * Perform all chosen rescue actions, logging them to be undone if necessary.
  245. *
  246. * @return True on success
  247. */
  248. bool DoRescues();
  249. /**
  250. * Reverse the effects of all rescues on the project.
  251. */
  252. void UndoRescues();
  253. static bool RescueProject( wxWindow* aParent, RESCUER& aRescuer, bool aRunningOnDemand );
  254. protected:
  255. friend class DIALOG_RESCUE_EACH;
  256. std::vector<SCH_SYMBOL*> m_symbols;
  257. PROJECT* m_prj;
  258. SCHEMATIC* m_schematic;
  259. EDA_DRAW_PANEL_GAL::GAL_TYPE m_galBackEndType;
  260. SCH_SHEET_PATH* m_currentSheet;
  261. boost::ptr_vector<RESCUE_CANDIDATE> m_all_candidates;
  262. std::vector<RESCUE_CANDIDATE*> m_chosen_candidates;
  263. std::vector<RESCUE_LOG> m_rescue_log;
  264. };
  265. class LEGACY_RESCUER : public RESCUER
  266. {
  267. public:
  268. LEGACY_RESCUER( PROJECT& aProject, SCHEMATIC* aSchematic, SCH_SHEET_PATH* aCurrentSheet,
  269. EDA_DRAW_PANEL_GAL::GAL_TYPE aGalBackEndType ) :
  270. RESCUER( aProject, aSchematic, aCurrentSheet, aGalBackEndType )
  271. {
  272. }
  273. virtual ~LEGACY_RESCUER()
  274. {
  275. }
  276. virtual void FindCandidates() override;
  277. virtual void InvokeDialog( wxWindow* aParent, bool aAskShowAgain ) override;
  278. virtual void OpenRescueLibrary() override;
  279. virtual bool WriteRescueLibrary( wxWindow *aParent ) override;
  280. virtual void AddSymbol( LIB_SYMBOL* aNewSymbol ) override;
  281. private:
  282. std::unique_ptr<SYMBOL_LIB> m_rescue_lib;
  283. };
  284. class SYMBOL_LIB_TABLE_RESCUER : public RESCUER
  285. {
  286. public:
  287. SYMBOL_LIB_TABLE_RESCUER( PROJECT& aProject, SCHEMATIC* aSchematic,
  288. SCH_SHEET_PATH* aCurrentSheet,
  289. EDA_DRAW_PANEL_GAL::GAL_TYPE aGalBackeEndType );
  290. virtual ~SYMBOL_LIB_TABLE_RESCUER()
  291. {
  292. }
  293. virtual void FindCandidates() override;
  294. virtual void InvokeDialog( wxWindow* aParent, bool aAskShowAgain ) override;
  295. virtual void OpenRescueLibrary() override;
  296. virtual bool WriteRescueLibrary( wxWindow* aParent ) override;
  297. virtual void AddSymbol( LIB_SYMBOL* aNewSymbol ) override;
  298. private:
  299. std::vector<std::unique_ptr<LIB_SYMBOL>> m_rescueLibSymbols;
  300. std::unique_ptr< PROPERTIES > m_properties; ///< Library plugin properties.
  301. };
  302. #endif // _LIB_CACHE_RESCUE_H_