File open/import progress dialogs.
Fixes https://gitlab.com/kicad/code/kicad/issues/6864 Fixes https://gitlab.com/kicad/code/kicad/issues/2166
This commit is contained in:
parent
1d6ad4a52a
commit
5fa5a73c6d
|
@ -167,8 +167,8 @@ FILE_LINE_READER::FILE_LINE_READER( const wxString& aFileName,
|
|||
|
||||
if( !m_fp )
|
||||
{
|
||||
wxString msg = wxString::Format(
|
||||
_( "Unable to open filename \"%s\" for reading" ), aFileName.GetData() );
|
||||
wxString msg = wxString::Format( _( "Unable to open %s for reading." ),
|
||||
aFileName.GetData() );
|
||||
THROW_IO_ERROR( msg );
|
||||
}
|
||||
|
||||
|
@ -195,6 +195,22 @@ FILE_LINE_READER::~FILE_LINE_READER()
|
|||
}
|
||||
|
||||
|
||||
long int FILE_LINE_READER::FileLength()
|
||||
{
|
||||
fseek( m_fp, 0, SEEK_END );
|
||||
long int fileLength = ftell( m_fp );
|
||||
rewind( m_fp );
|
||||
|
||||
return fileLength;
|
||||
}
|
||||
|
||||
|
||||
long int FILE_LINE_READER::CurPos()
|
||||
{
|
||||
return ftell( m_fp );
|
||||
}
|
||||
|
||||
|
||||
char* FILE_LINE_READER::ReadLine()
|
||||
{
|
||||
m_length = 0;
|
||||
|
|
|
@ -369,14 +369,6 @@ bool PGM_SINGLE_TOP::OnPgmInit()
|
|||
App().SetTopWindow( frame ); // wxApp gets a face.
|
||||
App().SetAppDisplayName( frame->GetAboutTitle() );
|
||||
|
||||
// Allocate a slice of time to show the frame and update wxWidgets widgets
|
||||
// (especially setting valid sizes) after creating frame and before calling
|
||||
// OpenProjectFiles() that can update/use some widgets.
|
||||
// The 2 calls to wxSafeYield are needed on wxGTK for best results.
|
||||
wxSafeYield();
|
||||
frame->Show();
|
||||
wxSafeYield();
|
||||
|
||||
// Individual frames may provide additional option/switch processing, but for compatibility,
|
||||
// any positional arguments are treated as a list of files to pass to OpenProjectFiles
|
||||
frame->ParseArgs( parser );
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
#include <tools/ee_inspection_tool.h>
|
||||
#include <paths.h>
|
||||
#include <wx_filename.h> // For ::ResolvePossibleSymlinks
|
||||
#include <widgets/progress_reporter.h>
|
||||
|
||||
bool SCH_EDIT_FRAME::SaveEEFile( SCH_SHEET* aSheet, bool aSaveUnderNewName )
|
||||
{
|
||||
|
@ -400,6 +401,9 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
|||
SCH_PLUGIN* plugin = SCH_IO_MGR::FindPlugin( schFileType );
|
||||
SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( plugin );
|
||||
|
||||
WX_PROGRESS_REPORTER progressReporter( this, _( "Loading Schematic" ), 1 );
|
||||
pi->SetProgressReporter( &progressReporter );
|
||||
|
||||
bool failedLoad = false;
|
||||
try
|
||||
{
|
||||
|
@ -1117,20 +1121,19 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType )
|
|||
try
|
||||
{
|
||||
SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( fileType ) );
|
||||
DIALOG_HTML_REPORTER* reporter = new DIALOG_HTML_REPORTER( this );
|
||||
DIALOG_HTML_REPORTER errorReporter( this );
|
||||
WX_PROGRESS_REPORTER progressReporter( this, _( "Importing Schematic" ), 1 );
|
||||
|
||||
pi->SetReporter( reporter->m_Reporter );
|
||||
pi->SetReporter( errorReporter.m_Reporter );
|
||||
pi->SetProgressReporter( &progressReporter );
|
||||
Schematic().SetRoot( pi->Load( aFileName, &Schematic() ) );
|
||||
|
||||
if( reporter->m_Reporter->HasMessage() )
|
||||
if( errorReporter.m_Reporter->HasMessage() )
|
||||
{
|
||||
reporter->m_Reporter->Flush(); // Build HTML messages
|
||||
reporter->ShowModal();
|
||||
errorReporter.m_Reporter->Flush(); // Build HTML messages
|
||||
errorReporter.ShowModal();
|
||||
}
|
||||
|
||||
pi->SetReporter( &WXLOG_REPORTER::GetInstance() );
|
||||
delete reporter;
|
||||
|
||||
// Non-KiCad schematics do not use a drawing-sheet (or if they do, it works differently
|
||||
// to KiCad), so set it to an empty one
|
||||
DS_DATA_MODEL& drawingSheet = DS_DATA_MODEL::GetTheInstance();
|
||||
|
|
|
@ -38,6 +38,7 @@ class KIWAY;
|
|||
class LIB_SYMBOL;
|
||||
class SYMBOL_LIB;
|
||||
class PROPERTIES;
|
||||
class PROGRESS_REPORTER;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -164,6 +165,11 @@ public:
|
|||
*/
|
||||
virtual void SetReporter( REPORTER* aReporter ) {}
|
||||
|
||||
/**
|
||||
* Set an optional progress reporter.
|
||||
*/
|
||||
virtual void SetProgressReporter( PROGRESS_REPORTER* aReporter ) {}
|
||||
|
||||
/**
|
||||
* Return the file extension for the #SCH_PLUGIN.
|
||||
*/
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <wx/tokenzr.h>
|
||||
#include <wx/wfstream.h>
|
||||
#include <wx/xml/xml.h>
|
||||
#include <wx/msgdlg.h>
|
||||
|
||||
#include <symbol_library.h>
|
||||
#include <plugins/eagle/eagle_parser.h>
|
||||
|
@ -60,6 +61,7 @@
|
|||
#include <schematic.h>
|
||||
#include <symbol_lib_table.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
#include <widgets/progress_reporter.h>
|
||||
|
||||
|
||||
// Eagle schematic axes are aligned with x increasing left to right and Y increasing bottom to top
|
||||
|
@ -351,7 +353,11 @@ static void eagleToKicadAlignment( EDA_TEXT* aText, int aEagleAlignment, int aRe
|
|||
}
|
||||
|
||||
|
||||
SCH_EAGLE_PLUGIN::SCH_EAGLE_PLUGIN()
|
||||
SCH_EAGLE_PLUGIN::SCH_EAGLE_PLUGIN() :
|
||||
m_progressReporter( nullptr ),
|
||||
m_doneCount( 0 ),
|
||||
m_lastProgressCount( 0 ),
|
||||
m_totalCount( 0 )
|
||||
{
|
||||
m_rootSheet = nullptr;
|
||||
m_currentSheet = nullptr;
|
||||
|
@ -390,6 +396,25 @@ int SCH_EAGLE_PLUGIN::GetModifyHash() const
|
|||
}
|
||||
|
||||
|
||||
void SCH_EAGLE_PLUGIN::checkpoint()
|
||||
{
|
||||
const unsigned PROGRESS_DELTA = 5;
|
||||
|
||||
if( m_progressReporter )
|
||||
{
|
||||
if( ++m_doneCount > m_lastProgressCount + PROGRESS_DELTA )
|
||||
{
|
||||
m_progressReporter->SetCurrentProgress(( (double) m_doneCount ) / m_totalCount );
|
||||
|
||||
if( !m_progressReporter->KeepRefreshing() )
|
||||
THROW_IO_ERROR( ( "Open cancelled by user." ) );
|
||||
|
||||
m_lastProgressCount = m_doneCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SCH_SHEET* SCH_EAGLE_PLUGIN::Load( const wxString& aFileName, SCHEMATIC* aSchematic,
|
||||
SCH_SHEET* aAppendToMe, const PROPERTIES* aProperties )
|
||||
{
|
||||
|
@ -399,13 +424,21 @@ SCH_SHEET* SCH_EAGLE_PLUGIN::Load( const wxString& aFileName, SCHEMATIC* aSchema
|
|||
m_filename = aFileName;
|
||||
m_schematic = aSchematic;
|
||||
|
||||
if( m_progressReporter )
|
||||
{
|
||||
m_progressReporter->Report( wxString::Format( _( "Loading %s..." ), aFileName ) );
|
||||
|
||||
if( !m_progressReporter->KeepRefreshing() )
|
||||
THROW_IO_ERROR( ( "Open cancelled by user." ) );
|
||||
}
|
||||
|
||||
// Load the document
|
||||
wxXmlDocument xmlDocument;
|
||||
wxFFileInputStream stream( m_filename.GetFullPath() );
|
||||
|
||||
if( !stream.IsOk() || !xmlDocument.Load( stream ) )
|
||||
{
|
||||
THROW_IO_ERROR( wxString::Format( _( "Unable to read file \"%s\"" ),
|
||||
THROW_IO_ERROR( wxString::Format( _( "Unable to read file '%s'." ),
|
||||
m_filename.GetFullPath() ) );
|
||||
}
|
||||
|
||||
|
@ -562,8 +595,68 @@ void SCH_EAGLE_PLUGIN::loadSchematic( wxXmlNode* aSchematicNode )
|
|||
if( !sheetNode )
|
||||
return;
|
||||
|
||||
auto count_nodes = []( wxXmlNode* aNode ) -> unsigned
|
||||
{
|
||||
unsigned count = 0;
|
||||
|
||||
while( aNode )
|
||||
{
|
||||
count++;
|
||||
aNode = aNode->GetNext();
|
||||
}
|
||||
|
||||
return count;
|
||||
};
|
||||
|
||||
if( m_progressReporter )
|
||||
{
|
||||
m_totalCount = 0;
|
||||
m_doneCount = 0;
|
||||
|
||||
m_totalCount += count_nodes( partNode );
|
||||
|
||||
while( libraryNode )
|
||||
{
|
||||
NODE_MAP libraryChildren = MapChildren( libraryNode );
|
||||
wxXmlNode* devicesetNode = getChildrenNodes( libraryChildren, "devicesets" );
|
||||
|
||||
while( devicesetNode )
|
||||
{
|
||||
NODE_MAP deviceSetChildren = MapChildren( devicesetNode );
|
||||
wxXmlNode* deviceNode = getChildrenNodes( deviceSetChildren, "devices" );
|
||||
wxXmlNode* gateNode = getChildrenNodes( deviceSetChildren, "gates" );
|
||||
|
||||
m_totalCount += count_nodes( deviceNode ) * count_nodes( gateNode );
|
||||
|
||||
devicesetNode = devicesetNode->GetNext();
|
||||
}
|
||||
|
||||
libraryNode = libraryNode->GetNext();
|
||||
}
|
||||
|
||||
// Rewind
|
||||
libraryNode = getChildrenNodes( schematicChildren, "libraries" );
|
||||
|
||||
while( sheetNode )
|
||||
{
|
||||
NODE_MAP sheetChildren = MapChildren( sheetNode );
|
||||
|
||||
m_totalCount += count_nodes( getChildrenNodes( sheetChildren, "instances" ) );
|
||||
m_totalCount += count_nodes( getChildrenNodes( sheetChildren, "busses" ) );
|
||||
m_totalCount += count_nodes( getChildrenNodes( sheetChildren, "nets" ) );
|
||||
m_totalCount += count_nodes( getChildrenNodes( sheetChildren, "plain" ) );
|
||||
|
||||
sheetNode = sheetNode->GetNext();
|
||||
}
|
||||
|
||||
// Rewind
|
||||
sheetNode = getChildrenNodes( schematicChildren, "sheets" );
|
||||
}
|
||||
|
||||
while( partNode )
|
||||
{
|
||||
checkpoint();
|
||||
|
||||
std::unique_ptr<EPART> epart = std::make_unique<EPART>( partNode );
|
||||
|
||||
// N.B. Eagle parts are case-insensitive in matching but we keep the display case
|
||||
|
@ -585,7 +678,6 @@ void SCH_EAGLE_PLUGIN::loadSchematic( wxXmlNode* aSchematicNode )
|
|||
|
||||
libraryNode = libraryNode->GetNext();
|
||||
}
|
||||
|
||||
m_pi->SaveLibrary( getLibFileName().GetFullPath() );
|
||||
}
|
||||
|
||||
|
@ -734,6 +826,8 @@ void SCH_EAGLE_PLUGIN::loadSheet( wxXmlNode* aSheetNode, int aSheetIndex )
|
|||
|
||||
while( instanceNode )
|
||||
{
|
||||
checkpoint();
|
||||
|
||||
loadInstance( instanceNode );
|
||||
instanceNode = instanceNode->GetNext();
|
||||
}
|
||||
|
@ -746,6 +840,8 @@ void SCH_EAGLE_PLUGIN::loadSheet( wxXmlNode* aSheetNode, int aSheetIndex )
|
|||
|
||||
while( busNode )
|
||||
{
|
||||
checkpoint();
|
||||
|
||||
// Get the bus name
|
||||
wxString busName = translateEagleBusName( busNode->GetAttribute( "name" ) );
|
||||
|
||||
|
@ -762,6 +858,8 @@ void SCH_EAGLE_PLUGIN::loadSheet( wxXmlNode* aSheetNode, int aSheetIndex )
|
|||
|
||||
while( netNode )
|
||||
{
|
||||
checkpoint();
|
||||
|
||||
// Get the net name and class
|
||||
wxString netName = netNode->GetAttribute( "name" );
|
||||
wxString netClass = netNode->GetAttribute( "class" );
|
||||
|
@ -792,6 +890,8 @@ void SCH_EAGLE_PLUGIN::loadSheet( wxXmlNode* aSheetNode, int aSheetIndex )
|
|||
|
||||
while( plainNode )
|
||||
{
|
||||
checkpoint();
|
||||
|
||||
wxString nodeName = plainNode->GetName();
|
||||
|
||||
if( nodeName == "text" )
|
||||
|
@ -1371,8 +1471,8 @@ void SCH_EAGLE_PLUGIN::loadInstance( wxXmlNode* aInstanceNode )
|
|||
}
|
||||
|
||||
|
||||
EAGLE_LIBRARY* SCH_EAGLE_PLUGIN::loadLibrary(
|
||||
wxXmlNode* aLibraryNode, EAGLE_LIBRARY* aEagleLibrary )
|
||||
EAGLE_LIBRARY* SCH_EAGLE_PLUGIN::loadLibrary( wxXmlNode* aLibraryNode,
|
||||
EAGLE_LIBRARY* aEagleLibrary )
|
||||
{
|
||||
NODE_MAP libraryChildren = MapChildren( aLibraryNode );
|
||||
|
||||
|
@ -1396,8 +1496,8 @@ EAGLE_LIBRARY* SCH_EAGLE_PLUGIN::loadLibrary(
|
|||
|
||||
wxString prefix = edeviceset.prefix ? edeviceset.prefix.Get() : "";
|
||||
|
||||
NODE_MAP aDeviceSetChildren = MapChildren( devicesetNode );
|
||||
wxXmlNode* deviceNode = getChildrenNodes( aDeviceSetChildren, "devices" );
|
||||
NODE_MAP deviceSetChildren = MapChildren( devicesetNode );
|
||||
wxXmlNode* deviceNode = getChildrenNodes( deviceSetChildren, "devices" );
|
||||
|
||||
// For each device in the device set:
|
||||
while( deviceNode )
|
||||
|
@ -1418,8 +1518,8 @@ EAGLE_LIBRARY* SCH_EAGLE_PLUGIN::loadLibrary(
|
|||
unique_ptr<LIB_SYMBOL> kpart( new LIB_SYMBOL( symbolName ) );
|
||||
|
||||
// Process each gate in the deviceset for this device.
|
||||
wxXmlNode* gateNode = getChildrenNodes( aDeviceSetChildren, "gates" );
|
||||
int gates_count = countChildren( aDeviceSetChildren["gates"], "gate" );
|
||||
wxXmlNode* gateNode = getChildrenNodes( deviceSetChildren, "gates" );
|
||||
int gates_count = countChildren( deviceSetChildren["gates"], "gate" );
|
||||
kpart->SetUnitCount( gates_count );
|
||||
kpart->LockUnits( true );
|
||||
|
||||
|
@ -1437,10 +1537,11 @@ EAGLE_LIBRARY* SCH_EAGLE_PLUGIN::loadLibrary(
|
|||
|
||||
while( gateNode )
|
||||
{
|
||||
checkpoint();
|
||||
|
||||
EGATE egate = EGATE( gateNode );
|
||||
|
||||
aEagleLibrary->GateUnit[edeviceset.name + edevice.name + egate.name] = gateindex;
|
||||
|
||||
ispower = loadSymbol( aEagleLibrary->SymbolNodes[egate.symbol], kpart, &edevice,
|
||||
gateindex, egate.name );
|
||||
|
||||
|
|
|
@ -87,6 +87,11 @@ public:
|
|||
|
||||
void SetReporter( REPORTER* aReporter ) override { m_reporter = aReporter; }
|
||||
|
||||
void SetProgressReporter( PROGRESS_REPORTER* aReporter ) override
|
||||
{
|
||||
m_progressReporter = aReporter;
|
||||
}
|
||||
|
||||
const wxString GetFileExtension() const override;
|
||||
|
||||
const wxString GetLibraryFileExtension() const override;
|
||||
|
@ -99,8 +104,9 @@ public:
|
|||
|
||||
bool CheckHeader( const wxString& aFileName ) override;
|
||||
|
||||
|
||||
private:
|
||||
void checkpoint();
|
||||
|
||||
void loadDrawing( wxXmlNode* aDrawingNode );
|
||||
void loadLayerDefs( wxXmlNode* aLayers );
|
||||
void loadSchematic( wxXmlNode* aSchematicNode );
|
||||
|
@ -228,9 +234,14 @@ private:
|
|||
EPART_MAP m_partlist;
|
||||
std::map<wxString, EAGLE_LIBRARY> m_eagleLibs;
|
||||
|
||||
SCH_PLUGIN::SCH_PLUGIN_RELEASER m_pi; ///< Plugin to create the KiCad symbol library.
|
||||
SCH_PLUGIN::SCH_PLUGIN_RELEASER m_pi; ///< PI to create KiCad symbol library.
|
||||
std::unique_ptr< PROPERTIES > m_properties; ///< Library plugin properties.
|
||||
|
||||
PROGRESS_REPORTER* m_progressReporter; ///< optional; may be nullptr
|
||||
unsigned m_doneCount;
|
||||
unsigned m_lastProgressCount;
|
||||
unsigned m_totalCount; ///< for progress reporting
|
||||
|
||||
std::map<wxString, int> m_netCounts;
|
||||
std::map<int, SCH_LAYER_ID> m_layerMap;
|
||||
|
||||
|
|
|
@ -55,21 +55,48 @@
|
|||
#include <sch_plugins/kicad/sch_sexpr_parser.h>
|
||||
#include <template_fieldnames.h>
|
||||
#include <trigo.h>
|
||||
#include <widgets/progress_reporter.h>
|
||||
|
||||
|
||||
using namespace TSCHEMATIC_T;
|
||||
|
||||
|
||||
SCH_SEXPR_PARSER::SCH_SEXPR_PARSER( LINE_READER* aLineReader ) :
|
||||
SCH_SEXPR_PARSER::SCH_SEXPR_PARSER( LINE_READER* aLineReader, PROGRESS_REPORTER* aProgressReporter,
|
||||
unsigned aLineCount ) :
|
||||
SCHEMATIC_LEXER( aLineReader ),
|
||||
m_requiredVersion( 0 ),
|
||||
m_fieldId( 0 ),
|
||||
m_unit( 1 ),
|
||||
m_convert( 1 )
|
||||
m_convert( 1 ),
|
||||
m_progressReporter( aProgressReporter ),
|
||||
m_lineReader( aLineReader ),
|
||||
m_lastProgressLine( 0 ),
|
||||
m_lineCount( aLineCount )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void SCH_SEXPR_PARSER::checkpoint()
|
||||
{
|
||||
const unsigned PROGRESS_DELTA = 250;
|
||||
|
||||
if( m_progressReporter )
|
||||
{
|
||||
unsigned curLine = m_lineReader->LineNumber();
|
||||
|
||||
if( curLine > m_lastProgressLine + PROGRESS_DELTA )
|
||||
{
|
||||
m_progressReporter->SetCurrentProgress( ( (double) curLine ) / m_lineCount );
|
||||
|
||||
if( !m_progressReporter->KeepRefreshing() )
|
||||
THROW_IO_ERROR( ( "Open cancelled by user." ) );
|
||||
|
||||
m_lastProgressLine = curLine;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool SCH_SEXPR_PARSER::parseBool()
|
||||
{
|
||||
T token = NextTok();
|
||||
|
@ -2090,6 +2117,8 @@ void SCH_SEXPR_PARSER::ParseSchematic( SCH_SHEET* aSheet, bool aIsCopyableOnly,
|
|||
|
||||
token = NextTok();
|
||||
|
||||
checkpoint();
|
||||
|
||||
if( !aIsCopyableOnly && token == T_page && m_requiredVersion <= 20200506 )
|
||||
token = T_paper;
|
||||
|
||||
|
|
|
@ -84,6 +84,13 @@ class SCH_SEXPR_PARSER : public SCHEMATIC_LEXER
|
|||
int m_convert; ///< The current body style being parsed.
|
||||
wxString m_symbolName; ///< The current symbol name.
|
||||
|
||||
PROGRESS_REPORTER* m_progressReporter; // optional; may be nullptr
|
||||
const LINE_READER* m_lineReader; // for progress reporting
|
||||
unsigned m_lastProgressLine;
|
||||
unsigned m_lineCount; // for progress reporting
|
||||
|
||||
void checkpoint();
|
||||
|
||||
void parseHeader( TSCHEMATIC_T::T aHeaderType, int aFileVersion );
|
||||
|
||||
inline long parseHex()
|
||||
|
@ -184,7 +191,8 @@ class SCH_SEXPR_PARSER : public SCHEMATIC_LEXER
|
|||
void parseBusAlias( SCH_SCREEN* aScreen );
|
||||
|
||||
public:
|
||||
SCH_SEXPR_PARSER( LINE_READER* aLineReader = nullptr );
|
||||
SCH_SEXPR_PARSER( LINE_READER* aLineReader = nullptr,
|
||||
PROGRESS_REPORTER* aProgressReporter = nullptr, unsigned aLineCount = 0 );
|
||||
|
||||
void ParseLib( LIB_SYMBOL_MAP& aSymbolLibMap );
|
||||
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
#include <ee_selection.h>
|
||||
#include <kicad_string.h>
|
||||
#include <wx_filename.h> // for ::ResolvePossibleSymlinks()
|
||||
#include <widgets/progress_reporter.h>
|
||||
|
||||
|
||||
using namespace TSCHEMATIC_T;
|
||||
|
@ -365,7 +366,8 @@ public:
|
|||
};
|
||||
|
||||
|
||||
SCH_SEXPR_PLUGIN::SCH_SEXPR_PLUGIN()
|
||||
SCH_SEXPR_PLUGIN::SCH_SEXPR_PLUGIN() :
|
||||
m_progressReporter( nullptr )
|
||||
{
|
||||
init( NULL );
|
||||
}
|
||||
|
@ -387,6 +389,7 @@ void SCH_SEXPR_PLUGIN::init( SCHEMATIC* aSchematic, const PROPERTIES* aPropertie
|
|||
m_nextFreeFieldId = 100; // number arbitrarily > MANDATORY_FIELDS or SHEET_MANDATORY_FIELDS
|
||||
}
|
||||
|
||||
|
||||
SCH_SHEET* SCH_SEXPR_PLUGIN::Load( const wxString& aFileName, SCHEMATIC* aSchematic,
|
||||
SCH_SHEET* aAppendToMe, const PROPERTIES* aProperties )
|
||||
{
|
||||
|
@ -518,10 +521,10 @@ void SCH_SEXPR_PLUGIN::loadHierarchy( SCH_SHEET* aSheet )
|
|||
|
||||
// This was moved out of the try{} block so that any sheets definitionsthat
|
||||
// the plugin fully parsed before the exception was raised will be loaded.
|
||||
for( auto aItem : aSheet->GetScreen()->Items().OfType( SCH_SHEET_T ) )
|
||||
for( SCH_ITEM* aItem : aSheet->GetScreen()->Items().OfType( SCH_SHEET_T ) )
|
||||
{
|
||||
wxCHECK2( aItem->Type() == SCH_SHEET_T, /* do nothing */ );
|
||||
auto sheet = static_cast<SCH_SHEET*>( aItem );
|
||||
SCH_SHEET* sheet = static_cast<SCH_SHEET*>( aItem );
|
||||
|
||||
// Recursion starts here.
|
||||
loadHierarchy( sheet );
|
||||
|
@ -538,7 +541,22 @@ void SCH_SEXPR_PLUGIN::loadFile( const wxString& aFileName, SCH_SHEET* aSheet )
|
|||
{
|
||||
FILE_LINE_READER reader( aFileName );
|
||||
|
||||
SCH_SEXPR_PARSER parser( &reader );
|
||||
size_t lineCount = 0;
|
||||
|
||||
if( m_progressReporter )
|
||||
{
|
||||
m_progressReporter->Report( wxString::Format( _( "Loading %s..." ), aFileName ) );
|
||||
|
||||
if( !m_progressReporter->KeepRefreshing() )
|
||||
THROW_IO_ERROR( ( "Open cancelled by user." ) );
|
||||
|
||||
while( reader.ReadLine() )
|
||||
lineCount++;
|
||||
|
||||
reader.Rewind();
|
||||
}
|
||||
|
||||
SCH_SEXPR_PARSER parser( &reader, m_progressReporter, lineCount );
|
||||
|
||||
parser.ParseSchematic( aSheet );
|
||||
}
|
||||
|
|
|
@ -79,6 +79,11 @@ public:
|
|||
return wxT( "kicad_sym" );
|
||||
}
|
||||
|
||||
void SetProgressReporter( PROGRESS_REPORTER* aReporter ) override
|
||||
{
|
||||
m_progressReporter = aReporter;
|
||||
}
|
||||
|
||||
/**
|
||||
* The property used internally by the plugin to enable cache buffering which prevents
|
||||
* the library file from being written every time the cache is changed. This is useful
|
||||
|
@ -155,13 +160,15 @@ protected:
|
|||
int m_version; ///< Version of file being loaded.
|
||||
int m_nextFreeFieldId;
|
||||
|
||||
wxString m_error; ///< For throwing exceptions or errors on partial loads.
|
||||
wxString m_error; ///< For throwing exceptions or errors on partial
|
||||
///< loads.
|
||||
PROGRESS_REPORTER* m_progressReporter;
|
||||
|
||||
wxString m_path; ///< Root project path for loading child sheets.
|
||||
std::stack<wxString> m_currentPath; ///< Stack to maintain nested sheet paths
|
||||
SCH_SHEET* m_rootSheet; ///< The root sheet of the schematic being loaded..
|
||||
SCHEMATIC* m_schematic; ///< Passed to Load(), the schematic object being loaded
|
||||
OUTPUTFORMATTER* m_out; ///< The output formatter for saving SCH_SCREEN objects.
|
||||
SCH_SHEET* m_rootSheet; ///< The root sheet of the schematic being loaded.
|
||||
SCHEMATIC* m_schematic;
|
||||
OUTPUTFORMATTER* m_out; ///< The formatter for saving SCH_SCREEN objects.
|
||||
SCH_SEXPR_PLUGIN_CACHE* m_cache;
|
||||
|
||||
/// initialize PLUGIN like a constructor would.
|
||||
|
|
|
@ -41,6 +41,9 @@
|
|||
#include <properties.h>
|
||||
#include <trace_helpers.h>
|
||||
#include <trigo.h>
|
||||
#include <confirm.h>
|
||||
#include <widgets/progress_reporter.h>
|
||||
#include <wx_filename.h> // For ::ResolvePossibleSymlinks()
|
||||
|
||||
#include <general.h>
|
||||
#include <sch_bitmap.h>
|
||||
|
@ -70,10 +73,8 @@
|
|||
#include <lib_text.h>
|
||||
#include <eeschema_id.h> // for MAX_UNIT_COUNT_PER_PACKAGE definition
|
||||
#include <symbol_lib_table.h> // for PropPowerSymsOnly definition.
|
||||
#include <confirm.h>
|
||||
#include <tool/selection.h>
|
||||
#include <default_values.h> // For some default values
|
||||
#include <wx_filename.h> // For ::ResolvePossibleSymlinks()
|
||||
|
||||
|
||||
#define Mils2Iu( x ) Mils2iu( x )
|
||||
|
@ -582,7 +583,11 @@ public:
|
|||
};
|
||||
|
||||
|
||||
SCH_LEGACY_PLUGIN::SCH_LEGACY_PLUGIN()
|
||||
SCH_LEGACY_PLUGIN::SCH_LEGACY_PLUGIN() :
|
||||
m_progressReporter( nullptr ),
|
||||
m_lineReader( nullptr ),
|
||||
m_lastProgressLine( 0 ),
|
||||
m_lineCount( 0 )
|
||||
{
|
||||
init( NULL );
|
||||
}
|
||||
|
@ -604,6 +609,27 @@ void SCH_LEGACY_PLUGIN::init( SCHEMATIC* aSchematic, const PROPERTIES* aProperti
|
|||
}
|
||||
|
||||
|
||||
void SCH_LEGACY_PLUGIN::checkpoint()
|
||||
{
|
||||
const unsigned PROGRESS_DELTA = 250;
|
||||
|
||||
if( m_progressReporter )
|
||||
{
|
||||
unsigned curLine = m_lineReader->LineNumber();
|
||||
|
||||
if( curLine > m_lastProgressLine + PROGRESS_DELTA )
|
||||
{
|
||||
m_progressReporter->SetCurrentProgress( ( (double) curLine ) / m_lineCount );
|
||||
|
||||
if( !m_progressReporter->KeepRefreshing() )
|
||||
THROW_IO_ERROR( ( "Open cancelled by user." ) );
|
||||
|
||||
m_lastProgressLine = curLine;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SCH_SHEET* SCH_LEGACY_PLUGIN::Load( const wxString& aFileName, SCHEMATIC* aSchematic,
|
||||
SCH_SHEET* aAppendToMe, const PROPERTIES* aProperties )
|
||||
{
|
||||
|
@ -753,6 +779,22 @@ void SCH_LEGACY_PLUGIN::loadFile( const wxString& aFileName, SCH_SCREEN* aScreen
|
|||
{
|
||||
FILE_LINE_READER reader( aFileName );
|
||||
|
||||
if( m_progressReporter )
|
||||
{
|
||||
m_progressReporter->Report( wxString::Format( _( "Loading %s..." ), aFileName ) );
|
||||
|
||||
if( !m_progressReporter->KeepRefreshing() )
|
||||
THROW_IO_ERROR( ( "Open cancelled by user." ) );
|
||||
|
||||
m_lineReader = &reader;
|
||||
m_lineCount = 0;
|
||||
|
||||
while( reader.ReadLine() )
|
||||
m_lineCount++;
|
||||
|
||||
reader.Rewind();
|
||||
}
|
||||
|
||||
loadHeader( reader, aScreen );
|
||||
|
||||
LoadContent( reader, aScreen, m_version );
|
||||
|
@ -782,6 +824,8 @@ void SCH_LEGACY_PLUGIN::LoadContent( LINE_READER& aReader, SCH_SCREEN* aScreen,
|
|||
|
||||
while( aReader.ReadLine() )
|
||||
{
|
||||
checkpoint();
|
||||
|
||||
char* line = aReader.Line();
|
||||
|
||||
while( *line == ' ' )
|
||||
|
@ -842,6 +886,8 @@ void SCH_LEGACY_PLUGIN::loadHeader( LINE_READER& aReader, SCH_SCREEN* aScreen )
|
|||
// Skip all lines until the end of header "EELAYER END" is found
|
||||
while( aReader.ReadLine() )
|
||||
{
|
||||
checkpoint();
|
||||
|
||||
line = aReader.Line();
|
||||
|
||||
while( *line == ' ' )
|
||||
|
|
|
@ -82,6 +82,11 @@ public:
|
|||
return wxT( "lib" );
|
||||
}
|
||||
|
||||
void SetProgressReporter( PROGRESS_REPORTER* aReporter ) override
|
||||
{
|
||||
m_progressReporter = aReporter;
|
||||
}
|
||||
|
||||
/**
|
||||
* The property used internally by the plugin to enable cache buffering which prevents
|
||||
* the library file from being written every time the cache is changed. This is useful
|
||||
|
@ -140,6 +145,7 @@ public:
|
|||
static void FormatPart( LIB_SYMBOL* aSymbol, OUTPUTFORMATTER& aFormatter );
|
||||
|
||||
private:
|
||||
void checkpoint();
|
||||
void loadHierarchy( SCH_SHEET* aSheet );
|
||||
void loadHeader( LINE_READER& aReader, SCH_SCREEN* aScreen );
|
||||
void loadPageSettings( LINE_READER& aReader, SCH_SCREEN* aScreen );
|
||||
|
@ -172,15 +178,19 @@ private:
|
|||
protected:
|
||||
int m_version; ///< Version of file being loaded.
|
||||
|
||||
/** For throwing exceptions or errors on partial schematic loads. */
|
||||
wxString m_error;
|
||||
wxString m_error; ///< For throwing exceptions or errors on partial
|
||||
///< schematic loads.
|
||||
PROGRESS_REPORTER* m_progressReporter; ///< optional; may be nullptr
|
||||
LINE_READER* m_lineReader; ///< for progress reporting
|
||||
unsigned m_lastProgressLine;
|
||||
unsigned m_lineCount; ///< for progress reporting
|
||||
|
||||
wxString m_path; ///< Root project path for loading child sheets.
|
||||
std::stack<wxString> m_currentPath; ///< Stack to maintain nested sheet paths
|
||||
SCH_SHEET* m_rootSheet; ///< The root sheet of the schematic being loaded..
|
||||
OUTPUTFORMATTER* m_out; ///< The output formatter for saving SCH_SCREEN objects.
|
||||
SCH_SHEET* m_rootSheet; ///< The root sheet of the schematic being loaded.
|
||||
OUTPUTFORMATTER* m_out; ///< The formatter for saving SCH_SCREEN objects.
|
||||
SCH_LEGACY_PLUGIN_CACHE* m_cache;
|
||||
SCHEMATIC* m_schematic; ///< Passed to Load(), the schematic object being loaded
|
||||
SCHEMATIC* m_schematic;
|
||||
|
||||
/// initialize PLUGIN like a constructor would.
|
||||
void init( SCHEMATIC* aSchematic, const PROPERTIES* aProperties = nullptr );
|
||||
|
|
|
@ -131,7 +131,7 @@ std::vector<SYMBOL_ASYNC_LOADER::LOADED_PAIR> SYMBOL_ASYNC_LOADER::worker()
|
|||
}
|
||||
|
||||
if( m_reporter )
|
||||
m_reporter->AdvancePhase( wxString::Format( _( "Loading library \"%s\"" ), nickname ) );
|
||||
m_reporter->AdvancePhase( wxString::Format( _( "Loading library %s..." ), nickname ) );
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -225,6 +225,9 @@ public:
|
|||
m_lineNum = 0;
|
||||
}
|
||||
|
||||
long int FileLength();
|
||||
long int CurPos();
|
||||
|
||||
protected:
|
||||
bool m_iOwn; ///< if I own the file, I'll promise to close it, else not.
|
||||
FILE* m_fp; ///< I may own this file, but might not.
|
||||
|
|
|
@ -665,18 +665,13 @@ int KICAD_MANAGER_CONTROL::ShowPlayer( const TOOL_EVENT& aEvent )
|
|||
filepath = legacy_board.GetFullPath();
|
||||
}
|
||||
|
||||
// Show the frame (and update widgets to set valid sizes),
|
||||
// after creating player and before calling OpenProjectFiles().
|
||||
// Useful because loading a complex board and building its internal data can be
|
||||
// time consuming
|
||||
player->Show( true );
|
||||
wxSafeYield();
|
||||
|
||||
if( !filepath.IsEmpty() )
|
||||
{
|
||||
if( !player->OpenProjectFiles( std::vector<wxString>( 1, filepath ) ) )
|
||||
return -1;
|
||||
}
|
||||
|
||||
player->Show( true );
|
||||
}
|
||||
|
||||
// Needed on Windows, other platforms do not use it, but it creates no issue
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include <settings/settings_manager.h>
|
||||
#include <widgets/infobar.h>
|
||||
#include <widgets/resettable_panel.h>
|
||||
#include <widgets/progress_reporter.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
|
||||
#include "dialog_board_setup.h"
|
||||
|
@ -192,7 +193,10 @@ void DIALOG_BOARD_SETUP::OnAuxiliaryAction( wxCommandEvent& event )
|
|||
|
||||
try
|
||||
{
|
||||
otherBoard = pi->Load( boardFn.GetFullPath(), nullptr, nullptr );
|
||||
WX_PROGRESS_REPORTER progressReporter( this, _( "Loading PCB" ), 1 );
|
||||
|
||||
otherBoard = pi->Load( boardFn.GetFullPath(), nullptr, nullptr, nullptr,
|
||||
&progressReporter );
|
||||
|
||||
if( importDlg.m_LayersOpt->GetValue() )
|
||||
{
|
||||
|
|
|
@ -501,7 +501,7 @@ void PANEL_PCBNEW_COLOR_SETTINGS::createPreviewItems()
|
|||
|
||||
try
|
||||
{
|
||||
pi.DoLoad( reader, m_preview->GetBoard(), nullptr );
|
||||
pi.DoLoad( reader, m_preview->GetBoard(), nullptr, nullptr, 0 );
|
||||
}
|
||||
catch( const IO_ERROR& )
|
||||
{
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
#include <confirm.h>
|
||||
#include <core/arraydim.h>
|
||||
#include <kicad_string.h>
|
||||
#include <gestfich.h>
|
||||
#include <pcb_edit_frame.h>
|
||||
#include <board_design_settings.h>
|
||||
|
@ -48,6 +47,7 @@
|
|||
#include <kiplatform/app.h>
|
||||
#include <widgets/appearance_controls.h>
|
||||
#include <widgets/infobar.h>
|
||||
#include <widgets/progress_reporter.h>
|
||||
#include <settings/settings_manager.h>
|
||||
#include <paths.h>
|
||||
#include <project/project_file.h>
|
||||
|
@ -56,7 +56,6 @@
|
|||
#include <plugins/cadstar/cadstar_pcb_archive_plugin.h>
|
||||
#include <plugins/kicad/kicad_plugin.h>
|
||||
#include <dialogs/dialog_imported_layers.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tools/pcb_actions.h>
|
||||
#include "footprint_info_impl.h"
|
||||
#include <wx_filename.h> // For ::ResolvePossibleSymlinks()
|
||||
|
@ -691,12 +690,13 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
|||
props["page_width"] = xbuf;
|
||||
props["page_height"] = ybuf;
|
||||
|
||||
WX_PROGRESS_REPORTER progressReporter( this, _( "Loading PCB" ), 1 );
|
||||
#if USE_INSTRUMENTATION
|
||||
// measure the time to load a BOARD.
|
||||
unsigned startTime = GetRunningMicroSecs();
|
||||
#endif
|
||||
|
||||
loadedBoard = pi->Load( fullFileName, NULL, &props, &Prj() );
|
||||
loadedBoard = pi->Load( fullFileName, NULL, &props, &Prj(), &progressReporter );
|
||||
|
||||
#if USE_INSTRUMENTATION
|
||||
unsigned stopTime = GetRunningMicroSecs();
|
||||
|
|
|
@ -156,14 +156,15 @@ IO_MGR::PCB_FILE_T IO_MGR::GuessPluginTypeFromLibPath( const wxString& aLibPath
|
|||
|
||||
|
||||
BOARD* IO_MGR::Load( PCB_FILE_T aFileType, const wxString& aFileName, BOARD* aAppendToMe,
|
||||
const PROPERTIES* aProperties, PROJECT* aProject )
|
||||
const PROPERTIES* aProperties, PROJECT* aProject,
|
||||
PROGRESS_REPORTER* aProgressReporter )
|
||||
{
|
||||
// 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, aProject ); // virtual
|
||||
return pi->Load( aFileName, aAppendToMe, aProperties, aProject, aProgressReporter );
|
||||
}
|
||||
|
||||
THROW_IO_ERROR( wxString::Format( FMT_NOTFOUND, ShowType( aFileType ).GetData() ) );
|
||||
|
|
|
@ -37,6 +37,7 @@ class PLUGIN;
|
|||
class FOOTPRINT;
|
||||
class PROPERTIES;
|
||||
class PROJECT;
|
||||
class PROGRESS_REPORTER;
|
||||
|
||||
/**
|
||||
* A factory which returns an instance of a #PLUGIN.
|
||||
|
@ -210,7 +211,8 @@ public:
|
|||
*/
|
||||
static BOARD* Load( PCB_FILE_T aFileType, const wxString& aFileName,
|
||||
BOARD* aAppendToMe = nullptr, const PROPERTIES* aProperties = nullptr,
|
||||
PROJECT* aProject = nullptr );
|
||||
PROJECT* aProject = nullptr,
|
||||
PROGRESS_REPORTER* aProgressReporter = nullptr );
|
||||
|
||||
/**
|
||||
* Write either a full \a aBoard to a storage file in a format that this implementation
|
||||
|
@ -296,6 +298,8 @@ public:
|
|||
* it to be optionally NULL.
|
||||
* @param aProject is the optional #PROJECT object primarily used by third party
|
||||
* importers.
|
||||
* @param aProgressReporter an optional progress reporter
|
||||
* @param aLineCount a line count (necessary if a progress reporter is supplied)
|
||||
* @return the successfully loaded board, or the same one as \a aAppendToMe if aAppendToMe
|
||||
* was not NULL, and caller owns it.
|
||||
*
|
||||
|
@ -304,7 +308,8 @@ public:
|
|||
* possible.
|
||||
*/
|
||||
virtual BOARD* Load( const wxString& aFileName, BOARD* aAppendToMe,
|
||||
const PROPERTIES* aProperties = nullptr, PROJECT* aProject = nullptr );
|
||||
const PROPERTIES* aProperties = nullptr, PROJECT* aProject = nullptr,
|
||||
PROGRESS_REPORTER* aProgressReporter = nullptr );
|
||||
|
||||
/**
|
||||
* Return a container with the cached library footprints generated in the last call to
|
||||
|
|
|
@ -352,7 +352,8 @@ void CLIPBOARD_IO::Save( const wxString& aFileName, BOARD* aBoard,
|
|||
|
||||
|
||||
BOARD* CLIPBOARD_IO::Load( const wxString& aFileName, BOARD* aAppendToMe,
|
||||
const PROPERTIES* aProperties, PROJECT* aProject )
|
||||
const PROPERTIES* aProperties, PROJECT* aProject,
|
||||
PROGRESS_REPORTER* aProgressReporter )
|
||||
{
|
||||
std::string result;
|
||||
|
||||
|
|
|
@ -59,7 +59,8 @@ public:
|
|||
BOARD_ITEM* Parse();
|
||||
|
||||
BOARD* Load( const wxString& aFileName, BOARD* aAppendToMe,
|
||||
const PROPERTIES* aProperties = nullptr, PROJECT* aProject = nullptr ) override;
|
||||
const PROPERTIES* aProperties = nullptr, PROJECT* aProject = nullptr,
|
||||
PROGRESS_REPORTER* aProgressReporter = nullptr ) override;
|
||||
|
||||
void SetBoard( BOARD* aBoard );
|
||||
|
||||
|
|
|
@ -1164,9 +1164,10 @@ void PCB_PAINTER::draw( const PAD* aPad, int aLayer )
|
|||
|
||||
m_gal->DrawPolygon( outline );
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
m_gal->DrawPolygon( poly->Vertices() );
|
||||
}
|
||||
|
||||
// Now add on a rounded margin (using segments) if the margin > 0
|
||||
if( margin.x > 0 )
|
||||
|
|
|
@ -44,7 +44,7 @@ static void not_implemented( PLUGIN* aPlugin, const char* aCaller )
|
|||
|
||||
|
||||
BOARD* PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe, const PROPERTIES* aProperties,
|
||||
PROJECT* aProject )
|
||||
PROJECT* aProject, PROGRESS_REPORTER* aProgressReporter )
|
||||
{
|
||||
not_implemented( this, __FUNCTION__ );
|
||||
return nullptr;
|
||||
|
|
|
@ -64,7 +64,8 @@ const wxString ALTIUM_CIRCUIT_MAKER_PLUGIN::GetFileExtension() const
|
|||
|
||||
|
||||
BOARD* ALTIUM_CIRCUIT_MAKER_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe,
|
||||
const PROPERTIES* aProperties, PROJECT* aProject )
|
||||
const PROPERTIES* aProperties, PROJECT* aProject,
|
||||
PROGRESS_REPORTER* aProgressReporter )
|
||||
{
|
||||
m_props = aProperties;
|
||||
|
||||
|
|
|
@ -39,7 +39,8 @@ public:
|
|||
const wxString PluginName() const override;
|
||||
|
||||
BOARD* Load( const wxString& aFileName, BOARD* aAppendToMe, const PROPERTIES* aProperties,
|
||||
PROJECT* aProject = nullptr ) override;
|
||||
PROJECT* aProject = nullptr,
|
||||
PROGRESS_REPORTER* aProgressReporter = nullptr ) override;
|
||||
|
||||
const wxString GetFileExtension() const override;
|
||||
|
||||
|
|
|
@ -64,7 +64,8 @@ const wxString ALTIUM_CIRCUIT_STUDIO_PLUGIN::GetFileExtension() const
|
|||
|
||||
|
||||
BOARD* ALTIUM_CIRCUIT_STUDIO_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe,
|
||||
const PROPERTIES* aProperties, PROJECT* aProject )
|
||||
const PROPERTIES* aProperties, PROJECT* aProject,
|
||||
PROGRESS_REPORTER* aProgressReporter )
|
||||
{
|
||||
m_props = aProperties;
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ public:
|
|||
const wxString PluginName() const override;
|
||||
|
||||
BOARD* Load( const wxString& aFileName, BOARD* aAppendToMe, const PROPERTIES* aProperties,
|
||||
PROJECT* aProject ) override;
|
||||
PROJECT* aProject, PROGRESS_REPORTER* aProgressReporter = nullptr ) override;
|
||||
|
||||
const wxString GetFileExtension() const override;
|
||||
|
||||
|
|
|
@ -64,7 +64,8 @@ const wxString ALTIUM_DESIGNER_PLUGIN::GetFileExtension() const
|
|||
|
||||
|
||||
BOARD* ALTIUM_DESIGNER_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe,
|
||||
const PROPERTIES* aProperties, PROJECT* aProject )
|
||||
const PROPERTIES* aProperties, PROJECT* aProject,
|
||||
PROGRESS_REPORTER* aProgressReporter )
|
||||
{
|
||||
m_props = aProperties;
|
||||
|
||||
|
|
|
@ -41,7 +41,8 @@ public:
|
|||
const wxString PluginName() const override;
|
||||
|
||||
BOARD* Load( const wxString& aFileName, BOARD* aAppendToMe, const PROPERTIES* aProperties,
|
||||
PROJECT* aProject = nullptr) override;
|
||||
PROJECT* aProject = nullptr,
|
||||
PROGRESS_REPORTER* aProgressReporter = nullptr ) override;
|
||||
|
||||
const wxString GetFileExtension() const override;
|
||||
|
||||
|
|
|
@ -106,7 +106,8 @@ std::vector<FOOTPRINT*> CADSTAR_PCB_ARCHIVE_PLUGIN::GetImportedCachedLibraryFoot
|
|||
|
||||
|
||||
BOARD* CADSTAR_PCB_ARCHIVE_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe,
|
||||
const PROPERTIES* aProperties, PROJECT* aProject )
|
||||
const PROPERTIES* aProperties, PROJECT* aProject,
|
||||
PROGRESS_REPORTER* aProgressReporter )
|
||||
{
|
||||
m_props = aProperties;
|
||||
m_board = aAppendToMe ? aAppendToMe : new BOARD();
|
||||
|
|
|
@ -39,7 +39,8 @@ public:
|
|||
const wxString PluginName() const override;
|
||||
|
||||
BOARD* Load( const wxString& aFileName, BOARD* aAppendToMe,
|
||||
const PROPERTIES* aProperties = nullptr, PROJECT* aProject = nullptr ) override;
|
||||
const PROPERTIES* aProperties = nullptr, PROJECT* aProject = nullptr,
|
||||
PROGRESS_REPORTER* aProgressReporter = nullptr ) override;
|
||||
|
||||
const wxString GetFileExtension() const override;
|
||||
|
||||
|
|
|
@ -67,6 +67,7 @@ Load() TODO's
|
|||
#include <properties.h>
|
||||
#include <trigo.h>
|
||||
#include <math/util.h> // for KiROUND
|
||||
#include <widgets/progress_reporter.h>
|
||||
|
||||
#include <board.h>
|
||||
#include <board_design_settings.h>
|
||||
|
@ -207,12 +208,14 @@ static void setKeepoutSettingsToZone( ZONE* aZone, LAYER_NUM aLayer )
|
|||
}
|
||||
|
||||
|
||||
void ERULES::parse( wxXmlNode* aRules )
|
||||
void ERULES::parse( wxXmlNode* aRules, std::function<void()> aCheckpoint )
|
||||
{
|
||||
wxXmlNode* child = aRules->GetChildren();
|
||||
|
||||
while( child )
|
||||
{
|
||||
aCheckpoint();
|
||||
|
||||
if( child->GetName() == "param" )
|
||||
{
|
||||
const wxString& name = child->GetAttribute( "name" );
|
||||
|
@ -275,6 +278,10 @@ void ERULES::parse( wxXmlNode* aRules )
|
|||
EAGLE_PLUGIN::EAGLE_PLUGIN() :
|
||||
m_rules( new ERULES() ),
|
||||
m_xpath( new XPATH() ),
|
||||
m_progressReporter( nullptr ),
|
||||
m_doneCount( 0 ),
|
||||
m_lastProgressCount( 0 ),
|
||||
m_totalCount( 0 ),
|
||||
m_mod_time( wxDateTime::Now() )
|
||||
{
|
||||
using namespace std::placeholders;
|
||||
|
@ -305,6 +312,26 @@ const wxString EAGLE_PLUGIN::GetFileExtension() const
|
|||
return wxT( "brd" );
|
||||
}
|
||||
|
||||
|
||||
void EAGLE_PLUGIN::checkpoint()
|
||||
{
|
||||
const unsigned PROGRESS_DELTA = 50;
|
||||
|
||||
if( m_progressReporter )
|
||||
{
|
||||
if( ++m_doneCount > m_lastProgressCount + PROGRESS_DELTA )
|
||||
{
|
||||
m_progressReporter->SetCurrentProgress(( (double) m_doneCount ) / m_totalCount );
|
||||
|
||||
if( !m_progressReporter->KeepRefreshing() )
|
||||
THROW_IO_ERROR( ( "Open cancelled by user." ) );
|
||||
|
||||
m_lastProgressCount = m_doneCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
wxSize inline EAGLE_PLUGIN::kicad_fontz( const ECOORD& d, int aTextThickness ) const
|
||||
{
|
||||
// Eagle includes stroke thickness in the text size, KiCAD does not
|
||||
|
@ -314,7 +341,8 @@ wxSize inline EAGLE_PLUGIN::kicad_fontz( const ECOORD& d, int aTextThickness ) c
|
|||
|
||||
|
||||
BOARD* EAGLE_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe,
|
||||
const PROPERTIES* aProperties, PROJECT* aProject )
|
||||
const PROPERTIES* aProperties, PROJECT* aProject,
|
||||
PROGRESS_REPORTER* aProgressReporter )
|
||||
{
|
||||
LOCALE_IO toggle; // toggles on, then off, the C locale.
|
||||
wxXmlNode* doc;
|
||||
|
@ -322,6 +350,7 @@ BOARD* EAGLE_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe,
|
|||
init( aProperties );
|
||||
|
||||
m_board = aAppendToMe ? aAppendToMe : new BOARD();
|
||||
m_progressReporter = aProgressReporter;
|
||||
|
||||
// Give the filename to the board if it's new
|
||||
if( !aAppendToMe )
|
||||
|
@ -332,6 +361,14 @@ BOARD* EAGLE_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe,
|
|||
|
||||
try
|
||||
{
|
||||
if( m_progressReporter )
|
||||
{
|
||||
m_progressReporter->Report( wxString::Format( _( "Loading %s..." ), aFileName ) );
|
||||
|
||||
if( !m_progressReporter->KeepRefreshing() )
|
||||
THROW_IO_ERROR( ( "Open cancelled by user." ) );
|
||||
}
|
||||
|
||||
wxFileName fn = aFileName;
|
||||
// Load the document
|
||||
wxFFileInputStream stream( fn.GetFullPath() );
|
||||
|
@ -339,7 +376,7 @@ BOARD* EAGLE_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe,
|
|||
|
||||
if( !stream.IsOk() || !xmlDocument.Load( stream ) )
|
||||
{
|
||||
THROW_IO_ERROR( wxString::Format( _( "Unable to read file \"%s\"" ),
|
||||
THROW_IO_ERROR( wxString::Format( _( "Unable to read file '%s'" ),
|
||||
fn.GetFullPath() ) );
|
||||
}
|
||||
|
||||
|
@ -414,9 +451,7 @@ std::vector<FOOTPRINT*> EAGLE_PLUGIN::GetImportedCachedLibraryFootprints()
|
|||
std::vector<FOOTPRINT*> retval;
|
||||
|
||||
for( std::pair<wxString, FOOTPRINT*> fp : m_templates )
|
||||
{
|
||||
retval.push_back( static_cast<FOOTPRINT*>( fp.second->Clone() ) );
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
@ -458,12 +493,53 @@ void EAGLE_PLUGIN::loadAllSections( wxXmlNode* aDoc )
|
|||
wxXmlNode* board = drawingChildren["board"];
|
||||
NODE_MAP boardChildren = MapChildren( board );
|
||||
|
||||
auto count_children = [this]( wxXmlNode* aNode )
|
||||
{
|
||||
if( aNode )
|
||||
{
|
||||
wxXmlNode* child = aNode->GetChildren();
|
||||
|
||||
while( child )
|
||||
{
|
||||
m_totalCount++;
|
||||
child = child->GetNext();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
wxXmlNode* designrules = boardChildren["designrules"];
|
||||
wxXmlNode* layers = drawingChildren["layers"];
|
||||
wxXmlNode* plain = boardChildren["plain"];
|
||||
wxXmlNode* signals = boardChildren["signals"];
|
||||
wxXmlNode* libs = boardChildren["libraries"];
|
||||
wxXmlNode* elems = boardChildren["elements"];
|
||||
|
||||
if( m_progressReporter )
|
||||
{
|
||||
m_totalCount = 0;
|
||||
m_doneCount = 0;
|
||||
|
||||
count_children( designrules );
|
||||
count_children( layers );
|
||||
count_children( plain );
|
||||
count_children( signals );
|
||||
count_children( elems );
|
||||
|
||||
while( libs )
|
||||
{
|
||||
count_children( MapChildren( libs )["packages"] );
|
||||
libs = libs->GetNext();
|
||||
}
|
||||
|
||||
// Rewind
|
||||
libs = boardChildren["libraries"];
|
||||
}
|
||||
|
||||
m_xpath->push( "eagle.drawing" );
|
||||
|
||||
{
|
||||
m_xpath->push( "board" );
|
||||
|
||||
wxXmlNode* designrules = boardChildren["designrules"];
|
||||
loadDesignRules( designrules );
|
||||
|
||||
m_xpath->pop();
|
||||
|
@ -472,7 +548,6 @@ void EAGLE_PLUGIN::loadAllSections( wxXmlNode* aDoc )
|
|||
{
|
||||
m_xpath->push( "layers" );
|
||||
|
||||
wxXmlNode* layers = drawingChildren["layers"];
|
||||
loadLayerDefs( layers );
|
||||
mapEagleLayersToKicad();
|
||||
|
||||
|
@ -482,19 +557,12 @@ void EAGLE_PLUGIN::loadAllSections( wxXmlNode* aDoc )
|
|||
{
|
||||
m_xpath->push( "board" );
|
||||
|
||||
wxXmlNode* plain = boardChildren["plain"];
|
||||
loadPlain( plain );
|
||||
|
||||
wxXmlNode* signals = boardChildren["signals"];
|
||||
loadSignals( signals );
|
||||
|
||||
wxXmlNode* libs = boardChildren["libraries"];
|
||||
loadLibraries( libs );
|
||||
|
||||
wxXmlNode* elems = boardChildren["elements"];
|
||||
loadElements( elems );
|
||||
|
||||
m_xpath->pop(); // "board"
|
||||
m_xpath->pop();
|
||||
}
|
||||
|
||||
m_xpath->pop(); // "eagle.drawing"
|
||||
|
@ -506,7 +574,7 @@ void EAGLE_PLUGIN::loadDesignRules( wxXmlNode* aDesignRules )
|
|||
if( aDesignRules )
|
||||
{
|
||||
m_xpath->push( "designrules" );
|
||||
m_rules->parse( aDesignRules );
|
||||
m_rules->parse( aDesignRules, [this](){ checkpoint(); } );
|
||||
m_xpath->pop(); // "designrules"
|
||||
}
|
||||
}
|
||||
|
@ -533,9 +601,7 @@ void EAGLE_PLUGIN::loadLayerDefs( wxXmlNode* aLayers )
|
|||
|
||||
// find the subset of layers that are copper and active
|
||||
if( elayer.number >= 1 && elayer.number <= 16 && ( !elayer.active || *elayer.active ) )
|
||||
{
|
||||
cu.push_back( elayer );
|
||||
}
|
||||
|
||||
layerNode = layerNode->GetNext();
|
||||
}
|
||||
|
@ -546,9 +612,13 @@ void EAGLE_PLUGIN::loadLayerDefs( wxXmlNode* aLayers )
|
|||
for( EITER it = cu.begin(); it != cu.end(); ++it, ++ki_layer_count )
|
||||
{
|
||||
if( ki_layer_count == 0 )
|
||||
{
|
||||
m_cu_map[it->number] = F_Cu;
|
||||
}
|
||||
else if( ki_layer_count == int( cu.size()-1 ) )
|
||||
{
|
||||
m_cu_map[it->number] = B_Cu;
|
||||
}
|
||||
else
|
||||
{
|
||||
// some eagle boards do not have contiguous layer number sequences.
|
||||
|
@ -592,6 +662,8 @@ void EAGLE_PLUGIN::loadPlain( wxXmlNode* aGraphics )
|
|||
// (polygon | wire | text | circle | rectangle | frame | hole)*
|
||||
while( gr )
|
||||
{
|
||||
checkpoint();
|
||||
|
||||
wxString grName = gr->GetName();
|
||||
|
||||
if( grName == "wire" )
|
||||
|
@ -945,6 +1017,8 @@ void EAGLE_PLUGIN::loadLibrary( wxXmlNode* aLib, const wxString* aLibName )
|
|||
|
||||
while( package )
|
||||
{
|
||||
checkpoint();
|
||||
|
||||
m_xpath->push( "package", "name" );
|
||||
|
||||
wxString pack_ref = package->GetAttribute( "name" );
|
||||
|
@ -1018,6 +1092,8 @@ void EAGLE_PLUGIN::loadElements( wxXmlNode* aElements )
|
|||
|
||||
while( element )
|
||||
{
|
||||
checkpoint();
|
||||
|
||||
if( element->GetName() != "element" )
|
||||
{
|
||||
// Get next item
|
||||
|
@ -1039,7 +1115,7 @@ void EAGLE_PLUGIN::loadElements( wxXmlNode* aElements )
|
|||
|
||||
if( it == m_templates.end() )
|
||||
{
|
||||
wxString emsg = wxString::Format( _( "No \"%s\" package in library \"%s\"" ),
|
||||
wxString emsg = wxString::Format( _( "No '%s' package in library '%s'." ),
|
||||
FROM_UTF8( e.package.c_str() ),
|
||||
FROM_UTF8( e.library.c_str() ) );
|
||||
THROW_IO_ERROR( emsg );
|
||||
|
@ -1742,7 +1818,7 @@ void EAGLE_PLUGIN::packagePad( FOOTPRINT* aFootprint, wxXmlNode* aTree )
|
|||
// if shape is not present, our default is circle and that matches their default "round"
|
||||
}
|
||||
|
||||
if( e.diameter )
|
||||
if( e.diameter && e.diameter->value > 0 )
|
||||
{
|
||||
int diameter = e.diameter->ToPcbUnits();
|
||||
pad->SetSize( wxSize( diameter, diameter ) );
|
||||
|
@ -2148,6 +2224,9 @@ void EAGLE_PLUGIN::packageHole( FOOTPRINT* aFootprint, wxXmlNode* aTree, bool aC
|
|||
{
|
||||
EHOLE e( aTree );
|
||||
|
||||
if( e.drill.value == 0 )
|
||||
return;
|
||||
|
||||
// we add a PAD_ATTRIB::NPTH pad to this footprint.
|
||||
PAD* pad = new PAD( aFootprint );
|
||||
aFootprint->Add( pad );
|
||||
|
@ -2188,7 +2267,7 @@ void EAGLE_PLUGIN::packageSMD( FOOTPRINT* aFootprint, wxXmlNode* aTree ) const
|
|||
ESMD e( aTree );
|
||||
PCB_LAYER_ID layer = kicad_layer( e.layer );
|
||||
|
||||
if( !IsCopperLayer( layer ) )
|
||||
if( !IsCopperLayer( layer ) || e.dx.value == 0 || e.dy.value == 0 )
|
||||
return;
|
||||
|
||||
PAD* pad = new PAD( aFootprint );
|
||||
|
@ -2304,6 +2383,8 @@ void EAGLE_PLUGIN::loadSignals( wxXmlNode* aSignals )
|
|||
|
||||
while( net )
|
||||
{
|
||||
checkpoint();
|
||||
|
||||
bool sawPad = false;
|
||||
|
||||
zones.clear();
|
||||
|
@ -2557,7 +2638,13 @@ void EAGLE_PLUGIN::mapEagleLayersToKicad()
|
|||
inputDescs.push_back( layerDesc );
|
||||
}
|
||||
|
||||
if( m_progressReporter && dynamic_cast<wxWindow*>( m_progressReporter ) )
|
||||
dynamic_cast<wxWindow*>( m_progressReporter )->Hide();
|
||||
|
||||
m_layer_map = m_layer_mapping_handler( inputDescs );
|
||||
|
||||
if( m_progressReporter && dynamic_cast<wxWindow*>( m_progressReporter ))
|
||||
dynamic_cast<wxWindow*>( m_progressReporter )->Show();
|
||||
}
|
||||
|
||||
PCB_LAYER_ID EAGLE_PLUGIN::kicad_layer( int aEagleLayer ) const
|
||||
|
|
|
@ -78,7 +78,7 @@ struct ERULES
|
|||
mdWireWire ( 0 )
|
||||
{}
|
||||
|
||||
void parse( wxXmlNode* aRules );
|
||||
void parse( wxXmlNode* aRules, std::function<void()> aCheckpoint );
|
||||
|
||||
///< percent over 100%. 0-> not elongated, 100->twice as wide as is tall
|
||||
///< Goes into making a scaling factor for "long" pads.
|
||||
|
@ -131,7 +131,8 @@ public:
|
|||
const wxString PluginName() const override;
|
||||
|
||||
BOARD* Load( const wxString& aFileName, BOARD* aAppendToMe,
|
||||
const PROPERTIES* aProperties = nullptr, PROJECT* aProject = nullptr ) override;
|
||||
const PROPERTIES* aProperties = nullptr, PROJECT* aProject = nullptr,
|
||||
PROGRESS_REPORTER* aProgressReporter = nullptr ) override;
|
||||
|
||||
std::vector<FOOTPRINT*> GetImportedCachedLibraryFootprints() override;
|
||||
|
||||
|
@ -178,6 +179,8 @@ private:
|
|||
/// initialize PLUGIN like a constructor would, and futz with fresh BOARD if needed.
|
||||
void init( const PROPERTIES* aProperties );
|
||||
|
||||
void checkpoint();
|
||||
|
||||
void clear_cu_map();
|
||||
|
||||
/// Convert an Eagle distance to a KiCad distance.
|
||||
|
@ -299,6 +302,11 @@ private:
|
|||
const PROPERTIES* m_props; ///< passed via Save() or Load(), no ownership, may be NULL.
|
||||
BOARD* m_board; ///< which BOARD is being worked on, no ownership here
|
||||
|
||||
PROGRESS_REPORTER* m_progressReporter; ///< optional; may be nullptr
|
||||
unsigned m_doneCount;
|
||||
unsigned m_lastProgressCount;
|
||||
unsigned m_totalCount; ///< for progress reporting
|
||||
|
||||
int m_min_trace; ///< smallest trace we find on Load(), in BIU.
|
||||
int m_min_hole; ///< smallest diameter hole we find on Load(), in BIU.
|
||||
int m_min_via; ///< smallest via we find on Load(), in BIU.
|
||||
|
|
|
@ -59,7 +59,8 @@ const wxString FABMASTER_PLUGIN::GetFileExtension() const
|
|||
|
||||
|
||||
BOARD* FABMASTER_PLUGIN::Load( const wxString &aFileName, BOARD *aAppendToMe,
|
||||
const PROPERTIES *aProperties, PROJECT *aProject )
|
||||
const PROPERTIES *aProperties, PROJECT *aProject,
|
||||
PROGRESS_REPORTER* aProgressReporter )
|
||||
{
|
||||
m_props = aProperties;
|
||||
|
||||
|
|
|
@ -43,7 +43,9 @@ public:
|
|||
|
||||
BOARD* Load( const wxString& aFileName,
|
||||
BOARD* aAppendToMe,
|
||||
const PROPERTIES* aProperties = NULL, PROJECT* aProject = nullptr ) override;
|
||||
const PROPERTIES* aProperties = NULL,
|
||||
PROJECT* aProject = nullptr,
|
||||
PROGRESS_REPORTER* aProgressReporter = nullptr ) override;
|
||||
|
||||
const wxString GetFileExtension() const override;
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include <plugins/kicad/pcb_parser.h>
|
||||
#include <trace_helpers.h>
|
||||
#include <pcb_track.h>
|
||||
#include <widgets/progress_reporter.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
#include <wx/dir.h>
|
||||
#include <wx/log.h>
|
||||
|
@ -2188,11 +2189,26 @@ PCB_IO::~PCB_IO()
|
|||
|
||||
|
||||
BOARD* PCB_IO::Load( const wxString& aFileName, BOARD* aAppendToMe, const PROPERTIES* aProperties,
|
||||
PROJECT* aProject )
|
||||
PROJECT* aProject, PROGRESS_REPORTER* aProgressReporter )
|
||||
{
|
||||
FILE_LINE_READER reader( aFileName );
|
||||
|
||||
BOARD* board = DoLoad( reader, aAppendToMe, aProperties );
|
||||
unsigned lineCount = 0;
|
||||
|
||||
if( aProgressReporter )
|
||||
{
|
||||
aProgressReporter->Report( wxString::Format( _( "Loading %s..." ), aFileName ) );
|
||||
|
||||
if( !aProgressReporter->KeepRefreshing() )
|
||||
THROW_IO_ERROR( ( "Open cancelled by user." ) );
|
||||
|
||||
while( reader.ReadLine() )
|
||||
lineCount++;
|
||||
|
||||
reader.Rewind();
|
||||
}
|
||||
|
||||
BOARD* board = DoLoad( reader, aAppendToMe, aProperties, aProgressReporter, lineCount );
|
||||
|
||||
// Give the filename to the board if it's new
|
||||
if( !aAppendToMe )
|
||||
|
@ -2202,12 +2218,14 @@ BOARD* PCB_IO::Load( const wxString& aFileName, BOARD* aAppendToMe, const PROPER
|
|||
}
|
||||
|
||||
|
||||
BOARD* PCB_IO::DoLoad( LINE_READER& aReader, BOARD* aAppendToMe, const PROPERTIES* aProperties )
|
||||
BOARD* PCB_IO::DoLoad( LINE_READER& aReader, BOARD* aAppendToMe, const PROPERTIES* aProperties,
|
||||
PROGRESS_REPORTER* aProgressReporter, unsigned aLineCount)
|
||||
{
|
||||
init( aProperties );
|
||||
|
||||
m_parser->SetLineReader( &aReader );
|
||||
m_parser->SetBoard( aAppendToMe );
|
||||
m_parser->SetProgressReporter( aProgressReporter, &aReader, aLineCount );
|
||||
|
||||
BOARD* board;
|
||||
|
||||
|
|
|
@ -153,9 +153,11 @@ public:
|
|||
const PROPERTIES* aProperties = nullptr ) override;
|
||||
|
||||
BOARD* Load( const wxString& aFileName, BOARD* aAppendToMe,
|
||||
const PROPERTIES* aProperties = nullptr, PROJECT* aProject = nullptr ) override;
|
||||
const PROPERTIES* aProperties = nullptr, PROJECT* aProject = nullptr,
|
||||
PROGRESS_REPORTER* aProgressReporter = nullptr ) override;
|
||||
|
||||
BOARD* DoLoad( LINE_READER& aReader, BOARD* aAppendToMe, const PROPERTIES* aProperties );
|
||||
BOARD* DoLoad( LINE_READER& aReader, BOARD* aAppendToMe, const PROPERTIES* aProperties,
|
||||
PROGRESS_REPORTER* aProgressReporter, unsigned aLineCount );
|
||||
|
||||
void FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aLibraryPath,
|
||||
bool aBestEfforts, const PROPERTIES* aProperties = nullptr ) override;
|
||||
|
|
|
@ -28,13 +28,11 @@
|
|||
*/
|
||||
|
||||
#include <cerrno>
|
||||
#include <common.h>
|
||||
#include <confirm.h>
|
||||
#include <macros.h>
|
||||
#include <title_block.h>
|
||||
#include <trigo.h>
|
||||
|
||||
#include <advanced_config.h>
|
||||
#include <board.h>
|
||||
#include <board_design_settings.h>
|
||||
#include <pcb_dimension.h>
|
||||
|
@ -54,10 +52,10 @@
|
|||
#include <zones.h>
|
||||
#include <plugins/kicad/pcb_parser.h>
|
||||
#include <convert_basic_shapes_to_polygon.h> // for RECT_CHAMFER_POSITIONS definition
|
||||
#include <template_fieldnames.h>
|
||||
#include <math/util.h> // KiROUND, Clamp
|
||||
#include <kicad_string.h>
|
||||
#include <wx/log.h>
|
||||
#include <widgets/progress_reporter.h>
|
||||
|
||||
using namespace PCB_KEYS_T;
|
||||
|
||||
|
@ -107,6 +105,27 @@ void PCB_PARSER::init()
|
|||
}
|
||||
|
||||
|
||||
void PCB_PARSER::checkpoint()
|
||||
{
|
||||
const unsigned PROGRESS_DELTA = 250;
|
||||
|
||||
if( m_progressReporter )
|
||||
{
|
||||
unsigned curLine = m_lineReader->LineNumber();
|
||||
|
||||
if( curLine > m_lastProgressLine + PROGRESS_DELTA )
|
||||
{
|
||||
m_progressReporter->SetCurrentProgress( ( (double) curLine ) / m_lineCount );
|
||||
|
||||
if( !m_progressReporter->KeepRefreshing() )
|
||||
THROW_IO_ERROR( ( "Open cancelled by user." ) );
|
||||
|
||||
m_lastProgressLine = curLine;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PCB_PARSER::skipCurrent()
|
||||
{
|
||||
int curr_level = 0;
|
||||
|
@ -588,6 +607,8 @@ BOARD* PCB_PARSER::parseBOARD_unchecked()
|
|||
|
||||
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
|
||||
{
|
||||
checkpoint();
|
||||
|
||||
if( token != T_LEFT )
|
||||
Expecting( T_LEFT );
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ class PCB_VIA;
|
|||
class ZONE;
|
||||
class FP_3DMODEL;
|
||||
struct LAYER;
|
||||
class PROGRESS_REPORTER;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -72,7 +73,11 @@ public:
|
|||
PCB_PARSER( LINE_READER* aReader = nullptr ) :
|
||||
PCB_LEXER( aReader ),
|
||||
m_board( nullptr ),
|
||||
m_resetKIIDs( false )
|
||||
m_resetKIIDs( false ),
|
||||
m_progressReporter( nullptr ),
|
||||
m_lineReader( nullptr ),
|
||||
m_lastProgressLine( 0 ),
|
||||
m_lineCount( 0 )
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
@ -101,6 +106,15 @@ public:
|
|||
m_resetKIIDs = true;
|
||||
}
|
||||
|
||||
void SetProgressReporter( PROGRESS_REPORTER* aProgressReporter, const LINE_READER* aLineReader,
|
||||
unsigned aLineCount )
|
||||
{
|
||||
m_progressReporter = aProgressReporter;
|
||||
m_lineReader = aLineReader;
|
||||
m_lastProgressLine = 0;
|
||||
m_lineCount = aLineCount;
|
||||
}
|
||||
|
||||
BOARD_ITEM* Parse();
|
||||
|
||||
/**
|
||||
|
@ -154,6 +168,8 @@ private:
|
|||
*/
|
||||
void init();
|
||||
|
||||
void checkpoint();
|
||||
|
||||
/**
|
||||
* Create a mapping from the (short-lived) bug where layer names were translated.
|
||||
*
|
||||
|
@ -342,6 +358,11 @@ private:
|
|||
|
||||
bool m_showLegacyZoneWarning;
|
||||
|
||||
PROGRESS_REPORTER* m_progressReporter; ///< optional; may be nullptr
|
||||
const LINE_READER* m_lineReader; ///< for progress reporting
|
||||
unsigned m_lastProgressLine;
|
||||
unsigned m_lineCount; ///< for progress reporting
|
||||
|
||||
// Group membership info refers to other Uuids in the file.
|
||||
// We don't want to rely on group declarations being last in the file, so
|
||||
// we store info about the group declarations here during parsing and then resolve
|
||||
|
|
|
@ -88,6 +88,7 @@
|
|||
#include <trigo.h>
|
||||
#include <confirm.h>
|
||||
#include <math/util.h> // for KiROUND
|
||||
#include <widgets/progress_reporter.h>
|
||||
|
||||
typedef LEGACY_PLUGIN::BIU BIU;
|
||||
|
||||
|
@ -194,6 +195,28 @@ static bool inline isSpace( int c ) { return strchr( delims, c ) != nullptr; }
|
|||
|
||||
#define MASK(x) (1<<(x))
|
||||
|
||||
|
||||
void LEGACY_PLUGIN::checkpoint()
|
||||
{
|
||||
const unsigned PROGRESS_DELTA = 250;
|
||||
|
||||
if( m_progressReporter )
|
||||
{
|
||||
unsigned curLine = m_reader->LineNumber();
|
||||
|
||||
if( curLine > m_lastProgressLine + PROGRESS_DELTA )
|
||||
{
|
||||
m_progressReporter->SetCurrentProgress( ( (double) curLine ) / m_lineCount );
|
||||
|
||||
if( !m_progressReporter->KeepRefreshing() )
|
||||
THROW_IO_ERROR( ( "Open cancelled by user." ) );
|
||||
|
||||
m_lastProgressLine = curLine;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----<BOARD Load Functions>---------------------------------------------------
|
||||
|
||||
/// C string compare test for a specific length of characters.
|
||||
|
@ -378,7 +401,8 @@ static inline long hexParse( const char* next, const char** out = NULL )
|
|||
|
||||
|
||||
BOARD* LEGACY_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe,
|
||||
const PROPERTIES* aProperties, PROJECT* aProject )
|
||||
const PROPERTIES* aProperties, PROJECT* aProject,
|
||||
PROGRESS_REPORTER* aProgressReporter )
|
||||
{
|
||||
LOCALE_IO toggle; // toggles on, then off, the C locale.
|
||||
|
||||
|
@ -402,13 +426,30 @@ BOARD* LEGACY_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe,
|
|||
|
||||
FILE_LINE_READER reader( aFileName );
|
||||
|
||||
m_reader = &reader; // member function accessibility
|
||||
m_reader = &reader;
|
||||
m_progressReporter = aProgressReporter;
|
||||
|
||||
checkVersion();
|
||||
|
||||
if( m_progressReporter )
|
||||
{
|
||||
m_lineCount = 0;
|
||||
|
||||
m_progressReporter->Report( wxString::Format( _( "Loading %s..." ), aFileName ) );
|
||||
|
||||
if( !m_progressReporter->KeepRefreshing() )
|
||||
THROW_IO_ERROR( ( "Open cancelled by user." ) );
|
||||
|
||||
while( reader.ReadLine() )
|
||||
m_lineCount++;
|
||||
|
||||
reader.Rewind();
|
||||
}
|
||||
|
||||
loadAllSections( bool( aAppendToMe ) );
|
||||
|
||||
(void)boardDeleter.release(); // give it up so we dont delete it on exit
|
||||
m_progressReporter = nullptr;
|
||||
return m_board;
|
||||
}
|
||||
|
||||
|
@ -426,6 +467,8 @@ void LEGACY_PLUGIN::loadAllSections( bool doAppend )
|
|||
|
||||
while( ( line = READLINE( m_reader ) ) != NULL )
|
||||
{
|
||||
checkpoint();
|
||||
|
||||
// put the more frequent ones at the top, but realize TRACKs are loaded as a group
|
||||
|
||||
if( TESTLINE( "$MODULE" ) )
|
||||
|
@ -2200,6 +2243,8 @@ void LEGACY_PLUGIN::loadTrackList( int aStructType )
|
|||
|
||||
while( ( line = READLINE( m_reader ) ) != NULL )
|
||||
{
|
||||
checkpoint();
|
||||
|
||||
// read two lines per loop iteration, each loop is one TRACK or VIA
|
||||
// example first line:
|
||||
// e.g. "Po 0 23994 28800 24400 28800 150 -1" for a track
|
||||
|
@ -3386,6 +3431,9 @@ LEGACY_PLUGIN::LEGACY_PLUGIN() :
|
|||
m_cu_count( 16 ), // for FootprintLoad()
|
||||
m_board( nullptr ),
|
||||
m_props( nullptr ),
|
||||
m_progressReporter( nullptr ),
|
||||
m_lastProgressLine( 0 ),
|
||||
m_lineCount( 0 ),
|
||||
m_reader( nullptr ),
|
||||
m_fp( nullptr ),
|
||||
m_cache( nullptr )
|
||||
|
|
|
@ -74,7 +74,8 @@ public:
|
|||
}
|
||||
|
||||
BOARD* Load( const wxString& aFileName, BOARD* aAppendToMe,
|
||||
const PROPERTIES* aProperties = nullptr, PROJECT* aProject = nullptr ) override;
|
||||
const PROPERTIES* aProperties = nullptr, PROJECT* aProject = nullptr,
|
||||
PROGRESS_REPORTER* aProgressReporter = nullptr ) override;
|
||||
|
||||
void FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aLibraryPath,
|
||||
bool aBestEfforts,
|
||||
|
@ -101,6 +102,11 @@ public:
|
|||
static LSET leg_mask2new( int cu_count, unsigned aMask );
|
||||
|
||||
protected:
|
||||
/// initialize PLUGIN like a constructor would, and futz with fresh BOARD if needed.
|
||||
void init( const PROPERTIES* aProperties );
|
||||
|
||||
void checkpoint();
|
||||
|
||||
///< Converts net code using the mapping table if available,
|
||||
///< otherwise returns unchanged net code
|
||||
inline int getNetCode( int aNetCode )
|
||||
|
@ -178,7 +184,11 @@ protected:
|
|||
|
||||
wxString m_error; ///< for throwing exceptions
|
||||
BOARD* m_board; ///< which BOARD, no ownership here
|
||||
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.
|
||||
PROGRESS_REPORTER* m_progressReporter; ///< may be NULL, no ownership
|
||||
unsigned m_lastProgressLine;
|
||||
unsigned m_lineCount; ///< for progress reporting
|
||||
|
||||
LINE_READER* m_reader; ///< no ownership here.
|
||||
FILE* m_fp; ///< no ownership here.
|
||||
|
@ -190,9 +200,6 @@ protected:
|
|||
|
||||
std::vector<int> m_netCodes; ///< net codes mapping for boards being loaded
|
||||
|
||||
/// initialize PLUGIN like a constructor would, and futz with fresh BOARD if needed.
|
||||
void init( const PROPERTIES* aProperties );
|
||||
|
||||
double biuToDisk; ///< convert from BIUs to disk engineering units
|
||||
///< with this scale factor
|
||||
|
||||
|
|
|
@ -66,7 +66,8 @@ const wxString PCAD_PLUGIN::GetFileExtension() const
|
|||
|
||||
|
||||
BOARD* PCAD_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe,
|
||||
const PROPERTIES* aProperties, PROJECT* aProject )
|
||||
const PROPERTIES* aProperties, PROJECT* aProject,
|
||||
PROGRESS_REPORTER* aProgressReporter )
|
||||
{
|
||||
wxXmlDocument xmlDoc;
|
||||
|
||||
|
|
|
@ -43,7 +43,8 @@ public:
|
|||
BOARD* Load( const wxString& aFileName,
|
||||
BOARD* aAppendToMe,
|
||||
const PROPERTIES* aProperties = nullptr,
|
||||
PROJECT* aProject = nullptr ) override;
|
||||
PROJECT* aProject = nullptr,
|
||||
PROGRESS_REPORTER* aProgressReporter = nullptr ) override;
|
||||
|
||||
const wxString GetFileExtension() const override;
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
#include <view/view_controls.h>
|
||||
#include <footprint_viewer_frame.h>
|
||||
#include <footprint_edit_frame.h>
|
||||
#include <widgets/progress_reporter.h>
|
||||
|
||||
using namespace std::placeholders;
|
||||
|
||||
|
@ -1018,8 +1019,10 @@ int PCB_CONTROL::AppendBoard( PLUGIN& pi, wxString& fileName )
|
|||
props["page_width"] = xbuf;
|
||||
props["page_height"] = ybuf;
|
||||
|
||||
WX_PROGRESS_REPORTER progressReporter( editFrame, _( "Loading PCB" ), 1 );
|
||||
|
||||
editFrame->GetDesignSettings().GetNetClasses().Clear();
|
||||
pi.Load( fileName, brd, &props );
|
||||
pi.Load( fileName, brd, &props, nullptr, &progressReporter );
|
||||
}
|
||||
catch( const IO_ERROR& ioe )
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue