Schematic plugins refactoring, fixes for PCB plugins.

- Move PLUGIN_FILE_DESC to common.
- SCH_PLUGIN: rename Load -> LoadSchematicFile, Save -> SaveSchematicFile.
- Use PLUGIN_FILE_DESC and CanRead* in schematic plugins.
- Return none/unknown types from Find/GuessPluginType functions.
- Iterate over file types for file wildcards.
- Clean-up header checking in IO plugins.
- Use PCB plugin list in IO_MGR::GuessPluginTypeFromLibPath.
This commit is contained in:
Alex Shvartzkop 2023-08-26 22:28:53 +03:00
parent 7428f3d452
commit e128896ba6
43 changed files with 711 additions and 555 deletions

View File

@ -382,6 +382,7 @@ set( COMMON_SRCS
origin_transforms.cpp
page_info.cpp
paths.cpp
plugin_file_desc.cpp
printout.cpp
project.cpp
ptree.cpp

View File

@ -0,0 +1,32 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 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 <plugin_file_desc.h>
#include <wildcards_and_files_ext.h>
#include <wx/translation.h>
wxString PLUGIN_FILE_DESC::FileFilter() const
{
return wxGetTranslation( m_Description ) + AddFileExtListToFilter( m_FileExtensions );
}

View File

@ -130,7 +130,6 @@ const std::string KiCadSymbolLibFileExtension( "kicad_sym" );
const std::string SchematicSymbolFileExtension( "sym" );
const std::string LegacySymbolLibFileExtension( "lib" );
const std::string LegacySymbolDocumentFileExtension( "dcm" );
const std::string LtspiceSymbolExtension( "asy" );
const std::string VrmlFileExtension( "wrl" );
@ -138,12 +137,10 @@ const std::string ProjectFileExtension( "kicad_pro" );
const std::string LegacyProjectFileExtension( "pro" );
const std::string ProjectLocalSettingsFileExtension( "kicad_prl" );
const std::string LegacySchematicFileExtension( "sch" );
const std::string EagleSchematicFileExtension( "sch" );
const std::string CadstarSchematicFileExtension( "csa" );
const std::string CadstarPartsLibraryFileExtension( "lib" );
const std::string KiCadSchematicFileExtension( "kicad_sch" );
const std::string SpiceFileExtension( "cir" );
const std::string LtspiceSchematicExtension( "asc" );
const std::string CadstarNetlistFileExtension( "frp" );
const std::string OrCadPcb2NetlistFileExtension( "net" );
const std::string NetlistFileExtension( "net" );
@ -214,12 +211,6 @@ wxString AllFilesWildcard()
}
wxString SchematicSymbolFileWildcard()
{
return _( "KiCad drawing symbol files" ) + AddFileExtListToFilter( { "sym" } );
}
wxString KiCadSymbolLibFileWildcard()
{
return _( "KiCad symbol library files" )
@ -227,28 +218,6 @@ wxString KiCadSymbolLibFileWildcard()
}
wxString LegacySymbolLibFileWildcard()
{
return _( "KiCad legacy symbol library files" ) + AddFileExtListToFilter( { "lib" } );
}
wxString DatabaseLibFileWildcard()
{
return _( "KiCad database library files" )
+ AddFileExtListToFilter( { DatabaseLibraryFileExtension } );
}
wxString AllSymbolLibFilesWildcard()
{
return _( "All symbol library files" )
+ AddFileExtListToFilter( { KiCadSymbolLibFileExtension,
DatabaseLibraryFileExtension,
"lib" } );
}
wxString ProjectFileWildcard()
{
return _( "KiCad project files" ) + AddFileExtListToFilter( { ProjectFileExtension } );
@ -290,43 +259,12 @@ wxString KiCadSchematicFileWildcard()
}
wxString AltiumSchematicFileWildcard()
{
return _( "Altium schematic files" ) + AddFileExtListToFilter( { "SchDoc" } );
}
wxString CadstarPartsLibraryFileWildcard()
{
return _( "CADSTAR Parts Library files" )
+ AddFileExtListToFilter( { CadstarPartsLibraryFileExtension } );
}
wxString CadstarSchematicArchiveFileWildcard()
{
return _( "CADSTAR Schematic Archive files" ) + AddFileExtListToFilter( { "csa" } );
}
wxString CadstarArchiveFilesWildcard()
{
return _( "CADSTAR Archive files" ) + AddFileExtListToFilter( { "csa", "cpa" } );
}
wxString EagleSchematicFileWildcard()
{
return _( "Eagle XML schematic files" ) + AddFileExtListToFilter( { "sch" } );
}
wxString LtspiceSchematicFileWildcard()
{
return _( "LTspice schematic files" ) + AddFileExtListToFilter( { "asc" } );
}
wxString EagleFilesWildcard()
{
return _( "Eagle XML files" ) + AddFileExtListToFilter( { "sch", "brd" } );

View File

@ -572,7 +572,7 @@ bool DIALOG_SHEET_PROPERTIES::onSheetFilenameChanged( const wxString& aNewFilena
try
{
pi->Save( newAbsoluteFilename, m_sheet, &schematic );
pi->SaveSchematicFile( newAbsoluteFilename, m_sheet, &schematic );
}
catch( const IO_ERROR& ioe )
{

View File

@ -116,6 +116,10 @@ public:
if( aCol == COL_URI )
{
SCH_IO_MGR::SCH_FILE_T pluginType = SCH_IO_MGR::GuessPluginTypeFromLibPath( aValue );
if( pluginType == SCH_IO_MGR::SCH_FILE_UNKNOWN )
pluginType = SCH_IO_MGR::SCH_KICAD;
SetValue( aRow, COL_TYPE, SCH_IO_MGR::ShowType( pluginType ) );
}
}
@ -270,11 +274,38 @@ PANEL_SYM_LIB_TABLE::PANEL_SYM_LIB_TABLE( DIALOG_EDIT_LIBRARY_TABLES* aParent, P
attr = new wxGridCellAttr;
wxString wildcards = AllSymbolLibFilesWildcard()
+ "|" + KiCadSymbolLibFileWildcard()
+ "|" + LegacySymbolLibFileWildcard();
wxString fileFiltersStr;
wxString allWildcardsStr;
for( const SCH_IO_MGR::SCH_FILE_T& fileType : SCH_IO_MGR::SCH_FILE_T_vector )
{
if( fileType == SCH_IO_MGR::SCH_KICAD || fileType == SCH_IO_MGR::SCH_LEGACY )
continue; // this is "Import non-KiCad schematic"
SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( fileType ) );
if( !pi )
continue;
const PLUGIN_FILE_DESC& desc = pi->GetLibraryFileDesc();
if( desc.m_FileExtensions.empty() )
continue;
if( !fileFiltersStr.IsEmpty() )
fileFiltersStr += wxChar( '|' );
fileFiltersStr += desc.FileFilter();
for( const std::string& ext : desc.m_FileExtensions )
allWildcardsStr << wxT( "*." ) << formatWildcardExt( ext ) << wxT( ";" );
}
fileFiltersStr = _( "All supported formats" ) + wxT( "|" ) + allWildcardsStr + wxT( "|" )
+ fileFiltersStr;
attr->SetEditor( new GRID_CELL_PATH_EDITOR( m_parent, aGrid,
&cfg->m_lastSymbolLibDir, wildcards,
&cfg->m_lastSymbolLibDir, fileFiltersStr,
true, m_project->GetProjectPath() ) );
aGrid->SetColAttr( COL_URI, attr );
@ -533,11 +564,32 @@ void PANEL_SYM_LIB_TABLE::OnUpdateUI( wxUpdateUIEvent& event )
void PANEL_SYM_LIB_TABLE::browseLibrariesHandler( wxCommandEvent& event )
{
wxString wildcards = AllSymbolLibFilesWildcard()
+ "|" + KiCadSymbolLibFileWildcard()
+ "|" + LegacySymbolLibFileWildcard()
+ "|" + DatabaseLibFileWildcard()
+ "|" + CadstarPartsLibraryFileWildcard();
wxString fileFiltersStr;
wxString allWildcardsStr;
for( const SCH_IO_MGR::SCH_FILE_T& fileType : SCH_IO_MGR::SCH_FILE_T_vector )
{
SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( fileType ) );
if( !pi )
continue;
const PLUGIN_FILE_DESC& desc = pi->GetLibraryFileDesc();
if( desc.m_FileExtensions.empty() )
continue;
if( !fileFiltersStr.IsEmpty() )
fileFiltersStr += wxChar( '|' );
fileFiltersStr += desc.FileFilter();
for( const std::string& ext : desc.m_FileExtensions )
allWildcardsStr << wxT( "*." ) << formatWildcardExt( ext ) << wxT( ";" );
}
fileFiltersStr = _( "All supported formats" ) + wxT( "|" ) + allWildcardsStr + wxT( "|" )
+ fileFiltersStr;
EESCHEMA_SETTINGS* cfg = Pgm().GetSettingsManager().GetAppSettings<EESCHEMA_SETTINGS>();
@ -546,7 +598,7 @@ void PANEL_SYM_LIB_TABLE::browseLibrariesHandler( wxCommandEvent& event )
if( m_cur_grid == m_project_grid )
openDir = m_lastProjectLibDir;
wxFileDialog dlg( this, _( "Select Library" ), openDir, wxEmptyString, wildcards,
wxFileDialog dlg( this, _( "Select Library" ), openDir, wxEmptyString, fileFiltersStr,
wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE );
if( dlg.ShowModal() == wxID_CANCEL )
@ -595,6 +647,10 @@ void PANEL_SYM_LIB_TABLE::browseLibrariesHandler( wxCommandEvent& event )
// attempt to auto-detect the plugin type
SCH_IO_MGR::SCH_FILE_T pluginType = SCH_IO_MGR::GuessPluginTypeFromLibPath( filePath );
if( pluginType == SCH_IO_MGR::SCH_FILE_UNKNOWN )
pluginType = SCH_IO_MGR::SCH_KICAD;
m_cur_grid->SetCellValue( last_row, COL_TYPE, SCH_IO_MGR::ShowType( pluginType ) );
// try to use path normalized to an environmental variable or project path

View File

@ -82,7 +82,7 @@ static std::unique_ptr<SCHEMATIC> readSchematicFromFile( const std::string& aFil
manager.LoadProject( "" );
schematic->Reset();
schematic->SetProject( &manager.Prj() );
schematic->SetRoot( pi->Load( aFilename, schematic.get() ) );
schematic->SetRoot( pi->LoadSchematicFile( aFilename, schematic.get() ) );
schematic->CurrentSheet().push_back( &schematic->Root() );
SCH_SCREENS screens( schematic->Root() );

View File

@ -128,7 +128,7 @@ SCHEMATIC* EESCHEMA_HELPERS::LoadSchematic( wxString& aFileName, SCH_IO_MGR::SCH
try
{
schematic->SetRoot( pi->Load( aFileName, schematic ) );
schematic->SetRoot( pi->LoadSchematicFile( aFileName, schematic ) );
}
catch( ... )
{

View File

@ -240,7 +240,7 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
{
{
wxBusyCursor busy;
Schematic().SetRoot( pi->Load( fullFileName, &Schematic() ) );
Schematic().SetRoot( pi->LoadSchematicFile( fullFileName, &Schematic() ) );
}
if( !pi->GetError().IsEmpty() )
@ -620,39 +620,37 @@ void SCH_EDIT_FRAME::OnImportProject( wxCommandEvent& aEvent )
bool setProject = Prj().GetProjectFullName().IsEmpty() || Kiface().IsSingle();
wxString path = wxPathOnly( Prj().GetProjectFullName() );
std::list<std::pair<const wxString, const SCH_IO_MGR::SCH_FILE_T>> loaders;
wxString fileFiltersStr;
wxString allWildcardsStr;
// Import Altium schematic files.
loaders.emplace_back( AltiumSchematicFileWildcard(), SCH_IO_MGR::SCH_ALTIUM );
// Import CADSTAR Schematic Archive files.
loaders.emplace_back( CadstarSchematicArchiveFileWildcard(), SCH_IO_MGR::SCH_CADSTAR_ARCHIVE );
// Import Eagle schematic files.
loaders.emplace_back( EagleSchematicFileWildcard(), SCH_IO_MGR::SCH_EAGLE );
// Import LTspice schematic files.
loaders.emplace_back( LtspiceSchematicFileWildcard(), SCH_IO_MGR::SCH_LTSPICE );
wxString fileFilters;
wxString allWildcards;
for( std::pair<const wxString, const SCH_IO_MGR::SCH_FILE_T>& loader : loaders )
for( const SCH_IO_MGR::SCH_FILE_T& fileType : SCH_IO_MGR::SCH_FILE_T_vector )
{
if( !fileFilters.IsEmpty() )
fileFilters += wxChar( '|' );
if( fileType == SCH_IO_MGR::SCH_KICAD || fileType == SCH_IO_MGR::SCH_LEGACY )
continue; // this is "Import non-KiCad schematic"
fileFilters += wxGetTranslation( loader.first );
SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( fileType ) );
SCH_PLUGIN::SCH_PLUGIN_RELEASER plugin( SCH_IO_MGR::FindPlugin( loader.second ) );
wxCHECK( plugin, /*void*/ );
allWildcards += wxS( "*." ) + formatWildcardExt( plugin->GetFileExtension() ) + wxS( ";" );
if( !pi )
continue;
const PLUGIN_FILE_DESC& desc = pi->GetSchematicFileDesc();
if( desc.m_FileExtensions.empty() )
continue;
if( !fileFiltersStr.IsEmpty() )
fileFiltersStr += wxChar( '|' );
fileFiltersStr += desc.FileFilter();
for( const std::string& ext : desc.m_FileExtensions )
allWildcardsStr << wxT( "*." ) << formatWildcardExt( ext ) << wxT( ";" );
}
fileFilters = _( "All supported formats" ) + wxS( "|" ) + allWildcards + wxS( "|" ) +
fileFilters;
fileFiltersStr = _( "All supported formats" ) + wxT( "|" ) + allWildcardsStr + wxT( "|" )
+ fileFiltersStr;
wxFileDialog dlg( this, _( "Import Schematic" ), path, wxEmptyString, fileFilters,
wxFileDialog dlg( this, _( "Import Schematic" ), path, wxEmptyString, fileFiltersStr,
wxFD_OPEN | wxFD_FILE_MUST_EXIST ); // TODO
if( dlg.ShowModal() == wxID_CANCEL )
@ -683,18 +681,23 @@ void SCH_EDIT_FRAME::OnImportProject( wxCommandEvent& aEvent )
SCH_IO_MGR::SCH_FILE_T pluginType = SCH_IO_MGR::SCH_FILE_T::SCH_FILE_UNKNOWN;
for( std::pair<const wxString, const SCH_IO_MGR::SCH_FILE_T>& loader : loaders )
for( const SCH_IO_MGR::SCH_FILE_T& fileType : SCH_IO_MGR::SCH_FILE_T_vector )
{
if( fn.GetExt().CmpNoCase( SCH_IO_MGR::GetFileExtension( loader.second ) ) == 0 )
SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( fileType ) );
if( !pi )
continue;
if( pi->CanReadSchematicFile( fn.GetFullPath() ) )
{
pluginType = loader.second;
pluginType = fileType;
break;
}
}
if( pluginType == SCH_IO_MGR::SCH_FILE_T::SCH_FILE_UNKNOWN )
{
wxLogError( _( "Unexpected file extension: '%s'." ), fn.GetExt() );
wxLogError( _( "No loader can read the specified file: '%s'." ), fn.GetFullPath() );
return;
}
@ -749,11 +752,15 @@ bool SCH_EDIT_FRAME::saveSchematicFile( SCH_SHEET* aSheet, const wxString& aSave
SCH_IO_MGR::SCH_FILE_T pluginType = SCH_IO_MGR::GuessPluginTypeFromSchPath(
schematicFileName.GetFullPath() );
if( pluginType == SCH_IO_MGR::SCH_FILE_UNKNOWN )
pluginType = SCH_IO_MGR::SCH_KICAD;
SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( pluginType ) );
try
{
pi->Save( tempFile, aSheet, &Schematic() );
pi->SaveSchematicFile( tempFile, aSheet, &Schematic() );
success = true;
}
catch( const IO_ERROR& ioe )
@ -1255,7 +1262,7 @@ void SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType )
pi->SetReporter( errorReporter.m_Reporter );
pi->SetProgressReporter( &progressReporter );
Schematic().SetRoot( pi->Load( aFileName, &Schematic() ) );
Schematic().SetRoot( pi->LoadSchematicFile( aFileName, &Schematic() ) );
if( errorReporter.m_Reporter->HasMessage() )
{

View File

@ -32,9 +32,11 @@
#include <sch_plugins/cadstar/cadstar_sch_archive_plugin.h>
#include <sch_plugins/database/sch_database_plugin.h>
#include <sch_plugins/ltspice/ltspice_sch_plugin.h>
#include <wildcards_and_files_ext.h>
#include <common.h> // for ExpandEnvVarSubstitutions
#include <wildcards_and_files_ext.h>
#include <kiway_player.h>
#define FMT_UNIMPLEMENTED _( "Plugin \"%s\" does not implement the \"%s\" function." )
#define FMT_NOTFOUND _( "Plugin type \"%s\" is not found." )
@ -59,12 +61,12 @@ SCH_PLUGIN* SCH_IO_MGR::FindPlugin( SCH_FILE_T aFileType )
switch( aFileType )
{
case SCH_LEGACY: return new SCH_LEGACY_PLUGIN();
case SCH_KICAD: return new SCH_SEXPR_PLUGIN();
case SCH_LEGACY: return new SCH_LEGACY_PLUGIN();
case SCH_ALTIUM: return new SCH_ALTIUM_PLUGIN();
case SCH_CADSTAR_ARCHIVE: return new CADSTAR_SCH_ARCHIVE_PLUGIN();
case SCH_EAGLE: return new SCH_EAGLE_PLUGIN();
case SCH_DATABASE: return new SCH_DATABASE_PLUGIN();
case SCH_EAGLE: return new SCH_EAGLE_PLUGIN();
case SCH_LTSPICE: return new SCH_LTSPICE_PLUGIN();
default: return nullptr;
}
@ -89,12 +91,12 @@ const wxString SCH_IO_MGR::ShowType( SCH_FILE_T aType )
switch( aType )
{
case SCH_LEGACY: return wxString( wxT( "Legacy" ) );
case SCH_KICAD: return wxString( wxT( "KiCad" ) );
case SCH_LEGACY: return wxString( wxT( "Legacy" ) );
case SCH_ALTIUM: return wxString( wxT( "Altium" ) );
case SCH_CADSTAR_ARCHIVE: return wxString( wxT( "CADSTAR Schematic Archive" ) );
case SCH_EAGLE: return wxString( wxT( "EAGLE" ) );
case SCH_DATABASE: return wxString( wxT( "Database" ) );
case SCH_EAGLE: return wxString( wxT( "EAGLE" ) );
case SCH_LTSPICE: return wxString( wxT( "LTspice" ) );
default: return wxString::Format( _( "Unknown SCH_FILE_T value: %d" ),
aType );
@ -108,114 +110,73 @@ SCH_IO_MGR::SCH_FILE_T SCH_IO_MGR::EnumFromStr( const wxString& aType )
// text spellings. If you change the spellings, you will obsolete
// library tables, so don't do change, only additions are ok.
if( aType == wxT( "Legacy" ) )
return SCH_LEGACY;
else if( aType == wxT( "KiCad" ) )
if( aType == wxT( "KiCad" ) )
return SCH_KICAD;
else if( aType == wxT( "Legacy" ) )
return SCH_LEGACY;
else if( aType == wxT( "Altium" ) )
return SCH_ALTIUM;
else if( aType == wxT( "CADSTAR Schematic Archive" ) )
return SCH_CADSTAR_ARCHIVE;
else if( aType == wxT( "EAGLE" ) )
return SCH_EAGLE;
else if( aType == wxT( "Database" ) )
return SCH_DATABASE;
else if( aType == wxT( "EAGLE" ) )
return SCH_EAGLE;
else if( aType == wxT( "LTspice" ) )
return SCH_LTSPICE;
// wxASSERT( blow up here )
return SCH_FILE_T( -1 );
return SCH_FILE_UNKNOWN;
}
const wxString SCH_IO_MGR::GetFileExtension( SCH_FILE_T aFileType )
SCH_IO_MGR::SCH_FILE_T SCH_IO_MGR::GuessPluginTypeFromLibPath( const wxString& aLibPath, int aCtl )
{
wxString ext = wxEmptyString;
SCH_PLUGIN* plugin = FindPlugin( aFileType );
if( plugin != nullptr )
for( const SCH_IO_MGR::SCH_FILE_T& fileType : SCH_IO_MGR::SCH_FILE_T_vector )
{
ext = plugin->GetFileExtension();
ReleasePlugin( plugin );
bool isKiCad = fileType == SCH_IO_MGR::SCH_KICAD || fileType == SCH_IO_MGR::SCH_LEGACY;
if( ( aCtl & KICTL_KICAD_ONLY ) && !isKiCad )
continue;
if( ( aCtl & KICTL_NONKICAD_ONLY ) && isKiCad )
continue;
SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( fileType ) );
if( !pi )
continue;
if( pi->CanReadLibrary( aLibPath ) )
return fileType;
}
return ext;
return SCH_IO_MGR::SCH_FILE_UNKNOWN;
}
const wxString SCH_IO_MGR::GetLibraryFileExtension( SCH_FILE_T aFileType )
SCH_IO_MGR::SCH_FILE_T SCH_IO_MGR::GuessPluginTypeFromSchPath( const wxString& aSchematicPath,
int aCtl )
{
wxString ext = wxEmptyString;
SCH_PLUGIN* plugin = FindPlugin( aFileType );
if( plugin != nullptr )
for( const SCH_IO_MGR::SCH_FILE_T& fileType : SCH_IO_MGR::SCH_FILE_T_vector )
{
ext = plugin->GetLibraryFileExtension();
ReleasePlugin( plugin );
bool isKiCad = fileType == SCH_IO_MGR::SCH_KICAD || fileType == SCH_IO_MGR::SCH_LEGACY;
if( ( aCtl & KICTL_KICAD_ONLY ) && !isKiCad )
continue;
if( ( aCtl & KICTL_NONKICAD_ONLY ) && isKiCad )
continue;
SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( fileType ) );
if( !pi )
continue;
if( pi->CanReadSchematicFile( aSchematicPath ) )
return fileType;
}
return ext;
}
SCH_IO_MGR::SCH_FILE_T SCH_IO_MGR::GuessPluginTypeFromLibPath( const wxString& aLibPath )
{
SCH_FILE_T ret = SCH_KICAD; // default guess, unless detected otherwise.
wxFileName fn( aLibPath );
wxString ext = fn.GetExt().Lower();
// .lib is shared between CADSTAR and Legacy KiCad file formats. Let's read the header
if( ext == LegacySymbolLibFileExtension )
{
wxString fullName = ExpandEnvVarSubstitutions( aLibPath, nullptr );
// Of course the file should exist to be read. If not, use the SCH_LEGACY
// format: it is more usual than SCH_CADSTAR_ARCHIVE
if( !wxFileExists( fullName ) )
return SCH_LEGACY;
for( SCH_FILE_T pluginType : { SCH_LEGACY, SCH_CADSTAR_ARCHIVE } )
{
SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( pluginType ) );
if( pi )
{
if( pi->CheckHeader( fullName ) )
return pluginType;
}
}
// If not found, use the SCH_LEGACY.
return SCH_LEGACY;
}
for( SCH_IO_MGR::SCH_FILE_T piType : SCH_IO_MGR::SCH_FILE_T_vector )
{
if( SCH_IO_MGR::GetLibraryFileExtension( piType ).Lower() == ext )
{
ret = piType;
break;
}
}
return ret;
}
SCH_IO_MGR::SCH_FILE_T SCH_IO_MGR::GuessPluginTypeFromSchPath( const wxString& aSchematicPath )
{
SCH_FILE_T ret = SCH_KICAD; // default guess, unless detected otherwise.
wxFileName fn( aSchematicPath );
if( fn.GetExt() == LegacySchematicFileExtension )
{
ret = SCH_LEGACY;
}
else if( fn.GetExt() == KiCadSchematicFileExtension )
{
ret = SCH_KICAD;
}
return ret;
return SCH_IO_MGR::SCH_FILE_UNKNOWN;
}

View File

@ -1,6 +1,3 @@
#ifndef _SCH_IO_MGR_H_
#define _SCH_IO_MGR_H_
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
@ -23,11 +20,16 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _SCH_IO_MGR_H_
#define _SCH_IO_MGR_H_
#include <richio.h>
#include <import_export.h>
#include <map>
#include <enum_vector.h>
#include <reporter.h>
#include <i18n_utility.h>
#include <plugin_file_desc.h>
class SCH_SHEET;
@ -56,8 +58,8 @@ public:
// clang-format off
DEFINE_ENUM_VECTOR( SCH_FILE_T,
{
SCH_LEGACY, ///< Legacy Eeschema file formats prior to s-expression.
SCH_KICAD, ///< The s-expression version of the schematic.
SCH_LEGACY, ///< Legacy Eeschema file formats prior to s-expression.
SCH_ALTIUM, ///< Altium file format
SCH_CADSTAR_ARCHIVE, ///< CADSTAR Schematic Archive
SCH_DATABASE, ///< KiCad database library
@ -103,40 +105,22 @@ public:
*/
static SCH_FILE_T EnumFromStr( const wxString& aFileType );
/**
* Return the schematic file extension for \a aFileType.
*
* @param aFileType is the #SCH_FILE_T type.
*
* @return the file extension for \a aFileType or an empty string if \a aFileType is invalid.
*/
static const wxString GetFileExtension( SCH_FILE_T aFileType );
/**
* Return the symbol library file extension (if any) for \a aFileType.
*
* @param aFileType is the #SCH_FILE_T type.
*
* @return the file extension for \a aFileType or an empty string if \a aFileType is invalid.
*/
static const wxString GetLibraryFileExtension( SCH_FILE_T aFileType );
/**
* Return a plugin type given a symbol library using the file extension of \a aLibPath.
*/
static SCH_FILE_T GuessPluginTypeFromLibPath( const wxString& aLibPath );
static SCH_FILE_T GuessPluginTypeFromLibPath( const wxString& aLibPath, int aCtl = 0 );
/**
* Return a plugin type given a schematic using the file extension of \a aSchematicPath.
*/
static SCH_FILE_T GuessPluginTypeFromSchPath( const wxString& aSchematicPath );
static SCH_FILE_T GuessPluginTypeFromSchPath( const wxString& aSchematicPath, int aCtl = 0 );
};
/**
* Base class that schematic file and library loading and saving plugins should derive from.
* Implementations can provide either Load() or Save() functions, or both.
* SCH_PLUGINs throw exceptions, so it is best that you wrap your calls to these
* Implementations can provide either LoadSchematicFile() or SaveSchematicFile() functions,
* or both. SCH_PLUGINs throw exceptions, so it is best that you wrap your calls to these
* functions in a try catch block. Plugins throw exceptions because it is illegal
* for them to have any user interface calls in them whatsoever, i.e. no windowing
* or screen printing at all.
@ -144,9 +128,9 @@ public:
* <pre>
* try
* {
* SCH_IO_MGR::Load(...);
* SCH_IO_MGR::LoadSchematicFile(...);
* or
* SCH_IO_MGR::Save(...);
* SCH_IO_MGR::SaveSchematicFile(...);
* }
* catch( const IO_ERROR& ioe )
* {
@ -176,14 +160,26 @@ public:
virtual void SetProgressReporter( PROGRESS_REPORTER* aReporter ) {}
/**
* Return the file extension for the #SCH_PLUGIN.
* Returns schematic file description for the #SCH_PLUGIN.
*/
virtual const wxString GetFileExtension() const = 0;
virtual const PLUGIN_FILE_DESC GetSchematicFileDesc() const;
/**
* Return the library file extension for the #SCH_PLUGIN object.
* Returns symbol library description for the #SCH_PLUGIN.
*/
virtual const wxString GetLibraryFileExtension() const = 0;
virtual const PLUGIN_FILE_DESC GetLibraryFileDesc() const;
/**
* Checks if this SCH_PLUGIN can read the specified schematic file.
* If not overriden, extension check is used.
*/
virtual bool CanReadSchematicFile( const wxString& aFileName ) const;
/**
* Checks if this SCH_PLUGIN can read the specified symbol library file.
* If not overriden, extension check is used.
*/
virtual bool CanReadLibrary( const wxString& aFileName ) const;
/**
* Return the modification hash from the library cache.
@ -226,7 +222,7 @@ public:
* wrong, using line number and character offsets of the input file if
* possible.
*/
virtual SCH_SHEET* Load( const wxString& aFileName, SCHEMATIC* aSchematic,
virtual SCH_SHEET* LoadSchematicFile( const wxString& aFileName, SCHEMATIC* aSchematic,
SCH_SHEET* aAppendToMe = nullptr,
const STRING_UTF8_MAP* aProperties = nullptr );
@ -255,7 +251,8 @@ public:
*
* @throw IO_ERROR if there is a problem saving or exporting.
*/
virtual void Save( const wxString& aFileName, SCH_SHEET* aSheet, SCHEMATIC* aSchematic,
virtual void SaveSchematicFile( const wxString& aFileName, SCH_SHEET* aSheet,
SCHEMATIC* aSchematic,
const STRING_UTF8_MAP* aProperties = nullptr );
/**
@ -493,14 +490,6 @@ public:
return GetAvailableSymbolFields( aNames );
}
/**
* Return true if the first line in @a aFileName begins with the expected header.
*
* @param aFileName is the name of the file to use as input
*
*/
virtual bool CheckHeader( const wxString& aFileName );
/**
* Return an error string to the caller.
*
@ -579,6 +568,13 @@ public:
return plugin;
}
};
protected:
static bool fileStartsWithPrefix( const wxString& aFilePath, const wxString& aPrefix,
bool aIgnoreWhitespace );
static bool fileStartsWithBinaryHeader( const wxString& aFilePath,
const std::vector<uint8_t>& aHeader );
};
#endif // _SCH_IO_MGR_H_

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 CERN
* Copyright (C) 2016-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2016-2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* @author Wayne Stambaugh <stambaughw@gmail.com>
*
@ -21,9 +21,14 @@
*/
#include <string_utf8_map.h>
#include <unordered_set>
#include <sch_io_mgr.h>
#include <wx/translation.h>
#include <wx/filename.h>
#include <wx/dir.h>
#include <wx/wfstream.h>
#include <wx/txtstrm.h>
#define FMT_UNIMPLEMENTED wxT( "Plugin \"%s\" does not implement the \"%s\" function." )
#define NOT_IMPLEMENTED( aCaller ) \
@ -32,20 +37,99 @@
wxString::FromUTF8( aCaller ).GetData() ) );
const PLUGIN_FILE_DESC SCH_PLUGIN::GetSchematicFileDesc() const
{
return PLUGIN_FILE_DESC( wxEmptyString, {} );
}
const PLUGIN_FILE_DESC SCH_PLUGIN::GetLibraryFileDesc() const
{
return PLUGIN_FILE_DESC( wxEmptyString, {} );
}
bool SCH_PLUGIN::CanReadSchematicFile( const wxString& aFileName ) const
{
const std::vector<std::string>& exts = GetSchematicFileDesc().m_FileExtensions;
wxString fileExt = wxFileName( aFileName ).GetExt().MakeLower();
for( const std::string& ext : exts )
{
if( fileExt == wxString( ext ).Lower() )
return true;
}
return false;
}
bool SCH_PLUGIN::CanReadLibrary( const wxString& aFileName ) const
{
const PLUGIN_FILE_DESC& desc = GetLibraryFileDesc();
if( desc.m_IsFile )
{
const std::vector<std::string>& exts = desc.m_FileExtensions;
wxString fileExt = wxFileName( aFileName ).GetExt().MakeLower();
for( const std::string& ext : exts )
{
if( fileExt == wxString( ext ).Lower() )
return true;
}
}
else
{
wxDir dir( aFileName );
if( !dir.IsOpened() )
return false;
std::vector<std::string> exts = desc.m_ExtensionsInDir;
std::unordered_set<wxString> lowerExts;
for( const std::string& ext : exts )
lowerExts.emplace( wxString( ext ).MakeLower() );
wxString filenameStr;
bool cont = dir.GetFirst( &filenameStr, wxEmptyString, wxDIR_FILES | wxDIR_HIDDEN );
while( cont )
{
wxString ext = wxS( "" );
int idx = filenameStr.Find( '.', true );
if( idx != -1 )
ext = filenameStr.Mid( idx + 1 ).MakeLower();
if( lowerExts.count( ext ) )
return true;
cont = dir.GetNext( &filenameStr );
}
}
return false;
}
void SCH_PLUGIN::SaveLibrary( const wxString& aFileName, const STRING_UTF8_MAP* aProperties )
{
NOT_IMPLEMENTED( __FUNCTION__ );
}
SCH_SHEET* SCH_PLUGIN::Load( const wxString& aFileName, SCHEMATIC* aSchematic,
SCH_SHEET* SCH_PLUGIN::LoadSchematicFile( const wxString& aFileName, SCHEMATIC* aSchematic,
SCH_SHEET* aAppendToMe, const STRING_UTF8_MAP* aProperties )
{
NOT_IMPLEMENTED( __FUNCTION__ );
}
void SCH_PLUGIN::Save( const wxString& aFileName, SCH_SHEET* aSheet, SCHEMATIC* aSchematic,
void SCH_PLUGIN::SaveSchematicFile( const wxString& aFileName, SCH_SHEET* aSheet, SCHEMATIC* aSchematic,
const STRING_UTF8_MAP* aProperties )
{
// not pure virtual so that plugins only have to implement subset of the SCH_PLUGIN interface.
@ -128,15 +212,54 @@ void SCH_PLUGIN::SymbolLibOptions( STRING_UTF8_MAP* aListToAppendTo ) const
}
bool SCH_PLUGIN::CheckHeader( const wxString& aFileName )
{
// not pure virtual so that plugins only have to implement subset of the SCH_PLUGIN interface.
NOT_IMPLEMENTED( __FUNCTION__ );
}
const wxString& SCH_PLUGIN::GetError() const
{
// not pure virtual so that plugins only have to implement subset of the SCH_PLUGIN interface.
NOT_IMPLEMENTED( __FUNCTION__ );
}
bool SCH_PLUGIN::fileStartsWithPrefix( const wxString& aFilePath, const wxString& aPrefix,
bool aIgnoreWhitespace )
{
wxFFileInputStream input( aFilePath );
if( input.IsOk() && !input.Eof() )
{
// Find first non-empty line
wxTextInputStream text( input );
wxString line = text.ReadLine();
if( aIgnoreWhitespace )
{
while( line.IsEmpty() )
line = text.ReadLine().Trim( false /*trim from left*/ );
}
if( line.StartsWith( aPrefix ) )
return true;
}
return false;
}
bool SCH_PLUGIN::fileStartsWithBinaryHeader( const wxString& aFilePath,
const std::vector<uint8_t>& aHeader )
{
wxFFileInputStream input( aFilePath );
if( input.IsOk() && !input.Eof() )
{
if( input.GetLength() < aHeader.size() )
return false;
std::vector<uint8_t> parsedHeader( aHeader.size() );
if( !input.ReadAll( parsedHeader.data(), parsedHeader.size() ) )
return false;
return parsedHeader == aHeader;
}
return false;
}

View File

@ -160,32 +160,12 @@ const wxString SCH_ALTIUM_PLUGIN::GetName() const
}
const wxString SCH_ALTIUM_PLUGIN::GetFileExtension() const
{
return "SchDoc";
}
const wxString SCH_ALTIUM_PLUGIN::GetLibraryFileExtension() const
{
return "SchLib";
}
int SCH_ALTIUM_PLUGIN::GetModifyHash() const
{
return 0;
}
bool SCH_ALTIUM_PLUGIN::CheckHeader( const wxString& aFileName )
{
// TODO
return true;
}
wxString SCH_ALTIUM_PLUGIN::getLibName()
{
if( m_libName.IsEmpty() )
@ -218,8 +198,9 @@ wxFileName SCH_ALTIUM_PLUGIN::getLibFileName()
}
SCH_SHEET* SCH_ALTIUM_PLUGIN::Load( const wxString& aFileName, SCHEMATIC* aSchematic,
SCH_SHEET* aAppendToMe, const STRING_UTF8_MAP* aProperties )
SCH_SHEET* SCH_ALTIUM_PLUGIN::LoadSchematicFile( const wxString& aFileName, SCHEMATIC* aSchematic,
SCH_SHEET* aAppendToMe,
const STRING_UTF8_MAP* aProperties )
{
wxCHECK( !aFileName.IsEmpty() && aSchematic, nullptr );

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 Thomas Pointhuber <thomas.pointhuber@gmx.at>
* Copyright (C) 2021-2022 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2021-2023 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
@ -55,18 +55,22 @@ public:
void SetReporter( REPORTER* aReporter ) override { m_reporter = aReporter; }
const wxString GetFileExtension() const override;
const PLUGIN_FILE_DESC GetSchematicFileDesc() const override
{
return PLUGIN_FILE_DESC( _HKI( "Altium schematic files" ), { "SchDoc" } );
}
const wxString GetLibraryFileExtension() const override;
/*const PLUGIN_FILE_DESC GetLibraryFileDesc() const override
{
return PLUGIN_FILE_DESC( _HKI( "Altium schematic library files" ), { "SchLib" } );
}*/
int GetModifyHash() const override;
SCH_SHEET* Load( const wxString& aFileName, SCHEMATIC* aSchematic,
SCH_SHEET* LoadSchematicFile( const wxString& aFileName, SCHEMATIC* aSchematic,
SCH_SHEET* aAppendToMe = nullptr,
const STRING_UTF8_MAP* aProperties = nullptr ) override;
bool CheckHeader( const wxString& aFileName ) override;
// unimplemented functions. Will trigger a not_implemented IO error.
//void SaveLibrary( const wxString& aFileName, const PROPERTIES* aProperties = NULL ) override;

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 Roberto Fernandez Bautista <roberto.fer.bau@gmail.com>
* Copyright (C) 2020-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2020-2023 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
@ -44,26 +44,16 @@ const wxString CADSTAR_SCH_ARCHIVE_PLUGIN::GetName() const
}
const wxString CADSTAR_SCH_ARCHIVE_PLUGIN::GetFileExtension() const
{
return CadstarSchematicFileExtension;
}
const wxString CADSTAR_SCH_ARCHIVE_PLUGIN::GetLibraryFileExtension() const
{
return CadstarPartsLibraryFileExtension;
}
int CADSTAR_SCH_ARCHIVE_PLUGIN::GetModifyHash() const
{
return 0;
}
SCH_SHEET* CADSTAR_SCH_ARCHIVE_PLUGIN::Load( const wxString& aFileName, SCHEMATIC* aSchematic,
SCH_SHEET* aAppendToMe, const STRING_UTF8_MAP* aProperties )
SCH_SHEET* CADSTAR_SCH_ARCHIVE_PLUGIN::LoadSchematicFile( const wxString& aFileName,
SCHEMATIC* aSchematic,
SCH_SHEET* aAppendToMe,
const STRING_UTF8_MAP* aProperties )
{
wxCHECK( !aFileName.IsEmpty() && aSchematic, nullptr );
@ -174,14 +164,6 @@ SCH_SHEET* CADSTAR_SCH_ARCHIVE_PLUGIN::Load( const wxString& aFileName, SCHEMATI
}
bool CADSTAR_SCH_ARCHIVE_PLUGIN::CheckHeader( const wxString& aFileName )
{
// TODO: write a parser for the cpa header. For now assume it is valid
// and throw exceptions when parsing
return true;
}
void CADSTAR_SCH_ARCHIVE_PLUGIN::EnumerateSymbolLib( wxArrayString& aSymbolNameList,
const wxString& aLibraryPath,
const STRING_UTF8_MAP* aProperties )

View File

@ -31,6 +31,7 @@
#include <sch_io_mgr.h>
#include <reporter.h>
#include <lib_symbol.h>
#include <wildcards_and_files_ext.h>
class SCH_SHEET;
@ -57,18 +58,24 @@ public:
m_progressReporter = aReporter;
}
const wxString GetFileExtension() const override;
const PLUGIN_FILE_DESC GetSchematicFileDesc() const override
{
return PLUGIN_FILE_DESC( _HKI( "CADSTAR Schematic Archive files" ),
{ CadstarSchematicFileExtension } );
}
const wxString GetLibraryFileExtension() const override;
const PLUGIN_FILE_DESC GetLibraryFileDesc() const override
{
return PLUGIN_FILE_DESC( _HKI( "CADSTAR Parts Library files" ),
{ CadstarPartsLibraryFileExtension } );
}
int GetModifyHash() const override;
SCH_SHEET* Load( const wxString& aFileName, SCHEMATIC* aSchematic,
SCH_SHEET* LoadSchematicFile( const wxString& aFileName, SCHEMATIC* aSchematic,
SCH_SHEET* aAppendToMe = nullptr,
const STRING_UTF8_MAP* aProperties = nullptr ) override;
bool CheckHeader( const wxString& aFileName ) override;
void EnumerateSymbolLib( wxArrayString& aSymbolNameList,
const wxString& aLibraryPath,
const STRING_UTF8_MAP* aProperties = nullptr ) override;

View File

@ -207,13 +207,6 @@ void SCH_DATABASE_PLUGIN::GetDefaultSymbolFields( std::vector<wxString>& aNames
}
bool SCH_DATABASE_PLUGIN::CheckHeader( const wxString& aFileName )
{
// TODO: Implement this sometime; but CheckHeader isn't even called...
return true;
}
bool SCH_DATABASE_PLUGIN::TestConnection( wxString* aErrorMsg )
{
if( m_conn && m_conn->IsConnected() )

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Jon Evans <jon@craftyjon.com>
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2022-2023 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
@ -49,15 +49,10 @@ public:
return wxT( "Database library" );
}
const wxString GetLibraryFileExtension() const override
const PLUGIN_FILE_DESC GetLibraryFileDesc() const override
{
return DatabaseLibraryFileExtension;
}
const wxString GetFileExtension() const override
{
wxFAIL_MSG( "Database libraries are not schematic files! Fix call site." );
return DatabaseLibraryFileExtension;
return PLUGIN_FILE_DESC( _HKI( "KiCad database library files" ),
{ DatabaseLibraryFileExtension } );
}
int GetModifyHash() const override { return 0; }
@ -81,8 +76,6 @@ public:
void GetDefaultSymbolFields( std::vector<wxString>& aNames ) override;
bool CheckHeader( const wxString& aFileName ) override;
// Database libraries can never be written using the symbol editing API
bool IsSymbolLibWritable( const wxString& aLibraryPath ) override
{

View File

@ -375,18 +375,6 @@ const wxString SCH_EAGLE_PLUGIN::GetName() const
}
const wxString SCH_EAGLE_PLUGIN::GetFileExtension() const
{
return wxT( "sch" );
}
const wxString SCH_EAGLE_PLUGIN::GetLibraryFileExtension() const
{
return wxT( "lbr" );
}
int SCH_EAGLE_PLUGIN::GetModifyHash() const
{
return 0;
@ -413,8 +401,9 @@ void SCH_EAGLE_PLUGIN::checkpoint()
}
SCH_SHEET* SCH_EAGLE_PLUGIN::Load( const wxString& aFileName, SCHEMATIC* aSchematic,
SCH_SHEET* aAppendToMe, const STRING_UTF8_MAP* aProperties )
SCH_SHEET* SCH_EAGLE_PLUGIN::LoadSchematicFile( const wxString& aFileName, SCHEMATIC* aSchematic,
SCH_SHEET* aAppendToMe,
const STRING_UTF8_MAP* aProperties )
{
wxASSERT( !aFileName || aSchematic != nullptr );
LOCALE_IO toggle; // toggles on, then off, the C locale.
@ -2724,23 +2713,43 @@ void SCH_EAGLE_PLUGIN::adjustNetLabels()
}
bool SCH_EAGLE_PLUGIN::CheckHeader( const wxString& aFileName )
bool SCH_EAGLE_PLUGIN::CanReadSchematicFile( const wxString& aFileName ) const
{
// Open file and check first line
wxTextFile tempFile;
if( !SCH_PLUGIN::CanReadSchematicFile( aFileName ) )
return false;
tempFile.Open( aFileName );
wxString firstline;
return checkHeader( aFileName );
}
// read the first line
firstline = tempFile.GetFirstLine();
wxString secondline = tempFile.GetNextLine();
wxString thirdline = tempFile.GetNextLine();
tempFile.Close();
return firstline.StartsWith( wxT( "<?xml" ) )
&& secondline.StartsWith( wxT( "<!DOCTYPE eagle SYSTEM" ) )
&& thirdline.StartsWith( wxT( "<eagle version" ) );
bool SCH_EAGLE_PLUGIN::CanReadLibrary( const wxString& aFileName ) const
{
if( !SCH_PLUGIN::CanReadLibrary( aFileName ) )
return false;
return checkHeader( aFileName );
}
bool SCH_EAGLE_PLUGIN::checkHeader( const wxString& aFileName ) const
{
wxFileInputStream input( aFileName );
if( !input.IsOk() )
return false;
wxTextInputStream text( input );
for( int i = 0; i < 3; i++ )
{
if( input.Eof() )
return false;
if( text.ReadLine().Contains( wxS( "<!DOCTYPE eagle" ) ) )
return true;
}
return false;
}

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2017 CERN
* Copyright (C) 2021-2022 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2021-2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* @author Alejandro García Montoro <alejandro.garciamontoro@gmail.com>
* @author Maciej Suminski <maciej.suminski@cern.ch>
@ -95,21 +95,30 @@ public:
m_progressReporter = aReporter;
}
const wxString GetFileExtension() const override;
const PLUGIN_FILE_DESC GetSchematicFileDesc() const override
{
return PLUGIN_FILE_DESC( _HKI( "Eagle XML schematic files" ), { "sch" } );
}
const wxString GetLibraryFileExtension() const override;
/*const PLUGIN_FILE_DESC GetLibraryFileDesc() const override
{
return PLUGIN_FILE_DESC( _HKI( "Eagle XML library files" ), { "lbr" } );
}*/
bool CanReadSchematicFile( const wxString& aFileName ) const override;
bool CanReadLibrary( const wxString& aFileName ) const override;
int GetModifyHash() const override;
SCH_SHEET* Load( const wxString& aFileName, SCHEMATIC* aSchematic,
SCH_SHEET* LoadSchematicFile( const wxString& aFileName, SCHEMATIC* aSchematic,
SCH_SHEET* aAppendToMe = nullptr,
const STRING_UTF8_MAP* aProperties = nullptr ) override;
bool CheckHeader( const wxString& aFileName ) override;
private:
void checkpoint();
bool checkHeader( const wxString& aFileName ) const;
void loadDrawing( wxXmlNode* aDrawingNode );
void loadLayerDefs( wxXmlNode* aLayers );
void loadSchematic( wxXmlNode* aSchematicNode );

View File

@ -97,8 +97,9 @@ void SCH_SEXPR_PLUGIN::init( SCHEMATIC* aSchematic, const STRING_UTF8_MAP* aProp
}
SCH_SHEET* SCH_SEXPR_PLUGIN::Load( const wxString& aFileName, SCHEMATIC* aSchematic,
SCH_SHEET* aAppendToMe, const STRING_UTF8_MAP* aProperties )
SCH_SHEET* SCH_SEXPR_PLUGIN::LoadSchematicFile( const wxString& aFileName, SCHEMATIC* aSchematic,
SCH_SHEET* aAppendToMe,
const STRING_UTF8_MAP* aProperties )
{
wxASSERT( !aFileName || aSchematic != nullptr );
@ -328,7 +329,8 @@ void SCH_SEXPR_PLUGIN::LoadContent( LINE_READER& aReader, SCH_SHEET* aSheet, int
}
void SCH_SEXPR_PLUGIN::Save( const wxString& aFileName, SCH_SHEET* aSheet, SCHEMATIC* aSchematic,
void SCH_SEXPR_PLUGIN::SaveSchematicFile( const wxString& aFileName, SCH_SHEET* aSheet,
SCHEMATIC* aSchematic,
const STRING_UTF8_MAP* aProperties )
{
wxCHECK_RET( aSheet != nullptr, "NULL SCH_SHEET object." );
@ -1613,21 +1615,6 @@ void SCH_SEXPR_PLUGIN::SaveLibrary( const wxString& aLibraryPath, const STRING_U
}
bool SCH_SEXPR_PLUGIN::CheckHeader( const wxString& aFileName )
{
// Open file and check first line
wxTextFile tempFile;
tempFile.Open( aFileName );
wxString firstline;
// read the first line
firstline = tempFile.GetFirstLine();
tempFile.Close();
return firstline.StartsWith( wxS( "EESchema" ) );
}
bool SCH_SEXPR_PLUGIN::IsSymbolLibWritable( const wxString& aLibraryPath )
{
wxFileName fn( aLibraryPath );

View File

@ -1,6 +1,3 @@
#ifndef _SCH_SEXPR_PLUGIN_H_
#define _SCH_SEXPR_PLUGIN_H_
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
@ -23,11 +20,15 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _SCH_SEXPR_PLUGIN_H_
#define _SCH_SEXPR_PLUGIN_H_
#include <memory>
#include <sch_io_mgr.h>
#include <sch_file_versions.h>
#include <sch_sheet_path.h>
#include <stack>
#include <wildcards_and_files_ext.h>
class KIWAY;
@ -71,14 +72,16 @@ public:
return wxT( "Eeschema s-expression" );
}
const wxString GetFileExtension() const override
const PLUGIN_FILE_DESC GetSchematicFileDesc() const override
{
return wxT( "kicad_sch" );
return PLUGIN_FILE_DESC( _HKI( "KiCad s-expression schematic files" ),
{ KiCadSchematicFileExtension } );
}
const wxString GetLibraryFileExtension() const override
const PLUGIN_FILE_DESC GetLibraryFileDesc() const override
{
return wxT( "kicad_sym" );
return PLUGIN_FILE_DESC( _HKI( "KiCad symbol library files" ),
{ KiCadSymbolLibFileExtension } );
}
void SetProgressReporter( PROGRESS_REPORTER* aReporter ) override
@ -95,14 +98,14 @@ public:
int GetModifyHash() const override;
SCH_SHEET* Load( const wxString& aFileName, SCHEMATIC* aSchematic,
SCH_SHEET* LoadSchematicFile( const wxString& aFileName, SCHEMATIC* aSchematic,
SCH_SHEET* aAppendToMe = nullptr,
const STRING_UTF8_MAP* aProperties = nullptr ) override;
void LoadContent( LINE_READER& aReader, SCH_SHEET* aSheet,
int aVersion = SEXPR_SCHEMATIC_FILE_VERSION );
void Save( const wxString& aFileName, SCH_SHEET* aSheet, SCHEMATIC* aSchematic,
void SaveSchematicFile( const wxString& aFileName, SCH_SHEET* aSheet, SCHEMATIC* aSchematic,
const STRING_UTF8_MAP* aProperties = nullptr ) override;
void Format( SCH_SHEET* aSheet );
@ -129,7 +132,6 @@ public:
void SaveLibrary( const wxString& aLibraryPath,
const STRING_UTF8_MAP* aProperties = nullptr ) override;
bool CheckHeader( const wxString& aFileName ) override;
bool IsSymbolLibWritable( const wxString& aLibraryPath ) override;
void GetAvailableSymbolFields( std::vector<wxString>& aNames ) override;

View File

@ -121,8 +121,9 @@ void SCH_LEGACY_PLUGIN::checkpoint()
}
SCH_SHEET* SCH_LEGACY_PLUGIN::Load( const wxString& aFileName, SCHEMATIC* aSchematic,
SCH_SHEET* aAppendToMe, const STRING_UTF8_MAP* aProperties )
SCH_SHEET* SCH_LEGACY_PLUGIN::LoadSchematicFile( const wxString& aFileName, SCHEMATIC* aSchematic,
SCH_SHEET* aAppendToMe,
const STRING_UTF8_MAP* aProperties )
{
wxASSERT( !aFileName || aSchematic != nullptr );
@ -1450,7 +1451,8 @@ std::shared_ptr<BUS_ALIAS> SCH_LEGACY_PLUGIN::loadBusAlias( LINE_READER& aReader
}
void SCH_LEGACY_PLUGIN::Save( const wxString& aFileName, SCH_SHEET* aSheet, SCHEMATIC* aSchematic,
void SCH_LEGACY_PLUGIN::SaveSchematicFile( const wxString& aFileName, SCH_SHEET* aSheet,
SCHEMATIC* aSchematic,
const STRING_UTF8_MAP* aProperties )
{
wxCHECK_RET( aSheet != nullptr, "NULL SCH_SHEET object." );
@ -2231,18 +2233,21 @@ void SCH_LEGACY_PLUGIN::SaveLibrary( const wxString& aLibraryPath, const STRING_
}
bool SCH_LEGACY_PLUGIN::CheckHeader( const wxString& aFileName )
bool SCH_LEGACY_PLUGIN::CanReadSchematicFile( const wxString& aFileName ) const
{
// Open file and check first line
wxTextFile tempFile;
if( !SCH_PLUGIN::CanReadSchematicFile( aFileName ) )
return false;
tempFile.Open( aFileName );
wxString firstline;
// read the first line
firstline = tempFile.GetFirstLine();
tempFile.Close();
return fileStartsWithPrefix( aFileName, wxT( "EESchema" ), true );
}
return firstline.StartsWith( wxS( "EESchema" ) );
bool SCH_LEGACY_PLUGIN::CanReadLibrary( const wxString& aFileName ) const
{
if( !SCH_PLUGIN::CanReadLibrary( aFileName ) )
return false;
return fileStartsWithPrefix( aFileName, wxT( "EESchema" ), true );
}

View File

@ -1,11 +1,8 @@
#ifndef _SCH_LEGACY_PLUGIN_H_
#define _SCH_LEGACY_PLUGIN_H_
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 CERN
* Copyright (C) 2016-2022 KiCad Developers, see change_log.txt for contributors.
* Copyright (C) 2016-2023 KiCad Developers, see change_log.txt for contributors.
*
* @author Wayne Stambaugh <stambaughw@gmail.com>
*
@ -23,10 +20,14 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _SCH_LEGACY_PLUGIN_H_
#define _SCH_LEGACY_PLUGIN_H_
#include <memory>
#include <sch_io_mgr.h>
#include <stack>
#include <general.h> // for EESCHEMA_VERSION definition
#include <wildcards_and_files_ext.h>
class KIWAY;
@ -72,16 +73,22 @@ public:
return wxT( "Eeschema-Legacy" );
}
const wxString GetFileExtension() const override
const PLUGIN_FILE_DESC GetSchematicFileDesc() const override
{
return wxT( "sch" );
return PLUGIN_FILE_DESC( _HKI( "KiCad legacy schematic files" ),
{ LegacySchematicFileExtension } );
}
const wxString GetLibraryFileExtension() const override
const PLUGIN_FILE_DESC GetLibraryFileDesc() const override
{
return wxT( "lib" );
return PLUGIN_FILE_DESC( _HKI( "KiCad legacy symbol library files" ),
{ LegacySymbolLibFileExtension } );
}
bool CanReadSchematicFile( const wxString& aFileName ) const override;
bool CanReadLibrary( const wxString& aFileName ) const override;
void SetProgressReporter( PROGRESS_REPORTER* aReporter ) override
{
m_progressReporter = aReporter;
@ -102,14 +109,14 @@ public:
int GetModifyHash() const override;
SCH_SHEET* Load( const wxString& aFileName, SCHEMATIC* aSchematic,
SCH_SHEET* LoadSchematicFile( const wxString& aFileName, SCHEMATIC* aSchematic,
SCH_SHEET* aAppendToMe = nullptr,
const STRING_UTF8_MAP* aProperties = nullptr ) override;
void LoadContent( LINE_READER& aReader, SCH_SCREEN* aScreen,
int version = EESCHEMA_VERSION );
void Save( const wxString& aFileName, SCH_SHEET* aScreen, SCHEMATIC* aSchematic,
void SaveSchematicFile( const wxString& aFileName, SCH_SHEET* aScreen, SCHEMATIC* aSchematic,
const STRING_UTF8_MAP* aProperties = nullptr ) override;
void Format( SCH_SHEET* aSheet );
@ -135,7 +142,6 @@ public:
void SaveLibrary( const wxString& aLibraryPath,
const STRING_UTF8_MAP* aProperties = nullptr ) override;
bool CheckHeader( const wxString& aFileName ) override;
bool IsSymbolLibWritable( const wxString& aLibraryPath ) override;
const wxString& GetError() const override { return m_error; }

View File

@ -38,26 +38,15 @@ const wxString SCH_LTSPICE_PLUGIN::GetName() const
}
const wxString SCH_LTSPICE_PLUGIN::GetFileExtension() const
{
return wxT( "asc" );
}
const wxString SCH_LTSPICE_PLUGIN::GetLibraryFileExtension() const
{
return wxT( "lib" );
}
int SCH_LTSPICE_PLUGIN::GetModifyHash() const
{
return 0;
}
SCH_SHEET* SCH_LTSPICE_PLUGIN::Load( const wxString& aFileName, SCHEMATIC* aSchematic,
SCH_SHEET* aAppendToMe, const STRING_UTF8_MAP* aProperties )
SCH_SHEET* SCH_LTSPICE_PLUGIN::LoadSchematicFile( const wxString& aFileName, SCHEMATIC* aSchematic,
SCH_SHEET* aAppendToMe,
const STRING_UTF8_MAP* aProperties )
{
wxASSERT( !aFileName || aSchematic );
@ -125,9 +114,3 @@ SCH_SHEET* SCH_LTSPICE_PLUGIN::Load( const wxString& aFileName, SCHEMATIC* aSche
return rootSheet;
}
bool SCH_LTSPICE_PLUGIN::CheckHeader( const wxString& aFileName )
{
return true;
}

View File

@ -53,18 +53,22 @@ public:
m_progressReporter = aReporter;
}
const wxString GetFileExtension() const override;
const PLUGIN_FILE_DESC GetSchematicFileDesc() const override
{
return PLUGIN_FILE_DESC( _HKI( "LTspice schematic files" ), { "asc" } );
}
const wxString GetLibraryFileExtension() const override;
/*const PLUGIN_FILE_DESC GetLibraryFileDesc() const override
{
return PLUGIN_FILE_DESC( _HKI( "LTspice library files" ), { "lib" } );
}*/
int GetModifyHash() const override;
SCH_SHEET* Load( const wxString& aFileName, SCHEMATIC* aSchematic,
SCH_SHEET* LoadSchematicFile( const wxString& aFileName, SCHEMATIC* aSchematic,
SCH_SHEET* aAppendToMe = nullptr,
const STRING_UTF8_MAP* aProperties = nullptr ) override;
bool CheckHeader( const wxString& aFileName ) override;
private:
REPORTER* m_reporter; // current reporter for warnings/errors
PROGRESS_REPORTER* m_progressReporter; // optional; may be nullptr

View File

@ -111,7 +111,12 @@ bool SCH_EDIT_FRAME::LoadSheetFromFile( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHier
wxString msg;
wxFileName currentSheetFileName;
bool libTableChanged = false;
SCH_IO_MGR::SCH_FILE_T schFileType = SCH_IO_MGR::GuessPluginTypeFromSchPath( aFileName );
if( schFileType == SCH_IO_MGR::SCH_FILE_UNKNOWN )
schFileType = SCH_IO_MGR::SCH_KICAD;
SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( schFileType ) );
std::unique_ptr< SCH_SHEET> tmpSheet = std::make_unique<SCH_SHEET>( &Schematic() );
@ -134,12 +139,12 @@ bool SCH_EDIT_FRAME::LoadSheetFromFile( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHier
{
if( aSheet->GetScreen() != nullptr )
{
tmpSheet.reset( pi->Load( fullFilename, &Schematic() ) );
tmpSheet.reset( pi->LoadSchematicFile( fullFilename, &Schematic() ) );
}
else
{
tmpSheet->SetFileName( fullFilename );
pi->Load( fullFilename, &Schematic(), tmpSheet.get() );
pi->LoadSchematicFile( fullFilename, &Schematic(), tmpSheet.get() );
}
if( !pi->GetError().IsEmpty() )

View File

@ -1071,6 +1071,9 @@ bool SYMBOL_EDIT_FRAME::saveLibrary( const wxString& aLibrary, bool aNewFile )
{
fn = prj.SchSymbolLibTable()->GetFullURI( aLibrary );
fileType = SCH_IO_MGR::GuessPluginTypeFromLibPath( fn.GetFullPath() );
if( fileType == SCH_IO_MGR::SCH_FILE_UNKNOWN )
fileType = SCH_IO_MGR::SCH_KICAD;
}
// Verify the user has write privileges before attempting to save the library file.

View File

@ -48,12 +48,38 @@ void SYMBOL_EDIT_FRAME::ImportSymbol()
return;
}
wxString wildcards = AllSymbolLibFilesWildcard()
+ "|" + KiCadSymbolLibFileWildcard()
+ "|" + LegacySymbolLibFileWildcard();
wxString fileFiltersStr;
wxString allWildcardsStr;
wxFileDialog dlg( this, _( "Import Symbol" ), m_mruPath, wxEmptyString,
wildcards, wxFD_OPEN | wxFD_FILE_MUST_EXIST );
for( const SCH_IO_MGR::SCH_FILE_T& fileType : SCH_IO_MGR::SCH_FILE_T_vector )
{
if( fileType == SCH_IO_MGR::SCH_KICAD || fileType == SCH_IO_MGR::SCH_LEGACY )
continue; // this is "Import non-KiCad schematic"
SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( fileType ) );
if( !pi )
continue;
const PLUGIN_FILE_DESC& desc = pi->GetLibraryFileDesc();
if( desc.m_FileExtensions.empty() )
continue;
if( !fileFiltersStr.IsEmpty() )
fileFiltersStr += wxChar( '|' );
fileFiltersStr += desc.FileFilter();
for( const std::string& ext : desc.m_FileExtensions )
allWildcardsStr << wxT( "*." ) << formatWildcardExt( ext ) << wxT( ";" );
}
fileFiltersStr = _( "All supported formats" ) + wxT( "|" ) + allWildcardsStr + wxT( "|" )
+ fileFiltersStr;
wxFileDialog dlg( this, _( "Import Symbol" ), m_mruPath, wxEmptyString, fileFiltersStr,
wxFD_OPEN | wxFD_FILE_MUST_EXIST );
if( dlg.ShowModal() == wxID_CANCEL )
return;
@ -69,6 +95,14 @@ void SYMBOL_EDIT_FRAME::ImportSymbol()
wxArrayString symbols;
SCH_IO_MGR::SCH_FILE_T piType = SCH_IO_MGR::GuessPluginTypeFromLibPath( fn.GetFullPath() );
if( piType == SCH_IO_MGR::SCH_FILE_UNKNOWN )
{
msg.Printf( _( "Unable to find a reader for '%s'." ), fn.GetFullPath() );
DisplayError( this, msg );
return;
}
SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( piType ) );
// TODO dialog to select the symbol to be imported if there is more than one
@ -140,6 +174,10 @@ void SYMBOL_EDIT_FRAME::ExportSymbol()
LIB_SYMBOL* old_symbol = nullptr;
SCH_IO_MGR::SCH_FILE_T pluginType = SCH_IO_MGR::GuessPluginTypeFromLibPath( fn.GetFullPath() );
if( pluginType == SCH_IO_MGR::SCH_FILE_UNKNOWN )
pluginType = SCH_IO_MGR::SCH_KICAD;
SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( pluginType ) );
if( fn.FileExists() )

View File

@ -68,8 +68,8 @@ void SYMBOL_LIB_TABLE_ROW::SetType( const wxString& aType )
{
type = SCH_IO_MGR::EnumFromStr( aType );
if( SCH_IO_MGR::SCH_FILE_T( -1 ) == type )
type = SCH_IO_MGR::SCH_LEGACY;
if( type == SCH_IO_MGR::SCH_FILE_UNKNOWN )
type = SCH_IO_MGR::SCH_KICAD;
plugin.release();
}

View File

@ -736,6 +736,10 @@ bool SYMBOL_LIBRARY_MANAGER::addLibrary( const wxString& aFilePath, bool aCreate
wxString relPath = NormalizePath( aFilePath, &Pgm().GetLocalEnvVariables(), &m_frame.Prj() );
SCH_IO_MGR::SCH_FILE_T schFileType = SCH_IO_MGR::GuessPluginTypeFromLibPath( aFilePath );
if( schFileType == SCH_IO_MGR::SCH_FILE_UNKNOWN )
schFileType = SCH_IO_MGR::SCH_LEGACY;
wxString typeName = SCH_IO_MGR::ShowType( schFileType );
SYMBOL_LIB_TABLE_ROW* libRow = new SYMBOL_LIB_TABLE_ROW( libName, relPath, typeName );
aTable->InsertRow( libRow );

View File

@ -0,0 +1,59 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 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
*/
#ifndef PLUGIN_FILE_DESC_H_
#define PLUGIN_FILE_DESC_H_
#include <vector>
#include <string>
#include <wx/string.h>
/**
* Container that describes file type info
*/
struct PLUGIN_FILE_DESC
{
wxString m_Description; ///< Description shown in the file picker dialog
std::vector<std::string> m_FileExtensions; ///< Filter used for file pickers if m_IsFile is true
std::vector<std::string> m_ExtensionsInDir; ///< In case of folders: extensions of files inside
bool m_IsFile; ///< Whether the library is a folder or a file
PLUGIN_FILE_DESC( const wxString& aDescription, const std::vector<std::string>& aFileExtensions,
const std::vector<std::string>& aExtsInFolder = {}, bool aIsFile = true ) :
m_Description( aDescription ),
m_FileExtensions( aFileExtensions ), m_ExtensionsInDir( aExtsInFolder ),
m_IsFile( aIsFile )
{
}
PLUGIN_FILE_DESC() : PLUGIN_FILE_DESC( wxEmptyString, {} ) {}
/**
* @return translated description + wildcards string for file dialogs.
*/
wxString FileFilter() const;
operator bool() const { return !m_Description.empty(); }
};
#endif // PLUGIN_FILE_DESC_H_

View File

@ -122,7 +122,6 @@ extern const std::string ProjectFileExtension;
extern const std::string LegacyProjectFileExtension;
extern const std::string ProjectLocalSettingsFileExtension;
extern const std::string LegacySchematicFileExtension;
extern const std::string EagleSchematicFileExtension;
extern const std::string CadstarSchematicFileExtension;
extern const std::string CadstarPartsLibraryFileExtension;
extern const std::string KiCadSchematicFileExtension;
@ -160,9 +159,6 @@ extern const std::string FootprintPlaceFileExtension;
extern const std::string KiCadFootprintFileExtension;
extern const std::string KiCadFootprintLibPathExtension;
extern const std::string AltiumFootprintLibPathExtension;
extern const std::string CadstarFootprintLibPathExtension;
extern const std::string LtspiceSchematicExtension;
extern const std::string LtspiceSymbolExtension;
extern const std::string GedaPcbFootprintLibFileExtension;
extern const std::string EagleFootprintLibPathExtension;
extern const std::string DrawingSheetFileExtension;
@ -206,11 +202,7 @@ extern wxString AllFilesWildcard();
extern wxString FootprintAssignmentFileWildcard();
extern wxString DrawingSheetFileWildcard();
extern wxString SchematicSymbolFileWildcard();
extern wxString KiCadSymbolLibFileWildcard();
extern wxString LegacySymbolLibFileWildcard();
extern wxString DatabaseLibFileWildcard();
extern wxString AllSymbolLibFilesWildcard();
extern wxString ProjectFileWildcard();
extern wxString LegacyProjectFileWildcard();
extern wxString AllProjectFilesWildcard();
@ -224,12 +216,7 @@ extern wxString AllegroNetlistFileWildcard();
extern wxString HtmlFileWildcard();
extern wxString CsvFileWildcard();
extern wxString PcbFileWildcard();
extern wxString AltiumSchematicFileWildcard();
extern wxString CadstarPartsLibraryFileWildcard();
extern wxString CadstarSchematicArchiveFileWildcard();
extern wxString CadstarArchiveFilesWildcard();
extern wxString EagleSchematicFileWildcard();
extern wxString LtspiceSchematicFileWildcard();
extern wxString EagleFilesWildcard();
extern wxString PdfFileWildcard();
extern wxString PSFileWildcard();

View File

@ -550,6 +550,9 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
IO_MGR::PCB_FILE_T pluginType = IO_MGR::FindPluginTypeFromBoardPath( fullFileName, aCtl );
if( pluginType == IO_MGR::FILE_TYPE_NONE )
return false;
bool converted = pluginType != IO_MGR::LEGACY && pluginType != IO_MGR::KICAD_SEXP;
// Loading a project should only be done under carefully considered circumstances.

View File

@ -467,8 +467,12 @@ bool PCB_BASE_EDIT_FRAME::AddLibrary( const wxString& aFilename, FP_LIB_TABLE* a
if( libName.IsEmpty() )
return false;
IO_MGR::PCB_FILE_T lib_type = IO_MGR::GuessPluginTypeFromLibPath( libPath );
if( lib_type == IO_MGR::FILE_TYPE_NONE )
lib_type = IO_MGR::LEGACY;
wxString type = IO_MGR::ShowType( lib_type );
// KiCad lib is our default guess. So it might not have the .pretty extension

View File

@ -58,12 +58,6 @@
// plugins coexisting.
wxString PLUGIN_FILE_DESC::FileFilter() const
{
return wxGetTranslation( m_Description ) + AddFileExtListToFilter( m_FileExtensions );
}
PLUGIN* IO_MGR::PluginFind( PCB_FILE_T aFileType )
{
// This implementation is subject to change, any magic is allowed here.
@ -141,45 +135,27 @@ IO_MGR::PCB_FILE_T IO_MGR::FindPluginTypeFromBoardPath( const wxString& aFileNam
}
IO_MGR::PCB_FILE_T IO_MGR::GuessPluginTypeFromLibPath( const wxString& aLibPath )
IO_MGR::PCB_FILE_T IO_MGR::GuessPluginTypeFromLibPath( const wxString& aLibPath, int aCtl )
{
PCB_FILE_T ret = KICAD_SEXP; // default guess, unless detected otherwise.
wxFileName fn( aLibPath );
const auto& plugins = IO_MGR::PLUGIN_REGISTRY::Instance()->AllPlugins();
if( fn.GetExt() == LegacyFootprintLibPathExtension )
for( const auto& plugin : plugins )
{
ret = LEGACY;
}
else if( fn.GetExt() == GedaPcbFootprintLibFileExtension )
{
ret = GEDA_PCB;
}
else if( fn.GetExt() == EagleFootprintLibPathExtension )
{
ret = EAGLE;
}
else if( fn.GetExt() == AltiumFootprintLibPathExtension )
{
ret = ALTIUM_DESIGNER;
}
else if( fn.GetExt() == CadstarFootprintLibPathExtension )
{
ret = CADSTAR_PCB_ARCHIVE;
bool isKiCad = plugin.m_type == IO_MGR::KICAD_SEXP || plugin.m_type == IO_MGR::LEGACY;
if( ( aCtl & KICTL_KICAD_ONLY ) && !isKiCad )
continue;
if( ( aCtl & KICTL_NONKICAD_ONLY ) && isKiCad )
continue;
PLUGIN::RELEASER pi( plugin.m_createFunc() );
if( pi->CanReadFootprintLib( aLibPath ) )
return plugin.m_type;
}
// 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.
//
else if( fn.GetExt() == KiCadFootprintLibPathExtension )
{
ret = KICAD_SEXP;
}
return ret;
return IO_MGR::FILE_TYPE_NONE;
}

View File

@ -1,6 +1,3 @@
#ifndef IO_MGR_H_
#define IO_MGR_H_
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
@ -25,11 +22,15 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef IO_MGR_H_
#define IO_MGR_H_
#include <cstdint>
#include <config.h>
#include <vector>
#include <wx/arrstr.h>
#include <i18n_utility.h>
#include <plugin_file_desc.h>
class BOARD;
class PLUGIN;
@ -185,7 +186,7 @@ public:
/**
* Return a plugin type given a footprint library's libPath.
*/
static PCB_FILE_T GuessPluginTypeFromLibPath( const wxString& aLibPath );
static PCB_FILE_T GuessPluginTypeFromLibPath( const wxString& aLibPath, int aCtl = 0 );
/**
* Find the requested #PLUGIN and if found, calls the #PLUGIN::LoadBoard() function
@ -235,33 +236,6 @@ public:
};
/**
* Container that describes file type info
*/
struct PLUGIN_FILE_DESC
{
wxString m_Description; ///< Description shown in the file picker dialog
std::vector<std::string> m_FileExtensions; ///< Filter used for file pickers if m_IsFile is true
std::vector<std::string> m_ExtensionsInDir; ///< In case of folders: extensions of files inside
bool m_IsFile; ///< Whether the library is a folder or a file
PLUGIN_FILE_DESC( const wxString& aDescription, const std::vector<std::string>& aFileExtensions,
const std::vector<std::string>& aExtsInFolder = {}, bool aIsFile = true ) :
m_Description( aDescription ),
m_FileExtensions( aFileExtensions ), m_ExtensionsInDir( aExtsInFolder ),
m_IsFile( aIsFile )
{
}
/**
* @return translated description + wildcards string for file dialogs.
*/
wxString FileFilter() const;
operator bool() const { return !m_Description.empty(); }
};
/**
* A base class that #BOARD loading and saving plugins should derive from.
*

View File

@ -428,11 +428,28 @@ bool FOOTPRINT_EDIT_FRAME::SaveLibraryAs( const wxString& aLibraryPath )
IO_MGR::PCB_FILE_T dstType = IO_MGR::GuessPluginTypeFromLibPath( dstLibPath );
IO_MGR::PCB_FILE_T curType = IO_MGR::GuessPluginTypeFromLibPath( curLibPath );
if( dstType == IO_MGR::FILE_TYPE_NONE )
dstType = IO_MGR::KICAD_SEXP;
try
{
PLUGIN::RELEASER cur( IO_MGR::PluginFind( curType ) );
PLUGIN::RELEASER dst( IO_MGR::PluginFind( dstType ) );
if( !cur )
{
msg = wxString::Format( _( "Unable to find a reader for '%s." ), curLibPath );
DisplayError( this, msg );
return false;
}
if( !dst )
{
msg = wxString::Format( _( "Unable to find a writer for '%s." ), dstLibPath );
DisplayError( this, msg );
return false;
}
wxArrayString footprints;
cur->FootprintEnumerate( footprints, curLibPath, false );

View File

@ -318,6 +318,7 @@ bool PLUGIN::fileStartsWithPrefix( const wxString& aFilePath, const wxString& aP
return false;
}
bool PLUGIN::fileStartsWithBinaryHeader( const wxString& aFilePath, const std::vector<uint8_t>& aHeader )
{
wxFileInputStream input( aFilePath );

View File

@ -282,7 +282,7 @@ bool EAGLE_PLUGIN::checkHeader(const wxString& aFileName) const
if( input.Eof() )
return false;
if( text.ReadLine().Lower().Contains( "eagle" ) )
if( text.ReadLine().Contains( wxS( "<!DOCTYPE eagle" ) ) )
return true;
}

View File

@ -1020,6 +1020,9 @@ int PCB_CONTROL::AppendBoardFromFile( const TOOL_EVENT& aEvent )
IO_MGR::FindPluginTypeFromBoardPath( fileName, KICTL_KICAD_ONLY );
PLUGIN::RELEASER pi( IO_MGR::PluginFind( pluginType ) );
if( !pi )
return 1;
return AppendBoard( *pi, fileName );
}
@ -1602,6 +1605,9 @@ int PCB_CONTROL::DdAppendBoard( const TOOL_EVENT& aEvent )
IO_MGR::PCB_FILE_T pluginType = IO_MGR::FindPluginTypeFromBoardPath( filePath );
PLUGIN::RELEASER pi( IO_MGR::PluginFind( pluginType ) );
if( !pi )
return 1;
return AppendBoard( *pi, filePath );
}

View File

@ -50,7 +50,7 @@ void KI_TEST::SCHEMATIC_TEST_FIXTURE::LoadSchematic( const wxString& aBaseName )
m_manager.Prj().SetElem( PROJECT::ELEM_SCH_SYMBOL_LIBS, nullptr );
m_schematic.SetProject( &m_manager.Prj() );
m_schematic.SetRoot( m_pi->Load( fn.GetFullPath(), &m_schematic ) );
m_schematic.SetRoot( m_pi->LoadSchematicFile( fn.GetFullPath(), &m_schematic ) );
BOOST_REQUIRE_EQUAL( m_pi->GetError().IsEmpty(), true );

View File

@ -41,7 +41,7 @@ namespace KI_TEST
void DumpSchematicToFile( SCHEMATIC& aSchematic, SCH_SHEET& aSheet, const std::string& aFilename )
{
SCH_SEXPR_PLUGIN io;
io.Save( aFilename, &aSheet, &aSchematic );
io.SaveSchematicFile( aFilename, &aSheet, &aSchematic );
}
void LoadSheetSchematicContents( const std::string& fileName, SCH_SHEET* sheet )

View File

@ -115,17 +115,17 @@ BOOST_AUTO_TEST_CASE( TestEditPageNumbersInSharedDesign )
newPrjFn.SetExt( ProjectFileExtension );
BOOST_CHECK( wxCopyFile( prjFn.GetFullPath(), newPrjFn.GetFullPath() ) );
m_pi->Save( rootFn.GetFullPath(), &m_schematic.Root(), &m_schematic );
m_pi->SaveSchematicFile( rootFn.GetFullPath(), &m_schematic.Root(), &m_schematic );
wxFileName subSheetFn = rootFn;
BOOST_CHECK( subSheetFn.AppendDir( "ampli_ht" ) );
BOOST_CHECK( subSheetFn.Mkdir() );
subSheetFn.SetName( "ampli_ht" );
m_pi->Save( subSheetFn.GetFullPath(), sheets.at( 1 ).Last(), &m_schematic );
m_pi->SaveSchematicFile( subSheetFn.GetFullPath(), sheets.at( 1 ).Last(), &m_schematic );
subSheetFn.SetName( "filter" );
m_pi->Save( subSheetFn.GetFullPath(), sheets.at( 2 ).Last(), &m_schematic );
m_pi->SaveSchematicFile( subSheetFn.GetFullPath(), sheets.at( 2 ).Last(), &m_schematic );
LoadSchematic( "complex_hierarchy_shared/temp/complex_hierarchy" );