Eeschema: allow for partial schematic loading.
With the implementation of the legacy schematic plugin, any I/O error when parsing the schematics would prevent the entire schematic from being loaded. This change restores (somewhat) the previous behavior where as long as the root schematic is loaded properly, then all of the remaining sub-sheet will attempt to load. Add GetError() method the SCH_PLUGIN object to allow for partial schematic loading. Check the error message contents when no exception was caught to warn the user of any accumulated errors. Fixes lp:1690644 https://bugs.launchpad.net/kicad/+bug/1690644
This commit is contained in:
parent
f44d4d01ea
commit
8af9aa7574
|
@ -293,6 +293,15 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
||||||
g_RootSheet = pi->Load( fullFileName, &Kiway() );
|
g_RootSheet = pi->Load( fullFileName, &Kiway() );
|
||||||
m_CurrentSheet->clear();
|
m_CurrentSheet->clear();
|
||||||
m_CurrentSheet->push_back( g_RootSheet );
|
m_CurrentSheet->push_back( g_RootSheet );
|
||||||
|
|
||||||
|
if( !pi->GetError().IsEmpty() )
|
||||||
|
{
|
||||||
|
DisplayErrorMessage( this,
|
||||||
|
_( "The entire schematic could not be load. Errors "
|
||||||
|
"occurred attempting to load hierarchical sheet "
|
||||||
|
"schematics." ),
|
||||||
|
pi->GetError() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch( const IO_ERROR& ioe )
|
catch( const IO_ERROR& ioe )
|
||||||
{
|
{
|
||||||
|
@ -434,6 +443,15 @@ bool SCH_EDIT_FRAME::AppendSchematic()
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
pi->Load( fullFileName, &Kiway(), newSheet.get() );
|
pi->Load( fullFileName, &Kiway(), newSheet.get() );
|
||||||
|
|
||||||
|
if( !pi->GetError().IsEmpty() )
|
||||||
|
{
|
||||||
|
DisplayErrorMessage( this,
|
||||||
|
_( "The entire schematic could not be load. Errors "
|
||||||
|
"occurred attempting to load hierarchical sheet "
|
||||||
|
"schematics." ),
|
||||||
|
pi->GetError() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch( const IO_ERROR& ioe )
|
catch( const IO_ERROR& ioe )
|
||||||
{
|
{
|
||||||
|
|
|
@ -486,13 +486,23 @@ public:
|
||||||
virtual void SymbolLibOptions( PROPERTIES* aListToAppendTo ) const;
|
virtual void SymbolLibOptions( PROPERTIES* aListToAppendTo ) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function CheckHeader
|
* Return true if the first line in @a aFileName begins with the expected header.
|
||||||
* returns 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
|
* @param aFileName is the name of the file to use as input
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
virtual bool CheckHeader( const wxString& aFileName );
|
virtual bool CheckHeader( const wxString& aFileName );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an error string to the caller.
|
||||||
|
*
|
||||||
|
* This is useful for schematic loaders that can load partial schematics where throwing
|
||||||
|
* an exception would be problematic such as the KiCad legacy plugin.
|
||||||
|
*
|
||||||
|
* @return an unformatted string containing errors if any.
|
||||||
|
*/
|
||||||
|
virtual const wxString& GetError() const;
|
||||||
|
|
||||||
//-----</PUBLIC SCH_PLUGIN API>------------------------------------------------
|
//-----</PUBLIC SCH_PLUGIN API>------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -652,28 +652,44 @@ void SCH_LEGACY_PLUGIN::loadHierarchy( SCH_SHEET* aSheet )
|
||||||
{
|
{
|
||||||
aSheet->SetScreen( new SCH_SCREEN( m_kiway ) );
|
aSheet->SetScreen( new SCH_SCREEN( m_kiway ) );
|
||||||
aSheet->GetScreen()->SetFileName( fileName.GetFullPath() );
|
aSheet->GetScreen()->SetFileName( fileName.GetFullPath() );
|
||||||
loadFile( fileName.GetFullPath(), aSheet->GetScreen() );
|
|
||||||
|
|
||||||
EDA_ITEM* item = aSheet->GetScreen()->GetDrawItems();
|
try
|
||||||
|
|
||||||
while( item )
|
|
||||||
{
|
{
|
||||||
if( item->Type() == SCH_SHEET_T )
|
loadFile( fileName.GetFullPath(), aSheet->GetScreen() );
|
||||||
|
|
||||||
|
EDA_ITEM* item = aSheet->GetScreen()->GetDrawItems();
|
||||||
|
|
||||||
|
while( item )
|
||||||
{
|
{
|
||||||
SCH_SHEET* sheet = (SCH_SHEET*) item;
|
if( item->Type() == SCH_SHEET_T )
|
||||||
|
{
|
||||||
|
SCH_SHEET* sheet = (SCH_SHEET*) item;
|
||||||
|
|
||||||
// Set the parent to aSheet. This effectively creates a method to find
|
// Set the parent to aSheet. This effectively creates a method to find
|
||||||
// the root sheet from any sheet so a pointer to the root sheet does not
|
// the root sheet from any sheet so a pointer to the root sheet does not
|
||||||
// need to be stored globally. Note: this is not the same as a hierarchy.
|
// need to be stored globally. Note: this is not the same as a hierarchy.
|
||||||
// Complex hierarchies can have multiple copies of a sheet. This only
|
// Complex hierarchies can have multiple copies of a sheet. This only
|
||||||
// provides a simple tree to find the root sheet.
|
// provides a simple tree to find the root sheet.
|
||||||
sheet->SetParent( aSheet );
|
sheet->SetParent( aSheet );
|
||||||
|
|
||||||
// Recursion starts here.
|
// Recursion starts here.
|
||||||
loadHierarchy( sheet );
|
loadHierarchy( sheet );
|
||||||
|
}
|
||||||
|
|
||||||
|
item = item->Next();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
catch( const IO_ERROR& ioe )
|
||||||
|
{
|
||||||
|
// If there is a problem loading the root sheet, there is no recovery.
|
||||||
|
if( aSheet == m_rootSheet )
|
||||||
|
throw( ioe );
|
||||||
|
|
||||||
item = item->Next();
|
// For all subsheets, queue up the error message for the caller.
|
||||||
|
if( !m_error.IsEmpty() )
|
||||||
|
m_error += "\n";
|
||||||
|
|
||||||
|
m_error += ioe.What();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,6 +125,8 @@ public:
|
||||||
bool CheckHeader( const wxString& aFileName ) override;
|
bool CheckHeader( const wxString& aFileName ) override;
|
||||||
bool IsSymbolLibWritable( const wxString& aLibraryPath ) override;
|
bool IsSymbolLibWritable( const wxString& aLibraryPath ) override;
|
||||||
|
|
||||||
|
const wxString& GetError() const override { return m_error; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void loadHierarchy( SCH_SHEET* aSheet );
|
void loadHierarchy( SCH_SHEET* aSheet );
|
||||||
void loadHeader( FILE_LINE_READER& aReader, SCH_SCREEN* aScreen );
|
void loadHeader( FILE_LINE_READER& aReader, SCH_SCREEN* aScreen );
|
||||||
|
@ -155,7 +157,10 @@ private:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int m_version; ///< Version of file being loaded.
|
int m_version; ///< Version of file being loaded.
|
||||||
wxString m_error; ///< For throwing exceptions
|
|
||||||
|
/** For throwing exceptions or errors on partial schematic loads. */
|
||||||
|
wxString m_error;
|
||||||
|
|
||||||
wxString m_path; ///< Root project path for loading child sheets.
|
wxString m_path; ///< Root project path for loading child sheets.
|
||||||
const PROPERTIES* m_props; ///< Passed via Save() or Load(), no ownership, may be NULL.
|
const PROPERTIES* m_props; ///< Passed via Save() or Load(), no ownership, may be NULL.
|
||||||
KIWAY* m_kiway; ///< Required for path to legacy component libraries.
|
KIWAY* m_kiway; ///< Required for path to legacy component libraries.
|
||||||
|
|
|
@ -188,3 +188,12 @@ bool SCH_PLUGIN::CheckHeader( const wxString& aFileName )
|
||||||
not_implemented( this, __FUNCTION__ );
|
not_implemented( this, __FUNCTION__ );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const wxString& SCH_PLUGIN::GetError() const
|
||||||
|
{
|
||||||
|
// not pure virtual so that plugins only have to implement subset of the SCH_PLUGIN interface.
|
||||||
|
not_implemented( this, __FUNCTION__ );
|
||||||
|
static wxString error;
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
|
@ -247,6 +247,15 @@ bool SCH_EDIT_FRAME::EditSheet( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHierarchy )
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
aSheet = pi->Load( newFilename, &Kiway(), aSheet );
|
aSheet = pi->Load( newFilename, &Kiway(), aSheet );
|
||||||
|
|
||||||
|
if( !pi->GetError().IsEmpty() )
|
||||||
|
{
|
||||||
|
DisplayErrorMessage( this,
|
||||||
|
_( "The entire schematic could not be load. Errors "
|
||||||
|
"occurred attempting to load hierarchical sheet "
|
||||||
|
"schematics." ),
|
||||||
|
pi->GetError() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch( const IO_ERROR& ioe )
|
catch( const IO_ERROR& ioe )
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue