7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-21 19:43:44 +00:00

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:
Jeff Young 2021-06-23 23:53:08 +01:00
parent 1d6ad4a52a
commit 5fa5a73c6d
45 changed files with 643 additions and 158 deletions

View File

@ -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;

View File

@ -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 );

View File

@ -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();

View File

@ -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.
*/

View File

@ -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 );

View File

@ -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 );
@ -120,15 +126,15 @@ private:
SCH_LAYER_ID kiCadLayer( int aEagleLayer );
std::pair<VECTOR2I, const SEG*> findNearestLinePoint( const wxPoint& aPoint,
const std::vector<SEG>& aLines ) const;
const std::vector<SEG>& aLines ) const;
void loadSegments( wxXmlNode* aSegmentsNode, const wxString& aNetName,
const wxString& aNetClass );
SCH_LINE* loadWire( wxXmlNode* aWireNode );
SCH_TEXT* loadLabel( wxXmlNode* aLabelNode, const wxString& aNetName );
SCH_JUNCTION* loadJunction( wxXmlNode* aJunction );
SCH_TEXT* loadPlainText( wxXmlNode* aSchText );
void loadFrame( wxXmlNode* aFrameNode, std::vector<SCH_LINE*>& aLines );
void loadSegments( wxXmlNode* aSegmentsNode, const wxString& aNetName,
const wxString& aNetClass );
SCH_LINE* loadWire( wxXmlNode* aWireNode );
SCH_TEXT* loadLabel( wxXmlNode* aLabelNode, const wxString& aNetName );
SCH_JUNCTION* loadJunction( wxXmlNode* aJunction );
SCH_TEXT* loadPlainText( wxXmlNode* aSchText );
void loadFrame( wxXmlNode* aFrameNode, std::vector<SCH_LINE*>& aLines );
bool loadSymbol( wxXmlNode* aSymbolNode, std::unique_ptr<LIB_SYMBOL>& aSymbol,
EDEVICE* aDevice, int aGateNumber, const wxString& aGateName );
@ -228,8 +234,13 @@ 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.
std::unique_ptr< PROPERTIES > m_properties; ///< Library plugin properties.
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;

View File

@ -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;

View File

@ -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 );

View File

@ -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 );
}

View File

@ -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
@ -152,16 +157,18 @@ private:
bool isBuffering( const PROPERTIES* aProperties );
protected:
int m_version; ///< Version of file being loaded.
int m_nextFreeFieldId;
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.
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;
OUTPUTFORMATTER* m_out; ///< The formatter for saving SCH_SCREEN objects.
SCH_SEXPR_PLUGIN_CACHE* m_cache;
/// initialize PLUGIN like a constructor would.

View File

@ -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 == ' ' )

View File

@ -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 );
@ -170,17 +176,21 @@ private:
bool isBuffering( const PROPERTIES* aProperties );
protected:
int m_version; ///< Version of file being loaded.
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.
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 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 );

View File

@ -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;

View File

@ -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.

View File

@ -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

View File

@ -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() )
{

View File

@ -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& )
{

View File

@ -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();

View File

@ -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() ) );

View File

@ -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

View File

@ -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;

View File

@ -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 );

View File

@ -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 )

View File

@ -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;

View File

@ -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;

Some files were not shown because too many files have changed in this diff Show More