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.

657 lines
28 KiB

++PCBNew * Removed Pcb_Frame argument from BOARD() constructor, since it precludes having a BOARD being edited by more than one editor, it was a bad design. And this meant removing m_PcbFrame from BOARD. * removed BOARD::SetWindowFrame(), and BOARD::m_PcbFrame * Removed the global BOARD_DESIGN_SETTINGS which was in class_board.cpp * added BOARD_DESIGN_SETTINGS to the BOARD class, a full instance * a couple dialogs now only change BOARD_DESIGN_SETTINGS when OK is pressed, such as dialog_mask_clearance, dialog_drc, etc. * Removed common/pcbcommon.cpp's int g_CurrentVersionPCB = 1 and replaced it with build_version.h's #define BOARD_FILE_VERSION, although there may be a better place for this constant. * Made the public functions in PARAM_CFG_ARRAY be type const. void SaveParam(..) const and void ReadParam(..) const * PARAM_CFG_BASE now has virtual destructor since we have various way of destroying the derived class and boost::ptr_vector must be told about this. * Pass const PARAM_CFG_ARRAY& instead of PARAM_CFG_ARRAY so that we can use an automatic PARAM_CFG_ARRAY which is on the stack.\ * PCB_EDIT_FRAME::GetProjectFileParameters() may no longer cache the array, since it has to access the current BOARD and the BOARD can change. Remember BOARD_DESIGN_SETTINGS are now in the BOARD. * Made the m_BoundingBox member private, this was a brutally hard task, and indicative of the lack of commitment to accessors and object oriented design on the part of KiCad developers. We must do better. Added BOARD::GetBoundingBox, SetBoundingBox(), ComputeBoundingBox(). * Added PCB_BASE_FRAME::GetBoardBoundingBox() which calls BOARD::ComputeBoundingBox()
14 years ago
++PCBNew * Removed Pcb_Frame argument from BOARD() constructor, since it precludes having a BOARD being edited by more than one editor, it was a bad design. And this meant removing m_PcbFrame from BOARD. * removed BOARD::SetWindowFrame(), and BOARD::m_PcbFrame * Removed the global BOARD_DESIGN_SETTINGS which was in class_board.cpp * added BOARD_DESIGN_SETTINGS to the BOARD class, a full instance * a couple dialogs now only change BOARD_DESIGN_SETTINGS when OK is pressed, such as dialog_mask_clearance, dialog_drc, etc. * Removed common/pcbcommon.cpp's int g_CurrentVersionPCB = 1 and replaced it with build_version.h's #define BOARD_FILE_VERSION, although there may be a better place for this constant. * Made the public functions in PARAM_CFG_ARRAY be type const. void SaveParam(..) const and void ReadParam(..) const * PARAM_CFG_BASE now has virtual destructor since we have various way of destroying the derived class and boost::ptr_vector must be told about this. * Pass const PARAM_CFG_ARRAY& instead of PARAM_CFG_ARRAY so that we can use an automatic PARAM_CFG_ARRAY which is on the stack.\ * PCB_EDIT_FRAME::GetProjectFileParameters() may no longer cache the array, since it has to access the current BOARD and the BOARD can change. Remember BOARD_DESIGN_SETTINGS are now in the BOARD. * Made the m_BoundingBox member private, this was a brutally hard task, and indicative of the lack of commitment to accessors and object oriented design on the part of KiCad developers. We must do better. Added BOARD::GetBoundingBox, SetBoundingBox(), ComputeBoundingBox(). * Added PCB_BASE_FRAME::GetBoardBoundingBox() which calls BOARD::ComputeBoundingBox()
14 years ago
++PCBNew * Removed Pcb_Frame argument from BOARD() constructor, since it precludes having a BOARD being edited by more than one editor, it was a bad design. And this meant removing m_PcbFrame from BOARD. * removed BOARD::SetWindowFrame(), and BOARD::m_PcbFrame * Removed the global BOARD_DESIGN_SETTINGS which was in class_board.cpp * added BOARD_DESIGN_SETTINGS to the BOARD class, a full instance * a couple dialogs now only change BOARD_DESIGN_SETTINGS when OK is pressed, such as dialog_mask_clearance, dialog_drc, etc. * Removed common/pcbcommon.cpp's int g_CurrentVersionPCB = 1 and replaced it with build_version.h's #define BOARD_FILE_VERSION, although there may be a better place for this constant. * Made the public functions in PARAM_CFG_ARRAY be type const. void SaveParam(..) const and void ReadParam(..) const * PARAM_CFG_BASE now has virtual destructor since we have various way of destroying the derived class and boost::ptr_vector must be told about this. * Pass const PARAM_CFG_ARRAY& instead of PARAM_CFG_ARRAY so that we can use an automatic PARAM_CFG_ARRAY which is on the stack.\ * PCB_EDIT_FRAME::GetProjectFileParameters() may no longer cache the array, since it has to access the current BOARD and the BOARD can change. Remember BOARD_DESIGN_SETTINGS are now in the BOARD. * Made the m_BoundingBox member private, this was a brutally hard task, and indicative of the lack of commitment to accessors and object oriented design on the part of KiCad developers. We must do better. Added BOARD::GetBoundingBox, SetBoundingBox(), ComputeBoundingBox(). * Added PCB_BASE_FRAME::GetBoardBoundingBox() which calls BOARD::ComputeBoundingBox()
14 years ago
++PCBNew * Removed Pcb_Frame argument from BOARD() constructor, since it precludes having a BOARD being edited by more than one editor, it was a bad design. And this meant removing m_PcbFrame from BOARD. * removed BOARD::SetWindowFrame(), and BOARD::m_PcbFrame * Removed the global BOARD_DESIGN_SETTINGS which was in class_board.cpp * added BOARD_DESIGN_SETTINGS to the BOARD class, a full instance * a couple dialogs now only change BOARD_DESIGN_SETTINGS when OK is pressed, such as dialog_mask_clearance, dialog_drc, etc. * Removed common/pcbcommon.cpp's int g_CurrentVersionPCB = 1 and replaced it with build_version.h's #define BOARD_FILE_VERSION, although there may be a better place for this constant. * Made the public functions in PARAM_CFG_ARRAY be type const. void SaveParam(..) const and void ReadParam(..) const * PARAM_CFG_BASE now has virtual destructor since we have various way of destroying the derived class and boost::ptr_vector must be told about this. * Pass const PARAM_CFG_ARRAY& instead of PARAM_CFG_ARRAY so that we can use an automatic PARAM_CFG_ARRAY which is on the stack.\ * PCB_EDIT_FRAME::GetProjectFileParameters() may no longer cache the array, since it has to access the current BOARD and the BOARD can change. Remember BOARD_DESIGN_SETTINGS are now in the BOARD. * Made the m_BoundingBox member private, this was a brutally hard task, and indicative of the lack of commitment to accessors and object oriented design on the part of KiCad developers. We must do better. Added BOARD::GetBoundingBox, SetBoundingBox(), ComputeBoundingBox(). * Added PCB_BASE_FRAME::GetBoardBoundingBox() which calls BOARD::ComputeBoundingBox()
14 years ago
++PCBNew * Removed Pcb_Frame argument from BOARD() constructor, since it precludes having a BOARD being edited by more than one editor, it was a bad design. And this meant removing m_PcbFrame from BOARD. * removed BOARD::SetWindowFrame(), and BOARD::m_PcbFrame * Removed the global BOARD_DESIGN_SETTINGS which was in class_board.cpp * added BOARD_DESIGN_SETTINGS to the BOARD class, a full instance * a couple dialogs now only change BOARD_DESIGN_SETTINGS when OK is pressed, such as dialog_mask_clearance, dialog_drc, etc. * Removed common/pcbcommon.cpp's int g_CurrentVersionPCB = 1 and replaced it with build_version.h's #define BOARD_FILE_VERSION, although there may be a better place for this constant. * Made the public functions in PARAM_CFG_ARRAY be type const. void SaveParam(..) const and void ReadParam(..) const * PARAM_CFG_BASE now has virtual destructor since we have various way of destroying the derived class and boost::ptr_vector must be told about this. * Pass const PARAM_CFG_ARRAY& instead of PARAM_CFG_ARRAY so that we can use an automatic PARAM_CFG_ARRAY which is on the stack.\ * PCB_EDIT_FRAME::GetProjectFileParameters() may no longer cache the array, since it has to access the current BOARD and the BOARD can change. Remember BOARD_DESIGN_SETTINGS are now in the BOARD. * Made the m_BoundingBox member private, this was a brutally hard task, and indicative of the lack of commitment to accessors and object oriented design on the part of KiCad developers. We must do better. Added BOARD::GetBoundingBox, SetBoundingBox(), ComputeBoundingBox(). * Added PCB_BASE_FRAME::GetBoardBoundingBox() which calls BOARD::ComputeBoundingBox()
14 years ago
++PCBNew * Removed Pcb_Frame argument from BOARD() constructor, since it precludes having a BOARD being edited by more than one editor, it was a bad design. And this meant removing m_PcbFrame from BOARD. * removed BOARD::SetWindowFrame(), and BOARD::m_PcbFrame * Removed the global BOARD_DESIGN_SETTINGS which was in class_board.cpp * added BOARD_DESIGN_SETTINGS to the BOARD class, a full instance * a couple dialogs now only change BOARD_DESIGN_SETTINGS when OK is pressed, such as dialog_mask_clearance, dialog_drc, etc. * Removed common/pcbcommon.cpp's int g_CurrentVersionPCB = 1 and replaced it with build_version.h's #define BOARD_FILE_VERSION, although there may be a better place for this constant. * Made the public functions in PARAM_CFG_ARRAY be type const. void SaveParam(..) const and void ReadParam(..) const * PARAM_CFG_BASE now has virtual destructor since we have various way of destroying the derived class and boost::ptr_vector must be told about this. * Pass const PARAM_CFG_ARRAY& instead of PARAM_CFG_ARRAY so that we can use an automatic PARAM_CFG_ARRAY which is on the stack.\ * PCB_EDIT_FRAME::GetProjectFileParameters() may no longer cache the array, since it has to access the current BOARD and the BOARD can change. Remember BOARD_DESIGN_SETTINGS are now in the BOARD. * Made the m_BoundingBox member private, this was a brutally hard task, and indicative of the lack of commitment to accessors and object oriented design on the part of KiCad developers. We must do better. Added BOARD::GetBoundingBox, SetBoundingBox(), ComputeBoundingBox(). * Added PCB_BASE_FRAME::GetBoardBoundingBox() which calls BOARD::ComputeBoundingBox()
14 years ago
++PCBNew * Removed Pcb_Frame argument from BOARD() constructor, since it precludes having a BOARD being edited by more than one editor, it was a bad design. And this meant removing m_PcbFrame from BOARD. * removed BOARD::SetWindowFrame(), and BOARD::m_PcbFrame * Removed the global BOARD_DESIGN_SETTINGS which was in class_board.cpp * added BOARD_DESIGN_SETTINGS to the BOARD class, a full instance * a couple dialogs now only change BOARD_DESIGN_SETTINGS when OK is pressed, such as dialog_mask_clearance, dialog_drc, etc. * Removed common/pcbcommon.cpp's int g_CurrentVersionPCB = 1 and replaced it with build_version.h's #define BOARD_FILE_VERSION, although there may be a better place for this constant. * Made the public functions in PARAM_CFG_ARRAY be type const. void SaveParam(..) const and void ReadParam(..) const * PARAM_CFG_BASE now has virtual destructor since we have various way of destroying the derived class and boost::ptr_vector must be told about this. * Pass const PARAM_CFG_ARRAY& instead of PARAM_CFG_ARRAY so that we can use an automatic PARAM_CFG_ARRAY which is on the stack.\ * PCB_EDIT_FRAME::GetProjectFileParameters() may no longer cache the array, since it has to access the current BOARD and the BOARD can change. Remember BOARD_DESIGN_SETTINGS are now in the BOARD. * Made the m_BoundingBox member private, this was a brutally hard task, and indicative of the lack of commitment to accessors and object oriented design on the part of KiCad developers. We must do better. Added BOARD::GetBoundingBox, SetBoundingBox(), ComputeBoundingBox(). * Added PCB_BASE_FRAME::GetBoardBoundingBox() which calls BOARD::ComputeBoundingBox()
14 years ago
++PCBNew * Removed Pcb_Frame argument from BOARD() constructor, since it precludes having a BOARD being edited by more than one editor, it was a bad design. And this meant removing m_PcbFrame from BOARD. * removed BOARD::SetWindowFrame(), and BOARD::m_PcbFrame * Removed the global BOARD_DESIGN_SETTINGS which was in class_board.cpp * added BOARD_DESIGN_SETTINGS to the BOARD class, a full instance * a couple dialogs now only change BOARD_DESIGN_SETTINGS when OK is pressed, such as dialog_mask_clearance, dialog_drc, etc. * Removed common/pcbcommon.cpp's int g_CurrentVersionPCB = 1 and replaced it with build_version.h's #define BOARD_FILE_VERSION, although there may be a better place for this constant. * Made the public functions in PARAM_CFG_ARRAY be type const. void SaveParam(..) const and void ReadParam(..) const * PARAM_CFG_BASE now has virtual destructor since we have various way of destroying the derived class and boost::ptr_vector must be told about this. * Pass const PARAM_CFG_ARRAY& instead of PARAM_CFG_ARRAY so that we can use an automatic PARAM_CFG_ARRAY which is on the stack.\ * PCB_EDIT_FRAME::GetProjectFileParameters() may no longer cache the array, since it has to access the current BOARD and the BOARD can change. Remember BOARD_DESIGN_SETTINGS are now in the BOARD. * Made the m_BoundingBox member private, this was a brutally hard task, and indicative of the lack of commitment to accessors and object oriented design on the part of KiCad developers. We must do better. Added BOARD::GetBoundingBox, SetBoundingBox(), ComputeBoundingBox(). * Added PCB_BASE_FRAME::GetBoardBoundingBox() which calls BOARD::ComputeBoundingBox()
14 years ago
  1. /*
  2. * This program source code file is part of KICAD, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2011-2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
  5. * Copyright (C) 2016-2023 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. #ifndef IO_MGR_H_
  25. #define IO_MGR_H_
  26. #include <cstdint>
  27. #include <config.h>
  28. #include <vector>
  29. #include <wx/arrstr.h>
  30. #include <i18n_utility.h>
  31. #include <plugin_file_desc.h>
  32. class BOARD;
  33. class PLUGIN;
  34. class FOOTPRINT;
  35. class STRING_UTF8_MAP;
  36. class PROJECT;
  37. class PROGRESS_REPORTER;
  38. /**
  39. * A factory which returns an instance of a #PLUGIN.
  40. */
  41. class IO_MGR
  42. {
  43. public:
  44. /**
  45. * The set of file types that the IO_MGR knows about, and for which there has been a
  46. * plugin written, in alphabetical order.
  47. */
  48. enum PCB_FILE_T
  49. {
  50. KICAD_SEXP, ///< S-expression Pcbnew file format.
  51. LEGACY, ///< Legacy Pcbnew file formats prior to s-expression.
  52. ALTIUM_CIRCUIT_MAKER,
  53. ALTIUM_CIRCUIT_STUDIO,
  54. ALTIUM_DESIGNER,
  55. CADSTAR_PCB_ARCHIVE,
  56. EAGLE,
  57. EASYEDA,
  58. EASYEDAPRO,
  59. FABMASTER,
  60. GEDA_PCB, ///< Geda PCB file formats.
  61. PCAD,
  62. SOLIDWORKS_PCB,
  63. // add your type here.
  64. // etc.
  65. FILE_TYPE_NONE
  66. };
  67. /**
  68. * Hold a list of available plugins, created using a singleton REGISTER_PLUGIN object.
  69. * This way, plugins can be added link-time.
  70. */
  71. class PLUGIN_REGISTRY
  72. {
  73. public:
  74. struct ENTRY
  75. {
  76. PCB_FILE_T m_type;
  77. std::function<PLUGIN*(void)> m_createFunc;
  78. wxString m_name;
  79. };
  80. static PLUGIN_REGISTRY *Instance()
  81. {
  82. static PLUGIN_REGISTRY *self = nullptr;
  83. if( !self )
  84. {
  85. self = new PLUGIN_REGISTRY;
  86. }
  87. return self;
  88. }
  89. void Register( PCB_FILE_T aType, const wxString& aName,
  90. std::function<PLUGIN*(void)> aCreateFunc )
  91. {
  92. ENTRY ent;
  93. ent.m_type = aType;
  94. ent.m_createFunc = aCreateFunc;
  95. ent.m_name = aName;
  96. m_plugins.push_back( ent );
  97. }
  98. PLUGIN* Create( PCB_FILE_T aFileType ) const
  99. {
  100. for( auto& ent : m_plugins )
  101. {
  102. if ( ent.m_type == aFileType )
  103. {
  104. return ent.m_createFunc();
  105. }
  106. }
  107. return nullptr;
  108. }
  109. const std::vector<ENTRY>& AllPlugins() const
  110. {
  111. return m_plugins;
  112. }
  113. private:
  114. std::vector<ENTRY> m_plugins;
  115. };
  116. /**
  117. * Register a plugin.
  118. *
  119. * Declare as a static variable in an anonymous namespace.
  120. *
  121. * @param aType type of the plugin
  122. * @param aName name of the file format
  123. * @param aCreateFunc function that creates a new object for the plugin.
  124. */
  125. struct REGISTER_PLUGIN
  126. {
  127. REGISTER_PLUGIN( PCB_FILE_T aType, const wxString& aName,
  128. std::function<PLUGIN*(void)> aCreateFunc )
  129. {
  130. PLUGIN_REGISTRY::Instance()->Register( aType, aName, aCreateFunc );
  131. }
  132. };
  133. /**
  134. * Return a #PLUGIN which the caller can use to import, export, save, or load
  135. * design documents.
  136. *
  137. * The returned #PLUGIN, may be reference counted, so please call PluginRelease() when you
  138. * are done using the returned #PLUGIN. It may or may not be code running from a DLL/DSO.
  139. *
  140. * @note The caller owns the returned object and must call PluginRelease when done using it.
  141. *
  142. * @param aFileType is from #PCB_FILE_T and tells which plugin to find.
  143. * @return the plug in corresponding to \a aFileType or NULL if not found.
  144. */
  145. static PLUGIN* PluginFind( PCB_FILE_T aFileType );
  146. /**
  147. * Release a #PLUGIN back to the system and may cause it to be unloaded from memory.
  148. *
  149. * @param aPlugin is the one to be released, and which is no longer usable
  150. * after calling this.
  151. */
  152. static void PluginRelease( PLUGIN* aPlugin );
  153. /**
  154. * Return a brief name for a plugin given \a aFileType enum.
  155. */
  156. static const wxString ShowType( PCB_FILE_T aFileType );
  157. /**
  158. * Return the #PCB_FILE_T from the corresponding plugin type name: "kicad", "legacy", etc.
  159. */
  160. static PCB_FILE_T EnumFromStr( const wxString& aFileType );
  161. /**
  162. * Return a plugin type given a path for a board file. FILE_TYPE_NONE if the file is not known.
  163. */
  164. static PCB_FILE_T FindPluginTypeFromBoardPath( const wxString& aFileName, int aCtl = 0 );
  165. /**
  166. * Return a plugin type given a footprint library's libPath.
  167. */
  168. static PCB_FILE_T GuessPluginTypeFromLibPath( const wxString& aLibPath, int aCtl = 0 );
  169. /**
  170. * Find the requested #PLUGIN and if found, calls the #PLUGIN::LoadBoard() function
  171. * on it using the arguments passed to this function. After the #PLUGIN::LoadBoard()
  172. * function returns, the #PLUGIN is Released() as part of this call.
  173. *
  174. * @param aFileType is the #PCB_FILE_T of file to load.
  175. * @param aFileName is the name of the file to load.
  176. * @param aAppendToMe is an existing BOARD to append to, use NULL if fresh
  177. * board load is wanted.
  178. * @param aProperties is an associative array that allows the caller to
  179. * pass additional tuning parameters to the PLUGIN.
  180. * @param aProject is the optional #PROJECT object primarily used by third party
  181. * importers.
  182. * @return the loaded #BOARD object. The caller owns it an it will never NULL because
  183. * exception thrown if error.
  184. *
  185. * @throw IO_ERROR if the #PLUGIN cannot be found, file cannot be found, or file cannot
  186. * be loaded.
  187. */
  188. static BOARD* Load( PCB_FILE_T aFileType, const wxString& aFileName,
  189. BOARD* aAppendToMe = nullptr, const STRING_UTF8_MAP* aProperties = nullptr,
  190. PROJECT* aProject = nullptr,
  191. PROGRESS_REPORTER* aProgressReporter = nullptr );
  192. /**
  193. * Write either a full \a aBoard to a storage file in a format that this implementation
  194. * knows about, or it can be used to write a portion of\a aBoard to a special kind of
  195. * export file.
  196. *
  197. * @param aFileType is the #PCB_FILE_T of file to save.
  198. * @param aFileName is the name of a file to save to on disk.
  199. * @param aBoard is the #BOARD document (data tree) to save or export to disk.
  200. * @param aBoard is the in memory document tree from which to extract information when
  201. * writing to \a aFileName. The caller continues to own the #BOARD, and
  202. * the plugin should refrain from modifying the #BOARD if possible.
  203. * @param aProperties is an associative array that can be used to tell the saver how to
  204. * save the file, because it can take any number of additional named
  205. * tuning arguments that the plugin is known to support. The caller
  206. * continues to own this object (plugin may not delete it), and plugins
  207. * should expect it to be optionally NULL.
  208. *
  209. * @throw IO_ERROR if there is a problem saving or exporting.
  210. */
  211. static void Save( PCB_FILE_T aFileType, const wxString& aFileName, BOARD* aBoard,
  212. const STRING_UTF8_MAP* aProperties = nullptr );
  213. };
  214. /**
  215. * A base class that #BOARD loading and saving plugins should derive from.
  216. *
  217. * Implementations can provide either Load() or Save() functions, or both. PLUGINs throw
  218. * exceptions, so it is best that you wrap your calls to these functions in a try catch block.
  219. * Plugins throw exceptions because it is illegal for them to have any user interface calls in
  220. * them whatsoever, i.e. no windowing or screen printing at all.
  221. *
  222. *The compiler writes the "zero argument" constructor for a PLUGIN automatically if you do
  223. * not provide one. If you decide you need to provide a zero argument constructor of your
  224. * own design, that is allowed. It must be public, and it is what the #IO_MGR uses. Parameters
  225. * may be passed into a PLUGIN via the #PROPERTIES variable for any of the public API functions
  226. * which take one.
  227. *
  228. *
  229. * <pre>
  230. * try
  231. * {
  232. * IO_MGR::Load(...);
  233. * or
  234. * IO_MGR::Save(...);
  235. * }
  236. * catch( const IO_ERROR& ioe )
  237. * {
  238. * // grab text from ioe, show in error window.
  239. * }
  240. * </pre>
  241. */
  242. class PLUGIN
  243. {
  244. public:
  245. /**
  246. * Return a brief hard coded name for this PLUGIN.
  247. */
  248. virtual const wxString PluginName() const = 0;
  249. /**
  250. * Returns board file description for the PLUGIN.
  251. */
  252. virtual PLUGIN_FILE_DESC GetBoardFileDesc() const;
  253. /**
  254. * Returns footprint file description for the PLUGIN.
  255. */
  256. virtual PLUGIN_FILE_DESC GetFootprintFileDesc() const;
  257. /**
  258. * Returns footprint library description for the PLUGIN.
  259. */
  260. virtual PLUGIN_FILE_DESC GetFootprintLibDesc() const;
  261. /**
  262. * Checks if this PLUGIN can read the specified board file.
  263. * If not overriden, extension check is used.
  264. */
  265. virtual bool CanReadBoard( const wxString& aFileName ) const;
  266. /**
  267. * Checks if this PLUGIN can read a footprint from specified file or directory.
  268. * If not overriden, extension check is used.
  269. */
  270. virtual bool CanReadFootprint( const wxString& aFileName ) const;
  271. /**
  272. * Checks if this PLUGIN can read footprint library from specified file or directory.
  273. * If not overriden, extension check is used.
  274. */
  275. virtual bool CanReadFootprintLib( const wxString& aFileName ) const;
  276. /**
  277. * Registers a KIDIALOG callback for collecting info from the user.
  278. */
  279. virtual void SetQueryUserCallback( std::function<bool( wxString aTitle, int aIcon,
  280. wxString aMessage,
  281. wxString aAction )> aCallback )
  282. { }
  283. /**
  284. * Load information from some input file format that this PLUGIN implementation
  285. * knows about into either a new #BOARD or an existing one.
  286. *
  287. * This may be used to load an entire new #BOARD, or to augment an existing one if
  288. * @a aAppendToMe is not NULL.
  289. *
  290. * @param aFileName is the name of the file to use as input and may be foreign in
  291. * nature or native in nature.
  292. * @param aAppendToMe is an existing BOARD to append to, but if NULL then this means
  293. * "do not append, rather load anew".
  294. * @param aProperties is an associative array that can be used to tell the loader how to
  295. * load the file, because it can take any number of additional named
  296. * arguments that the plugin is known to support. These are tuning
  297. * parameters for the import or load. The caller continues to own
  298. * this object (plugin may not delete it), and plugins should expect
  299. * it to be optionally NULL.
  300. * @param aProject is the optional #PROJECT object primarily used by third party
  301. * importers.
  302. * @param aProgressReporter an optional progress reporter
  303. * @param aLineCount a line count (necessary if a progress reporter is supplied)
  304. * @return the successfully loaded board, or the same one as \a aAppendToMe if aAppendToMe
  305. * was not NULL, and caller owns it.
  306. *
  307. * @throw IO_ERROR if there is a problem loading, and its contents should say what went
  308. * wrong, using line number and character offsets of the input file if
  309. * possible.
  310. */
  311. virtual BOARD* LoadBoard( const wxString& aFileName, BOARD* aAppendToMe,
  312. const STRING_UTF8_MAP* aProperties = nullptr, PROJECT* aProject = nullptr,
  313. PROGRESS_REPORTER* aProgressReporter = nullptr );
  314. /**
  315. * Return a container with the cached library footprints generated in the last call to
  316. * #Load. This function is intended to be used ONLY by the non-KiCad board importers for the
  317. * purpose of obtaining the footprint library of the design and creating a project-specific
  318. * library.
  319. *
  320. * @return Footprints (caller owns the objects)
  321. */
  322. virtual std::vector<FOOTPRINT*> GetImportedCachedLibraryFootprints();
  323. /**
  324. * Write @a aBoard to a storage file in a format that this PLUGIN implementation knows
  325. * about or it can be used to write a portion of \a aBoard to a special kind of export
  326. * file.
  327. *
  328. * @param aFileName is the name of a file to save to on disk.
  329. * @param aBoard is the class #BOARD in memory document tree from which to extract
  330. * information when writing to \a aFileName. The caller continues to
  331. * own the BOARD, and the plugin should refrain from modifying the BOARD
  332. * if possible.
  333. * @param aProperties is an associative array that can be used to tell the saver how to
  334. * save the file, because it can take any number of additional named
  335. * tuning arguments that the plugin is known to support. The caller
  336. * continues to own this object (plugin may not delete it) and plugins
  337. * should expect it to be optionally NULL.
  338. *
  339. * @throw IO_ERROR if there is a problem saving or exporting.
  340. */
  341. virtual void SaveBoard( const wxString& aFileName, BOARD* aBoard,
  342. const STRING_UTF8_MAP* aProperties = nullptr );
  343. /**
  344. * Return a list of footprint names contained within the library at @a aLibraryPath.
  345. *
  346. * @param aLibraryPath is a locator for the "library", usually a directory, file,
  347. * or URL containing several footprints.
  348. * @param aProperties is an associative array that can be used to tell the plugin
  349. * anything needed about how to perform with respect to @a aLibraryPath.
  350. * The caller continues to own this object (plugin may not delete it),
  351. * and plugins should expect it to be optionally NULL.
  352. * @param aFootprintNames is the array of available footprint names inside a library.
  353. * @param aBestEfforts if true, don't throw on errors, just return an empty list.
  354. *
  355. * @throw IO_ERROR if the library cannot be found, or footprint cannot be loaded.
  356. */
  357. virtual void FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aLibraryPath,
  358. bool aBestEfforts, const STRING_UTF8_MAP* aProperties = nullptr );
  359. /**
  360. * Generate a timestamp representing all the files in the library (including the library
  361. * directory).
  362. *
  363. * Timestamps should not be considered ordered, they either match or they don't.
  364. */
  365. virtual long long GetLibraryTimestamp( const wxString& aLibraryPath ) const = 0;
  366. /**
  367. * If possible, prefetches the specified library (e.g. performing downloads). Does not parse.
  368. * Threadsafe.
  369. *
  370. * This is a no-op for libraries that cannot be prefetched. Plugins that cannot prefetch
  371. * need not override this; a default no-op is provided.
  372. *
  373. * @param aLibraryPath is a locator for the "library", usually a directory, file, or URL
  374. * containing several footprints.
  375. *
  376. * @param aProperties is an associative array that can be used to tell the plugin anything
  377. * needed about how to perform with respect to @a aLibraryPath. The
  378. * caller continues to own this object (plugin may not delete it), and
  379. * plugins should expect it to be optionally NULL.
  380. *
  381. * @throw IO_ERROR if there is an error prefetching the library.
  382. */
  383. virtual void PrefetchLib( const wxString& aLibraryPath,
  384. const STRING_UTF8_MAP* aProperties = nullptr );
  385. /**
  386. * Load a single footprint from @a aFootprintPath and put its name in @a aFootprintNameOut.
  387. * If this is a footprint library, the first footprint should be loaded.
  388. * The default implementation uses FootprintEnumerate and FootprintLoad to load first footprint.
  389. *
  390. * @param aLibraryPath is a path of the footprint file.
  391. * @param aFootprintNameOut is the name output of the loaded footprint.
  392. * @param aProperties is an associative array that can be used to tell the loader
  393. * implementation to do something special, because it can take
  394. * any number of additional named tuning arguments that the plugin
  395. * is known to support. The caller continues to own this object
  396. * (plugin may not delete it), and plugins should expect it to be
  397. * optionally NULL.
  398. * @return the #FOOTPRINT object if found, caller owns it, else NULL if not found.
  399. *
  400. * @throw IO_ERROR if the footprint cannot be found or read.
  401. */
  402. virtual FOOTPRINT* ImportFootprint( const wxString& aFootprintPath, wxString& aFootprintNameOut,
  403. const STRING_UTF8_MAP* aProperties = nullptr );
  404. /**
  405. * Load a footprint having @a aFootprintName from the @a aLibraryPath containing a library
  406. * format that this PLUGIN knows about.
  407. *
  408. * @param aLibraryPath is a locator for the "library", usually a directory, file, or URL
  409. * containing several footprints.
  410. * @param aFootprintName is the name of the footprint to load.
  411. * @param aProperties is an associative array that can be used to tell the loader
  412. * implementation to do something special, because it can take
  413. * any number of additional named tuning arguments that the plugin
  414. * is known to support. The caller continues to own this object
  415. * (plugin may not delete it), and plugins should expect it to be
  416. * optionally NULL.
  417. * @param aKeepUUID = true to keep initial items UUID, false to set new UUID
  418. * normally true if loaded in the footprint editor, false
  419. * if loaded in the board editor. Make sense only in kicad_plugin
  420. * @return the #FOOTPRINT object if found, caller owns it, else NULL if not found.
  421. *
  422. * @throw IO_ERROR if the library cannot be found or read. No exception is thrown in
  423. * the case where \a aFootprintName cannot be found.
  424. */
  425. virtual FOOTPRINT* FootprintLoad( const wxString& aLibraryPath,
  426. const wxString& aFootprintName,
  427. bool aKeepUUID = false,
  428. const STRING_UTF8_MAP* aProperties = nullptr );
  429. /**
  430. * A version of FootprintLoad() for use after FootprintEnumerate() for more efficient
  431. * cache management.
  432. */
  433. virtual const FOOTPRINT* GetEnumeratedFootprint( const wxString& aLibraryPath,
  434. const wxString& aFootprintName,
  435. const STRING_UTF8_MAP* aProperties = nullptr );
  436. /**
  437. * Check for the existence of a footprint.
  438. */
  439. virtual bool FootprintExists( const wxString& aLibraryPath, const wxString& aFootprintName,
  440. const STRING_UTF8_MAP* aProperties = nullptr );
  441. /**
  442. * Write @a aFootprint to an existing library located at @a aLibraryPath.
  443. * If a footprint by the same name already exists, it is replaced.
  444. *
  445. * @param aLibraryPath is a locator for the "library", usually a directory, file, or URL
  446. * containing several footprints.
  447. * @param aFootprint is what to store in the library. The caller continues to own the
  448. * footprint after this call.
  449. * @param aProperties is an associative array that can be used to tell the saver how to
  450. * save the footprint, because it can take any number of additional
  451. * named tuning arguments that the plugin is known to support. The
  452. * caller continues to own this object (plugin may not delete it), and
  453. * plugins should expect it to be optionally NULL.
  454. *
  455. * @throw IO_ERROR if there is a problem saving.
  456. */
  457. virtual void FootprintSave( const wxString& aLibraryPath, const FOOTPRINT* aFootprint,
  458. const STRING_UTF8_MAP* aProperties = nullptr );
  459. /**
  460. * Delete @a aFootprintName from the library at @a aLibraryPath.
  461. *
  462. * @param aLibraryPath is a locator for the "library", usually a directory, file, or URL
  463. * containing several footprints.
  464. * @param aFootprintName is the name of a footprint to delete from the specified library.
  465. * @param aProperties is an associative array that can be used to tell the library delete
  466. * function anything special, because it can take any number of additional
  467. * named tuning arguments that the plugin is known to support. The caller
  468. * continues to own this object (plugin may not delete it), and plugins
  469. * should expect it to be optionally NULL.
  470. *
  471. * @throw IO_ERROR if there is a problem finding the footprint or the library, or deleting it.
  472. */
  473. virtual void FootprintDelete( const wxString& aLibraryPath, const wxString& aFootprintName,
  474. const STRING_UTF8_MAP* aProperties = nullptr );
  475. /**
  476. * Create a new empty footprint library at @a aLibraryPath empty.
  477. *
  478. * It is an error to attempt to create an existing library or to attempt to create
  479. * on a "read only" location.
  480. *
  481. * @param aLibraryPath is a locator for the "library", usually a directory, file, or URL
  482. * containing several footprints.
  483. * @param aProperties is an associative array that can be used to tell the library create
  484. * function anything special, because it can take any number of additional
  485. * named tuning arguments that the plugin is known to support. The caller
  486. * continues to own this object (plugin may not delete it), and plugins
  487. * should expect it to be optionally NULL.
  488. *
  489. * @throw IO_ERROR if there is a problem finding the library, or creating it.
  490. */
  491. virtual void FootprintLibCreate( const wxString& aLibraryPath,
  492. const STRING_UTF8_MAP* aProperties = nullptr );
  493. /**
  494. * Delete an existing footprint library and returns true, or if library does not
  495. * exist returns false, or throws an exception if library exists but is read only or
  496. * cannot be deleted for some other reason.
  497. *
  498. * @param aLibraryPath is a locator for the "library", usually a directory or file which
  499. * will contain footprints.
  500. * @param aProperties is an associative array that can be used to tell the library delete
  501. * implementation function anything special, because it can take any
  502. * number of additional named tuning arguments that the plugin is known
  503. * to support. The caller continues to own this object (plugin may not
  504. * delete it), and plugins should expect it to be optionally NULL.
  505. * @return true if library deleted, false if library did not exist.
  506. *
  507. * @throw IO_ERROR if there is a problem deleting an existing library.
  508. */
  509. virtual bool FootprintLibDelete( const wxString& aLibraryPath,
  510. const STRING_UTF8_MAP* aProperties = nullptr );
  511. /**
  512. * Return true if the library at @a aLibraryPath is writable.
  513. *
  514. * The system libraries are typically read only because of where they are installed..
  515. *
  516. * @param aLibraryPath is a locator for the "library", usually a directory, file, or URL
  517. * containing several footprints.
  518. *
  519. * @throw IO_ERROR if no library at aLibraryPath exists.
  520. */
  521. virtual bool IsFootprintLibWritable( const wxString& aLibraryPath );
  522. /**
  523. * Append supported PLUGIN options to @a aListToAppenTo along with internationalized
  524. * descriptions.
  525. *
  526. * Options are typically appended so that a derived #PLUGIN can call its base class
  527. * function by the same name first, thus inheriting options declared there. Some base
  528. * class options could pertain to all Footprint*() functions in all derived PLUGINs.
  529. *
  530. * @note Since aListToAppendTo is a #PROPERTIES object, all options will be unique and
  531. * last guy wins.
  532. *
  533. * @param aListToAppendTo holds a tuple of
  534. * <dl>
  535. * <dt>option</dt>
  536. * <dd>This eventually is what shows up into the fp-lib-table "options"
  537. * field, possibly combined with others.</dd>
  538. * <dt>internationalized description</dt>
  539. * <dd>The internationalized description is displayed in DIALOG_PLUGIN_OPTIONS.
  540. * It may be multi-line and be quite explanatory of the option.</dd>
  541. * </dl>
  542. * <br>
  543. * In the future perhaps @a aListToAppendTo evolves to something capable of also
  544. * holding a wxValidator for the cells in said dialog:
  545. * http://forums.wxwidgets.org/viewtopic.php?t=23277&p=104180.
  546. * This would require a 3 column list, and introducing wx GUI knowledge to
  547. * PLUGIN, which has been avoided to date.
  548. */
  549. virtual void FootprintLibOptions( STRING_UTF8_MAP* aListToAppendTo ) const;
  550. virtual ~PLUGIN()
  551. {};
  552. #ifndef SWIG
  553. /**
  554. * Releases a PLUGIN in the context of a potential thrown exception through its destructor.
  555. */
  556. class RELEASER
  557. {
  558. PLUGIN* plugin;
  559. // private assignment operator so it's illegal
  560. RELEASER& operator=( RELEASER& aOther ) { return *this; }
  561. // private copy constructor so it's illegal
  562. RELEASER( const RELEASER& aOther ) : plugin( nullptr ) {}
  563. public:
  564. RELEASER( PLUGIN* aPlugin = nullptr ) :
  565. plugin( aPlugin )
  566. {
  567. }
  568. ~RELEASER()
  569. {
  570. if( plugin )
  571. release();
  572. }
  573. void release()
  574. {
  575. IO_MGR::PluginRelease( plugin );
  576. plugin = nullptr;
  577. }
  578. void set( PLUGIN* aPlugin )
  579. {
  580. if( plugin )
  581. release();
  582. plugin = aPlugin;
  583. }
  584. operator PLUGIN* () const
  585. {
  586. return plugin;
  587. }
  588. PLUGIN* operator -> () const
  589. {
  590. return plugin;
  591. }
  592. };
  593. #endif
  594. };
  595. #endif // IO_MGR_H_