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.

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