KiCad PCB EDA Suite
Loading...
Searching...
No Matches
io_mgr.cpp
Go to the documentation of this file.
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 <[email protected]>
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
25#include <wx/filename.h>
26#include <wx/uri.h>
27
28#include <config.h>
29#include <kiway_player.h>
30#include <io_mgr.h>
32
47
48#define FMT_UNIMPLEMENTED _( "Plugin \"%s\" does not implement the \"%s\" function." )
49#define FMT_NOTFOUND _( "Plugin type \"%s\" is not found." )
50
51
52// Some day plugins might be in separate DLL/DSOs, simply because of numbers of them
53// and code size. Until then, use the simplest method:
54
55// This implementation is one of two which could be done.
56// The other one would cater to DLL/DSO's. But since it would be nearly
57// impossible to link a KICAD type DLL/DSO right now without pulling in all
58// ::Draw() functions, I forgo that option temporarily.
59
60// Some day it may be possible to have some built in AND some DLL/DSO
61// plugins coexisting.
62
63
65{
66 // This implementation is subject to change, any magic is allowed here.
67 // The public IO_MGR API is the only pertinent public information.
68
69 return PLUGIN_REGISTRY::Instance()->Create( aFileType );
70}
71
72
74{
75 // This function is a place holder for a future point in time where
76 // the plugin is a DLL/DSO. It could do reference counting, and then
77 // unload the DLL/DSO when count goes to zero.
78
79 delete aPlugin;
80}
81
82
83const wxString IO_MGR::ShowType( PCB_FILE_T aType )
84{
85 const auto& plugins = PLUGIN_REGISTRY::Instance()->AllPlugins();
86
87 for( const auto& plugin : plugins )
88 {
89 if ( plugin.m_type == aType )
90 {
91 return plugin.m_name;
92 }
93 }
94
95 return wxString::Format( _( "UNKNOWN (%d)" ), aType );
96}
97
98
100{
101 const auto& plugins = PLUGIN_REGISTRY::Instance()->AllPlugins();
102
103 for( const auto& plugin : plugins )
104 {
105 if ( plugin.m_name == aType )
106 {
107 return plugin.m_type;
108 }
109 }
110
111 return PCB_FILE_T( -1 );
112}
113
114
115// The KIWAY_PLAYER::OpenProjectFiles() API knows nothing about plugins, so
116// determine how to load the BOARD here
117IO_MGR::PCB_FILE_T IO_MGR::FindPluginTypeFromBoardPath( const wxString& aFileName, int aCtl )
118{
119 const auto& plugins = IO_MGR::PLUGIN_REGISTRY::Instance()->AllPlugins();
120
121 for( const auto& plugin : plugins )
122 {
123 bool isKiCad = plugin.m_type == IO_MGR::KICAD_SEXP || plugin.m_type == IO_MGR::LEGACY;
124
125 if( ( aCtl & KICTL_KICAD_ONLY ) && !isKiCad )
126 continue;
127
128 if( ( aCtl & KICTL_NONKICAD_ONLY ) && isKiCad )
129 continue;
130
131 PLUGIN::RELEASER pi( plugin.m_createFunc() );
132
133 if( pi->CanReadBoard( aFileName ) )
134 return plugin.m_type;
135 }
136
138}
139
140
141IO_MGR::PCB_FILE_T IO_MGR::GuessPluginTypeFromLibPath( const wxString& aLibPath, int aCtl )
142{
143 const auto& plugins = IO_MGR::PLUGIN_REGISTRY::Instance()->AllPlugins();
144
145 for( const auto& plugin : plugins )
146 {
147 bool isKiCad = plugin.m_type == IO_MGR::KICAD_SEXP || plugin.m_type == IO_MGR::LEGACY;
148
149 if( ( aCtl & KICTL_KICAD_ONLY ) && !isKiCad )
150 continue;
151
152 if( ( aCtl & KICTL_NONKICAD_ONLY ) && isKiCad )
153 continue;
154
155 PLUGIN::RELEASER pi( plugin.m_createFunc() );
156
157 if( pi->CanReadFootprintLib( aLibPath ) )
158 return plugin.m_type;
159 }
160
162}
163
164
165BOARD* IO_MGR::Load( PCB_FILE_T aFileType, const wxString& aFileName, BOARD* aAppendToMe,
166 const STRING_UTF8_MAP* aProperties, PROJECT* aProject,
167 PROGRESS_REPORTER* aProgressReporter )
168{
169 // release the PLUGIN even if an exception is thrown.
170 PLUGIN::RELEASER pi( PluginFind( aFileType ) );
171
172 if( (PLUGIN*) pi ) // test pi->plugin
173 {
174 return pi->LoadBoard( aFileName, aAppendToMe, aProperties, aProject, aProgressReporter );
175 }
176
177 THROW_IO_ERROR( wxString::Format( FMT_NOTFOUND, ShowType( aFileType ).GetData() ) );
178}
179
180
181void IO_MGR::Save( PCB_FILE_T aFileType, const wxString& aFileName, BOARD* aBoard,
182 const STRING_UTF8_MAP* aProperties )
183{
184 // release the PLUGIN even if an exception is thrown.
185 PLUGIN::RELEASER pi( PluginFind( aFileType ) );
186
187 if( (PLUGIN*) pi ) // test pi->plugin
188 {
189 pi->SaveBoard( aFileName, aBoard, aProperties ); // virtual
190 return;
191 }
192
193 THROW_IO_ERROR( wxString::Format( FMT_NOTFOUND, ShowType( aFileType ).GetData() ) );
194}
195
196// These text strings are "truth" for identifying the plugins. If you change the spellings,
197// you will obsolete library tables, so don't do it. Additions are OK.
198
199// clang-format off
202 wxT( "KiCad" ),
203 []() -> PLUGIN* { return new PCB_PLUGIN; } );
204
207 wxT( "Legacy" ),
208 []() -> PLUGIN* { return new LEGACY_PLUGIN; } );
209
210// Keep non-KiCad plugins in alphabetical order
211
214 wxT( "Altium Circuit Maker" ),
215 []() -> PLUGIN* { return new ALTIUM_CIRCUIT_MAKER_PLUGIN; } );
216
219 wxT( "Altium Circuit Studio" ),
220 []() -> PLUGIN* { return new ALTIUM_CIRCUIT_STUDIO_PLUGIN; } );
221
224 wxT( "Altium Designer" ),
225 []() -> PLUGIN* { return new ALTIUM_DESIGNER_PLUGIN; } );
226
229 wxT( "CADSTAR PCB Archive" ),
230 []() -> PLUGIN* { return new CADSTAR_PCB_ARCHIVE_PLUGIN; } );
231
234 wxT( "Eagle" ),
235 []() -> PLUGIN* { return new EAGLE_PLUGIN; } );
236
239 wxT( "EasyEDA / JLCEDA Std" ),
240 []() -> PLUGIN* { return new EASYEDA_PLUGIN; });
241
244 wxT( "EasyEDA / JLCEDA Pro" ),
245 []() -> PLUGIN* { return new EASYEDAPRO_PLUGIN; });
246
249 wxT( "Fabmaster" ),
250 []() -> PLUGIN* { return new FABMASTER_PLUGIN; } );
251
254 wxT( "GEDA/Pcb" ),
255 []() -> PLUGIN* { return new GPCB_PLUGIN; } );
256
259 wxT( "P-Cad" ),
260 []() -> PLUGIN* { return new PCAD_PLUGIN; } );
261
264 wxT( "Solidworks PCB" ),
265 []() -> PLUGIN* { return new SOLIDWORKS_PCB_PLUGIN; } );
266
269 wxT( "IPC-2581" ),
270 []() -> PLUGIN* { return new IPC2581_PLUGIN; } );
271// clang-format on
Pcbnew PLUGIN for CADSTAR PCB Archive (*.cpa) format: an ASCII format based on S-expressions.
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:276
Works with Eagle 6.x XML board files and footprints to implement the Pcbnew PLUGIN API or a portion o...
Definition: eagle_plugin.h:130
A PLUGIN derivation for saving and loading Geda PCB files.
Definition: gpcb_plugin.h:47
PLUGIN * Create(PCB_FILE_T aFileType) const
Definition: io_mgr.h:112
const std::vector< ENTRY > & AllPlugins() const
Definition: io_mgr.h:125
static PLUGIN_REGISTRY * Instance()
Definition: io_mgr.h:91
static const wxString ShowType(PCB_FILE_T aFileType)
Return a brief name for a plugin given aFileType enum.
Definition: io_mgr.cpp:83
static PCB_FILE_T GuessPluginTypeFromLibPath(const wxString &aLibPath, int aCtl=0)
Return a plugin type given a footprint library's libPath.
Definition: io_mgr.cpp:141
static void PluginRelease(PLUGIN *aPlugin)
Release a PLUGIN back to the system and may cause it to be unloaded from memory.
Definition: io_mgr.cpp:73
PCB_FILE_T
The set of file types that the IO_MGR knows about, and for which there has been a plugin written,...
Definition: io_mgr.h:54
@ LEGACY
Legacy Pcbnew file formats prior to s-expression.
Definition: io_mgr.h:57
@ ALTIUM_DESIGNER
Definition: io_mgr.h:60
@ KICAD_SEXP
S-expression Pcbnew file format.
Definition: io_mgr.h:56
@ ALTIUM_CIRCUIT_MAKER
Definition: io_mgr.h:58
@ EASYEDA
Definition: io_mgr.h:63
@ IPC2581
Definition: io_mgr.h:69
@ PCAD
Definition: io_mgr.h:67
@ EAGLE
Definition: io_mgr.h:62
@ FILE_TYPE_NONE
Definition: io_mgr.h:74
@ CADSTAR_PCB_ARCHIVE
Definition: io_mgr.h:61
@ GEDA_PCB
Geda PCB file formats.
Definition: io_mgr.h:66
@ SOLIDWORKS_PCB
Definition: io_mgr.h:68
@ FABMASTER
Definition: io_mgr.h:65
@ EASYEDAPRO
Definition: io_mgr.h:64
@ ALTIUM_CIRCUIT_STUDIO
Definition: io_mgr.h:59
static PCB_FILE_T EnumFromStr(const wxString &aFileType)
Return the PCB_FILE_T from the corresponding plugin type name: "kicad", "legacy", etc.
Definition: io_mgr.cpp:99
static PCB_FILE_T FindPluginTypeFromBoardPath(const wxString &aFileName, int aCtl=0)
Return a plugin type given a path for a board file.
Definition: io_mgr.cpp:117
static BOARD * Load(PCB_FILE_T aFileType, const wxString &aFileName, BOARD *aAppendToMe=nullptr, const STRING_UTF8_MAP *aProperties=nullptr, PROJECT *aProject=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr)
Find the requested PLUGIN and if found, calls the PLUGIN::LoadBoard() function on it using the argume...
Definition: io_mgr.cpp:165
static PLUGIN * PluginFind(PCB_FILE_T aFileType)
Return a PLUGIN which the caller can use to import, export, save, or load design documents.
Definition: io_mgr.cpp:64
static void Save(PCB_FILE_T aFileType, const wxString &aFileName, BOARD *aBoard, const STRING_UTF8_MAP *aProperties=nullptr)
Write either a full aBoard to a storage file in a format that this implementation knows about,...
Definition: io_mgr.cpp:181
A PLUGIN derivation which could possibly be put into a DLL/DSO.
Definition: legacy_plugin.h:60
A PLUGIN derivation for saving and loading Pcbnew s-expression formatted files.
Definition: pcb_plugin.h:275
Releases a PLUGIN in the context of a potential thrown exception through its destructor.
Definition: io_mgr.h:614
A base class that BOARD loading and saving plugins should derive from.
Definition: io_mgr.h:272
virtual bool CanReadFootprintLib(const wxString &aFileName) const
Checks if this PLUGIN can read footprint library from specified file or directory.
Definition: plugin.cpp:93
virtual void SaveBoard(const wxString &aFileName, BOARD *aBoard, const STRING_UTF8_MAP *aProperties=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr)
Write aBoard to a storage file in a format that this PLUGIN implementation knows about or it can be u...
Definition: plugin.cpp:158
virtual bool CanReadBoard(const wxString &aFileName) const
Checks if this PLUGIN can read the specified board file.
Definition: plugin.cpp:61
virtual BOARD * LoadBoard(const wxString &aFileName, BOARD *aAppendToMe, const STRING_UTF8_MAP *aProperties=nullptr, PROJECT *aProject=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr)
Load information from some input file format that this PLUGIN implementation knows about into either ...
Definition: plugin.cpp:144
A progress reporter interface for use in multi-threaded environments.
Container for project specific data.
Definition: project.h:62
A name/value tuple with unique names and optional values.
#define _(s)
Pcbnew PLUGIN for Fabmaster (Allegro) ASCII format.
static IO_MGR::REGISTER_PLUGIN registerAltiumCircuitMakerPlugin(IO_MGR::ALTIUM_CIRCUIT_MAKER, wxT("Altium Circuit Maker"), []() -> PLUGIN *{ return new ALTIUM_CIRCUIT_MAKER_PLUGIN;})
static IO_MGR::REGISTER_PLUGIN registerEasyEDAPlugin(IO_MGR::EASYEDA, wxT("EasyEDA / JLCEDA Std"), []() -> PLUGIN *{ return new EASYEDA_PLUGIN;})
static IO_MGR::REGISTER_PLUGIN registerCadstarArchivePlugin(IO_MGR::CADSTAR_PCB_ARCHIVE, wxT("CADSTAR PCB Archive"), []() -> PLUGIN *{ return new CADSTAR_PCB_ARCHIVE_PLUGIN;})
static IO_MGR::REGISTER_PLUGIN registerEaglePlugin(IO_MGR::EAGLE, wxT("Eagle"), []() -> PLUGIN *{ return new EAGLE_PLUGIN;})
static IO_MGR::REGISTER_PLUGIN registerAltiumDesignerPlugin(IO_MGR::ALTIUM_DESIGNER, wxT("Altium Designer"), []() -> PLUGIN *{ return new ALTIUM_DESIGNER_PLUGIN;})
static IO_MGR::REGISTER_PLUGIN registerFabmasterPlugin(IO_MGR::FABMASTER, wxT("Fabmaster"), []() -> PLUGIN *{ return new FABMASTER_PLUGIN;})
static IO_MGR::REGISTER_PLUGIN registerIPC2581Plugin(IO_MGR::IPC2581, wxT("IPC-2581"), []() -> PLUGIN *{ return new IPC2581_PLUGIN;})
static IO_MGR::REGISTER_PLUGIN registerGPCBPlugin(IO_MGR::GEDA_PCB, wxT("GEDA/Pcb"), []() -> PLUGIN *{ return new GPCB_PLUGIN;})
static IO_MGR::REGISTER_PLUGIN registerPcadPlugin(IO_MGR::PCAD, wxT("P-Cad"), []() -> PLUGIN *{ return new PCAD_PLUGIN;})
static IO_MGR::REGISTER_PLUGIN registerKicadPlugin(IO_MGR::KICAD_SEXP, wxT("KiCad"), []() -> PLUGIN *{ return new PCB_PLUGIN;})
static IO_MGR::REGISTER_PLUGIN registerEasyEDAProPlugin(IO_MGR::EASYEDAPRO, wxT("EasyEDA / JLCEDA Pro"), []() -> PLUGIN *{ return new EASYEDAPRO_PLUGIN;})
static IO_MGR::REGISTER_PLUGIN registerLegacyPlugin(IO_MGR::LEGACY, wxT("Legacy"), []() -> PLUGIN *{ return new LEGACY_PLUGIN;})
static IO_MGR::REGISTER_PLUGIN registerSolidworksPCBPlugin(IO_MGR::SOLIDWORKS_PCB, wxT("Solidworks PCB"), []() -> PLUGIN *{ return new SOLIDWORKS_PCB_PLUGIN;})
static IO_MGR::REGISTER_PLUGIN registerAltiumCircuitStudioPlugin(IO_MGR::ALTIUM_CIRCUIT_STUDIO, wxT("Altium Circuit Studio"), []() -> PLUGIN *{ return new ALTIUM_CIRCUIT_STUDIO_PLUGIN;})
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:39
#define KICTL_KICAD_ONLY
chosen file is from KiCad according to user
Definition: kiway_player.h:77
#define KICTL_NONKICAD_ONLY
chosen file is non-KiCad according to user
Definition: kiway_player.h:76
Pcbnew PLUGIN for P-Cad 200x ASCII *.pcb format.
#define FMT_NOTFOUND
Definition: sch_io_mgr.cpp:44
Register a plugin.
Definition: io_mgr.h:144
Definition of file extensions used in Kicad.