summaryrefslogtreecommitdiff
path: root/pcbnew/io_mgr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'pcbnew/io_mgr.cpp')
-rw-r--r--pcbnew/io_mgr.cpp272
1 files changed, 272 insertions, 0 deletions
diff --git a/pcbnew/io_mgr.cpp b/pcbnew/io_mgr.cpp
new file mode 100644
index 0000000..8d3981b
--- /dev/null
+++ b/pcbnew/io_mgr.cpp
@@ -0,0 +1,272 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2011-2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <wx/filename.h>
+#include <wx/uri.h>
+
+#include <io_mgr.h>
+#include <legacy_plugin.h>
+#include <kicad_plugin.h>
+#include <eagle_plugin.h>
+#include <pcad2kicadpcb_plugin/pcad_plugin.h>
+#include <gpcb_plugin.h>
+#include <config.h>
+
+#if defined(BUILD_GITHUB_PLUGIN)
+ #include <github/github_plugin.h>
+#endif
+
+#include <wildcards_and_files_ext.h>
+
+#define FMT_UNIMPLEMENTED _( "Plugin '%s' does not implement the '%s' function." )
+#define FMT_NOTFOUND _( "Plugin type '%s' is not found." )
+
+
+// is there a better place for this function?
+bool PROPERTIES::Value( const char* aName, UTF8* aFetchedValue ) const
+{
+ PROPERTIES::const_iterator it = find( aName );
+
+ if( it != end() )
+ {
+ if( aFetchedValue )
+ *aFetchedValue = it->second;
+ return true;
+ }
+ return false;
+}
+
+
+// Some day plugins might be in separate DLL/DSOs, simply because of numbers of them
+// and code size. Until then, use the simplest method:
+
+// This implementation is one of two which could be done.
+// The other one would cater to DLL/DSO's. But since it would be nearly
+// impossible to link a KICAD type DLL/DSO right now without pulling in all
+// ::Draw() functions, I forgo that option temporarily.
+
+// Some day it may be possible to have some built in AND some DLL/DSO
+// plugins coexisting.
+
+
+PLUGIN* IO_MGR::PluginFind( PCB_FILE_T aFileType )
+{
+ // This implementation is subject to change, any magic is allowed here.
+ // The public IO_MGR API is the only pertinent public information.
+
+ switch( aFileType )
+ {
+ case LEGACY:
+ return new LEGACY_PLUGIN();
+
+ case KICAD:
+ return new PCB_IO();
+
+ case EAGLE:
+ return new EAGLE_PLUGIN();
+
+ case PCAD:
+ return new PCAD_PLUGIN();
+
+ case GEDA_PCB:
+ return new GPCB_PLUGIN();
+
+ case GITHUB:
+#if defined(BUILD_GITHUB_PLUGIN)
+ return new GITHUB_PLUGIN();
+#else
+ THROW_IO_ERROR( "BUILD_GITHUB_PLUGIN not enabled in cmake build environment" );
+#endif
+
+ case FILE_TYPE_NONE:
+ return NULL;
+ }
+
+ return NULL;
+}
+
+
+void IO_MGR::PluginRelease( PLUGIN* aPlugin )
+{
+ // This function is a place holder for a future point in time where
+ // the plugin is a DLL/DSO. It could do reference counting, and then
+ // unload the DLL/DSO when count goes to zero.
+
+ delete aPlugin;
+}
+
+
+const wxString IO_MGR::ShowType( PCB_FILE_T aType )
+{
+ // keep this function in sync with EnumFromStr() relative to the
+ // text spellings. If you change the spellings, you will obsolete
+ // library tables, so don't do change, only additions are ok.
+
+ switch( aType )
+ {
+ default:
+ return wxString::Format( _( "Unknown PCB_FILE_T value: %d" ), aType );
+
+ case LEGACY:
+ return wxString( wxT( "Legacy" ) );
+
+ case KICAD:
+ return wxString( wxT( "KiCad" ) );
+
+ case EAGLE:
+ return wxString( wxT( "Eagle" ) );
+
+ case PCAD:
+ return wxString( wxT( "P-Cad" ) );
+
+ case GEDA_PCB:
+ return wxString( wxT( "Geda-PCB" ) );
+
+ case GITHUB:
+ return wxString( wxT( "Github" ) );
+ }
+}
+
+
+IO_MGR::PCB_FILE_T IO_MGR::EnumFromStr( const wxString& aType )
+{
+ // keep this function in sync with ShowType() relative to the
+ // text spellings. If you change the spellings, you will obsolete
+ // library tables, so don't do change, only additions are ok.
+
+ if( aType == wxT( "KiCad" ) )
+ return KICAD;
+
+ if( aType == wxT( "Legacy" ) )
+ return LEGACY;
+
+ if( aType == wxT( "Eagle" ) )
+ return EAGLE;
+
+ if( aType == wxT( "P-Cad" ) )
+ return PCAD;
+
+ if( aType == wxT( "Geda-PCB" ) )
+ return GEDA_PCB;
+
+ if( aType == wxT( "Github" ) )
+ return GITHUB;
+
+ // wxASSERT( blow up here )
+
+ return PCB_FILE_T( -1 );
+}
+
+
+const wxString IO_MGR::GetFileExtension( PCB_FILE_T aFileType )
+{
+ wxString ext = wxEmptyString;
+ PLUGIN* plugin = PluginFind( aFileType );
+
+ if( plugin != NULL )
+ {
+ ext = plugin->GetFileExtension();
+ PluginRelease( plugin );
+ }
+
+ return ext;
+}
+
+
+IO_MGR::PCB_FILE_T IO_MGR::GuessPluginTypeFromLibPath( const wxString& aLibPath )
+{
+ PCB_FILE_T ret = KICAD; // default guess, unless detected otherwise.
+ wxFileName fn( aLibPath );
+
+ if( fn.GetExt() == LegacyFootprintLibPathExtension )
+ {
+ ret = LEGACY;
+ }
+ else if( fn.GetExt() == GedaPcbFootprintLibFileExtension )
+ {
+ ret = GEDA_PCB;
+ }
+ else if( fn.GetExt() == EagleFootprintLibPathExtension )
+ {
+ ret = EAGLE;
+ }
+
+ // Test this one anyways, even though it's the default guess, to avoid
+ // the wxURI instantiation below.
+ // We default ret to KICAD above, because somebody might have
+ // mistakenly put a pretty library into a directory other than
+ // *.pretty/ with *.kicad_mod in there., and I don't want to return -1,
+ // since we only claimed to be guessing.
+ //
+ // However libraries on GitHub have names ending by .pretty
+ // so test also this is not a name starting by http (including https).
+ else if( fn.GetExt() == KiCadFootprintLibPathExtension &&
+ !aLibPath.StartsWith( wxT( "http" ) ) )
+ {
+ ret = KICAD;
+ }
+ else
+ {
+ // There is no extension for a remote repo, so test the server name.
+ wxURI uri( aLibPath );
+
+ if( uri.HasServer() && uri.GetServer() == wxT( "github.com" ) )
+ {
+ ret = GITHUB;
+ }
+ }
+
+ return ret;
+}
+
+
+BOARD* IO_MGR::Load( PCB_FILE_T aFileType, const wxString& aFileName,
+ BOARD* aAppendToMe, const PROPERTIES* aProperties )
+{
+ // release the PLUGIN even if an exception is thrown.
+ PLUGIN::RELEASER pi( PluginFind( aFileType ) );
+
+ if( (PLUGIN*) pi ) // test pi->plugin
+ {
+ return pi->Load( aFileName, aAppendToMe, aProperties ); // virtual
+ }
+
+ THROW_IO_ERROR( wxString::Format( FMT_NOTFOUND, ShowType( aFileType ).GetData() ) );
+}
+
+
+void IO_MGR::Save( PCB_FILE_T aFileType, const wxString& aFileName, BOARD* aBoard, const PROPERTIES* aProperties )
+{
+ // release the PLUGIN even if an exception is thrown.
+ PLUGIN::RELEASER pi( PluginFind( aFileType ) );
+
+ if( (PLUGIN*) pi ) // test pi->plugin
+ {
+ pi->Save( aFileName, aBoard, aProperties ); // virtual
+ return;
+ }
+
+ THROW_IO_ERROR( wxString::Format( FMT_NOTFOUND, ShowType( aFileType ).GetData() ) );
+}
+