Optionally sort reporter messages

It can be useful to have similar class messages grouped together so that
error messages in a larger report don't get lost among the
warning/info/action messages.

This patch allows sorting of messages for dialogs that benefit from
organization.  Default behavior of reporter messages remains
unchanged by this patch.

Fixes: lp:1772090
* https://bugs.launchpad.net/kicad/+bug/1772090
This commit is contained in:
Seth Hillbrand 2018-05-21 15:28:26 -07:00
parent b8f960ea09
commit 8c5037a48b
15 changed files with 161 additions and 79 deletions

View File

@ -19,6 +19,8 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <algorithm>
#include "wx_html_report_panel.h" #include "wx_html_report_panel.h"
#include <wildcards_and_files_ext.h> #include <wildcards_and_files_ext.h>
@ -62,15 +64,19 @@ REPORTER& WX_HTML_REPORT_PANEL::Reporter()
} }
void WX_HTML_REPORT_PANEL::Report( const wxString& aText, REPORTER::SEVERITY aSeverity ) void WX_HTML_REPORT_PANEL::Report( const wxString& aText, REPORTER::SEVERITY aSeverity,
REPORTER::LOCATION aLocation )
{ {
REPORT_LINE line; REPORT_LINE line;
line.message = aText; line.message = aText;
line.severity = aSeverity; line.severity = aSeverity;
m_report.push_back( line ); if( aLocation == REPORTER::LOC_HEAD )
m_reportHead.push_back( line );
m_html += generateHtml( line ); else if( aLocation == REPORTER::LOC_TAIL )
m_reportTail.push_back( line );
else
m_report.push_back( line );
if( !m_lazyUpdate ) if( !m_lazyUpdate )
{ {
@ -86,9 +92,29 @@ void WX_HTML_REPORT_PANEL::SetLazyUpdate( bool aLazyUpdate )
} }
void WX_HTML_REPORT_PANEL::Flush() void WX_HTML_REPORT_PANEL::Flush( bool aSort )
{ {
m_htmlView->SetPage( addHeader( m_html ) ); wxString html;
if( aSort )
{
std::sort( m_report.begin(), m_report.end(),
[]( REPORT_LINE& a, REPORT_LINE& b)
{
return a.severity < b.severity;
});
}
for( auto line : m_reportHead )
html += generateHtml( line );
for( auto line : m_report )
html += generateHtml( line );
for( auto line : m_reportTail )
html += generateHtml( line );
m_htmlView->SetPage( addHeader( html ) );
scrollToBottom(); scrollToBottom();
} }
@ -192,20 +218,6 @@ void WX_HTML_REPORT_PANEL::updateBadges()
} }
void WX_HTML_REPORT_PANEL::refreshView()
{
wxString html;
for( const REPORT_LINE& l : m_report )
{
html += generateHtml( l );
}
m_htmlView->SetPage( addHeader( html ) );
scrollToBottom();
}
wxString WX_HTML_REPORT_PANEL::addHeader( const wxString& aBody ) wxString WX_HTML_REPORT_PANEL::addHeader( const wxString& aBody )
{ {
wxColour bgcolor = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ); wxColour bgcolor = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW );
@ -310,7 +322,7 @@ void WX_HTML_REPORT_PANEL::onCheckBoxShowAll( wxCommandEvent& event )
m_showAll = false; m_showAll = false;
syncCheckboxes(); syncCheckboxes();
refreshView(); Flush( true );
} }
@ -326,45 +338,45 @@ void WX_HTML_REPORT_PANEL::syncCheckboxes()
void WX_HTML_REPORT_PANEL::onCheckBoxShowWarnings( wxCommandEvent& event ) void WX_HTML_REPORT_PANEL::onCheckBoxShowWarnings( wxCommandEvent& event )
{ {
if ( event.IsChecked() ) if( event.IsChecked() )
m_severities |= REPORTER::RPT_WARNING; m_severities |= REPORTER::RPT_WARNING;
else else
m_severities &= ~REPORTER::RPT_WARNING; m_severities &= ~REPORTER::RPT_WARNING;
refreshView(); Flush( true );
} }
void WX_HTML_REPORT_PANEL::onCheckBoxShowErrors( wxCommandEvent& event ) void WX_HTML_REPORT_PANEL::onCheckBoxShowErrors( wxCommandEvent& event )
{ {
if ( event.IsChecked() ) if( event.IsChecked() )
m_severities |= REPORTER::RPT_ERROR; m_severities |= REPORTER::RPT_ERROR;
else else
m_severities &= ~REPORTER::RPT_ERROR; m_severities &= ~REPORTER::RPT_ERROR;
refreshView(); Flush( true );
} }
void WX_HTML_REPORT_PANEL::onCheckBoxShowInfos( wxCommandEvent& event ) void WX_HTML_REPORT_PANEL::onCheckBoxShowInfos( wxCommandEvent& event )
{ {
if ( event.IsChecked() ) if( event.IsChecked() )
m_severities |= REPORTER::RPT_INFO; m_severities |= REPORTER::RPT_INFO;
else else
m_severities &= ~REPORTER::RPT_INFO; m_severities &= ~REPORTER::RPT_INFO;
refreshView(); Flush( true );
} }
void WX_HTML_REPORT_PANEL::onCheckBoxShowActions( wxCommandEvent& event ) void WX_HTML_REPORT_PANEL::onCheckBoxShowActions( wxCommandEvent& event )
{ {
if ( event.IsChecked() ) if( event.IsChecked() )
m_severities |= REPORTER::RPT_ACTION; m_severities |= REPORTER::RPT_ACTION;
else else
m_severities &= ~REPORTER::RPT_ACTION; m_severities &= ~REPORTER::RPT_ACTION;
refreshView(); Flush( true );
} }
@ -406,8 +418,9 @@ void WX_HTML_REPORT_PANEL::onBtnSaveToFile( wxCommandEvent& event )
void WX_HTML_REPORT_PANEL::Clear() void WX_HTML_REPORT_PANEL::Clear()
{ {
m_html.clear();
m_report.clear(); m_report.clear();
m_reportHead.clear();
m_reportTail.clear();
} }

View File

@ -52,8 +52,14 @@ public:
///> returns the reporter object that reports to this panel ///> returns the reporter object that reports to this panel
REPORTER& Reporter(); REPORTER& Reporter();
///> reports a string directly. /**
void Report( const wxString& aText, REPORTER::SEVERITY aSeverity ); * Reports the string
* @param aText string message to report
* @param aSeverity string classification level bitfield
* @param aLocation REPORTER::LOCATION enum for placement of message
*/
void Report( const wxString& aText, REPORTER::SEVERITY aSeverity,
REPORTER::LOCATION aLocation = REPORTER::LOC_BODY );
///> clears the report panel ///> clears the report panel
void Clear(); void Clear();
@ -70,7 +76,8 @@ public:
void SetLazyUpdate( bool aLazyUpdate ); void SetLazyUpdate( bool aLazyUpdate );
///> Forces updating the HTML page, after the report is built in lazy mode ///> Forces updating the HTML page, after the report is built in lazy mode
void Flush(); ///> If aSort = true, the body messages will be ordered by severity
void Flush( bool aSort = false );
///> Set the visible severity filter. ///> Set the visible severity filter.
///> if aSeverities < 0 the m_showAll option is set ///> if aSeverities < 0 the m_showAll option is set
@ -94,7 +101,6 @@ private:
wxString generatePlainText( const REPORT_LINE& aLine ); wxString generatePlainText( const REPORT_LINE& aLine );
void updateBadges(); void updateBadges();
void refreshView();
void scrollToBottom(); void scrollToBottom();
void syncCheckboxes(); void syncCheckboxes();
@ -111,6 +117,12 @@ private:
///> copy of the report, stored for filtering ///> copy of the report, stored for filtering
REPORT_LINES m_report; REPORT_LINES m_report;
///> Lines to print at the very end of the report, regardless of sorting
REPORT_LINES m_reportTail;
///> Lines to print at the very beginning of the report, regardless of sorting
REPORT_LINES m_reportHead;
///> the reporter ///> the reporter
WX_HTML_PANEL_REPORTER m_reporter; WX_HTML_PANEL_REPORTER m_reporter;
@ -120,8 +132,6 @@ private:
///> show all messages flag (overrides m_severities) ///> show all messages flag (overrides m_severities)
bool m_showAll; bool m_showAll;
wxString m_html;
bool m_lazyUpdate; bool m_lazyUpdate;
}; };

View File

@ -73,6 +73,24 @@ REPORTER& WX_HTML_PANEL_REPORTER::Report( const wxString& aText, SEVERITY aSever
return *this; return *this;
} }
REPORTER& WX_HTML_PANEL_REPORTER::ReportTail( const wxString& aText, SEVERITY aSeverity )
{
wxCHECK_MSG( m_panel != NULL, *this,
wxT( "No WX_HTML_REPORT_PANEL object defined in WX_HTML_PANEL_REPORTER." ) );
m_panel->Report( aText, aSeverity, LOC_TAIL );
return *this;
}
REPORTER& WX_HTML_PANEL_REPORTER::ReportHead( const wxString& aText, SEVERITY aSeverity )
{
wxCHECK_MSG( m_panel != NULL, *this,
wxT( "No WX_HTML_REPORT_PANEL object defined in WX_HTML_PANEL_REPORTER." ) );
m_panel->Report( aText, aSeverity, LOC_HEAD );
return *this;
}
bool WX_HTML_PANEL_REPORTER::HasMessage() const bool WX_HTML_PANEL_REPORTER::HasMessage() const
{ {
return m_panel->Count( REPORTER::RPT_ERROR | REPORTER::RPT_WARNING ) > 0; return m_panel->Count( REPORTER::RPT_ERROR | REPORTER::RPT_WARNING ) > 0;

View File

@ -110,7 +110,7 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic,
{ {
wxString msg; wxString msg;
msg.Printf( _( "%d duplicate time stamps were found and replaced." ), count ); msg.Printf( _( "%d duplicate time stamps were found and replaced." ), count );
aReporter.Report( msg, REPORTER::RPT_WARNING ); aReporter.ReportTail( msg, REPORTER::RPT_WARNING );
} }
} }
@ -228,7 +228,7 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic,
// Final control (just in case ... ). // Final control (just in case ... ).
if( !CheckAnnotate( aReporter, !aAnnotateSchematic ) ) if( !CheckAnnotate( aReporter, !aAnnotateSchematic ) )
aReporter.Report( _( "Annotation complete." ), REPORTER::RPT_ACTION ); aReporter.ReportTail( _( "Annotation complete." ), REPORTER::RPT_ACTION );
OnModify(); OnModify();

View File

@ -223,7 +223,7 @@ void DIALOG_ANNOTATE::OnApplyClick( wxCommandEvent& event )
(ANNOTATE_OPTION_T) GetAnnotateAlgo(), GetStartNumber(), (ANNOTATE_OPTION_T) GetAnnotateAlgo(), GetStartNumber(),
GetResetItems() , true, GetLockUnits(), reporter ); GetResetItems() , true, GetLockUnits(), reporter );
m_MessageWindow->Flush(); // Now update to show all messages m_MessageWindow->Flush( true ); // Now update to show all messages
m_Parent->GetCanvas()->Refresh(); m_Parent->GetCanvas()->Refresh();

View File

@ -475,7 +475,7 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter )
if( m_parent->CheckAnnotate( aReporter, false ) ) if( m_parent->CheckAnnotate( aReporter, false ) )
{ {
if( aReporter.HasMessage() ) if( aReporter.HasMessage() )
aReporter.Report( _( "Annotation required!" ), REPORTER::RPT_ERROR ); aReporter.ReportTail( _( "Annotation required!" ), REPORTER::RPT_ERROR );
return; return;
} }
@ -624,7 +624,7 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter )
m_parent->GetCanvas()->Refresh(); m_parent->GetCanvas()->Refresh();
// Display message // Display message
aReporter.Report( _( "Finished" ), REPORTER::RPT_INFO ); aReporter.ReportTail( _( "Finished" ), REPORTER::RPT_INFO );
if( m_writeErcFile ) if( m_writeErcFile )
{ {

View File

@ -214,10 +214,10 @@ void DIALOG_SYMBOL_REMAP::createProjectSymbolLibTable( REPORTER& aReporter )
{ {
msg.Printf( _( "Failed to write project symbol library table. Error:\n %s" ), msg.Printf( _( "Failed to write project symbol library table. Error:\n %s" ),
ioe.What() ); ioe.What() );
aReporter.Report( msg, REPORTER::RPT_ERROR ); aReporter.ReportTail( msg, REPORTER::RPT_ERROR );
} }
aReporter.Report( _( "Created project symbol library table.\n" ), REPORTER::RPT_INFO ); aReporter.ReportTail( _( "Created project symbol library table.\n" ), REPORTER::RPT_INFO );
} }
} }
} }

View File

@ -114,16 +114,14 @@ bool SCH_EDIT_FRAME::WriteNetListFile( NETLIST_OBJECT_LIST* aConnectedItemsList,
msg << _( "Run command:" ) << wxT( "\n" ) << commandLine << wxT( "\n\n" ); msg << _( "Run command:" ) << wxT( "\n" ) << commandLine << wxT( "\n\n" );
aReporter->Report( msg, REPORTER::RPT_ACTION ); aReporter->ReportHead( msg, REPORTER::RPT_ACTION );
if( diag != 0 ) if( diag != 0 )
aReporter->Report( wxString::Format( aReporter->ReportTail( wxString::Format(
_("Command error. Return code %d" ), diag ), _("Command error. Return code %d" ), diag ),
REPORTER::RPT_ERROR ); REPORTER::RPT_ERROR );
else else
aReporter->Report( _( "Success" ), REPORTER::RPT_INFO ); aReporter->ReportTail( _( "Success" ), REPORTER::RPT_INFO );
*aReporter << wxT("\n");
if( output.GetCount() ) if( output.GetCount() )
{ {

View File

@ -145,7 +145,7 @@ bool GERBER_JOBFILE_READER::ReadGerberJobFile()
else else
{ {
if( m_reporter ) if( m_reporter )
m_reporter->Report( _( "This job file uses an outdated format. Please, recreate it" ), m_reporter->ReportTail( _( "This job file uses an outdated format. Please, recreate it" ),
REPORTER::RPT_WARNING ); REPORTER::RPT_WARNING );
return false; return false;

View File

@ -61,13 +61,34 @@ class WX_HTML_REPORT_PANEL;
class REPORTER { class REPORTER {
public: public:
///> Severity of the reported messages. /**
* Severity of the reported messages.
* Undefined are default status messages
* Info are processing messages for which no action is taken
* Action messages are items that modify the file(s) as expected
* Warning messages are items that might be problematic but don't prevent
* the process from completing
* Error messages are items that prevent the process from completing
*/
//
enum SEVERITY { enum SEVERITY {
RPT_UNDEFINED = 0x0, RPT_UNDEFINED = 0x0,
RPT_INFO = 0x1, RPT_INFO = 0x1,
RPT_WARNING = 0x2, RPT_ACTION = 0x2,
RPT_ERROR = 0x4, RPT_WARNING = 0x4,
RPT_ACTION = 0x8 RPT_ERROR = 0x8
};
/**
* Location where the message is to be reported.
* LOC_HEAD messages are printed before all others (typically intro messages)
* LOC_BODY messages are printed in the middle
* LOC_TAIL messages are printed after all others (typically status messages)
*/
enum LOCATION {
LOC_HEAD = 0,
LOC_BODY,
LOC_TAIL
}; };
/** /**
@ -81,6 +102,24 @@ public:
virtual REPORTER& Report( const wxString& aText, SEVERITY aSeverity = RPT_UNDEFINED ) = 0; virtual REPORTER& Report( const wxString& aText, SEVERITY aSeverity = RPT_UNDEFINED ) = 0;
/**
* Function ReportTail
* Places the report at the end of the list, for objects that support report ordering
*/
virtual REPORTER& ReportTail( const wxString& aText, SEVERITY aSeverity = RPT_UNDEFINED )
{
return Report( aText, aSeverity );
}
/**
* Function ReportHead
* Places the report at the beginning of the list for objects that support ordering
*/
virtual REPORTER& ReportHead( const wxString& aText, SEVERITY aSeverity = RPT_UNDEFINED )
{
return Report( aText, aSeverity );
}
REPORTER& Report( const char* aText, SEVERITY aSeverity = RPT_UNDEFINED ); REPORTER& Report( const char* aText, SEVERITY aSeverity = RPT_UNDEFINED );
REPORTER& operator <<( const wxString& aText ) { return Report( aText ); } REPORTER& operator <<( const wxString& aText ) { return Report( aText ); }
@ -155,6 +194,10 @@ public:
REPORTER& Report( const wxString& aText, SEVERITY aSeverity = RPT_UNDEFINED ) override; REPORTER& Report( const wxString& aText, SEVERITY aSeverity = RPT_UNDEFINED ) override;
REPORTER& ReportTail( const wxString& aText, SEVERITY aSeverity = RPT_UNDEFINED ) override;
REPORTER& ReportHead( const wxString& aText, SEVERITY aSeverity = RPT_UNDEFINED ) override;
bool HasMessage() const override; bool HasMessage() const override;
}; };

View File

@ -774,15 +774,15 @@ bool BOARD_NETLIST_UPDATER::UpdateNetlist( NETLIST& aNetlist )
} }
// Update the ratsnest // Update the ratsnest
m_reporter->Report( wxT( "" ), REPORTER::RPT_ACTION ); m_reporter->ReportTail( wxT( "" ), REPORTER::RPT_ACTION );
m_reporter->Report( wxT( "" ), REPORTER::RPT_ACTION ); m_reporter->ReportTail( wxT( "" ), REPORTER::RPT_ACTION );
msg.Printf( _( "Total warnings: %d, errors: %d." ), m_warningCount, m_errorCount ); msg.Printf( _( "Total warnings: %d, errors: %d." ), m_warningCount, m_errorCount );
m_reporter->Report( msg, REPORTER::RPT_ACTION ); m_reporter->ReportTail( msg, REPORTER::RPT_ACTION );
if( m_errorCount ) if( m_errorCount )
{ {
m_reporter->Report( _( "Errors occurred during the netlist update. Unless you " m_reporter->ReportTail( _( "Errors occurred during the netlist update. Unless you "
"fix them, your board will not be consistent with the schematics." ), "fix them, your board will not be consistent with the schematics." ),
REPORTER::RPT_ERROR ); REPORTER::RPT_ERROR );
@ -790,7 +790,7 @@ bool BOARD_NETLIST_UPDATER::UpdateNetlist( NETLIST& aNetlist )
} }
else else
{ {
m_reporter->Report( _( "Netlist update successful!" ), REPORTER::RPT_ACTION ); m_reporter->ReportTail( _( "Netlist update successful!" ), REPORTER::RPT_ACTION );
} }
return true; return true;

View File

@ -310,7 +310,7 @@ void DIALOG_EXCHANGE_FOOTPRINTS::OnApplyClick( wxCommandEvent& event )
bool result = false; bool result = false;
m_MessageWindow->Clear(); m_MessageWindow->Clear();
m_MessageWindow->Flush(); m_MessageWindow->Flush( true );
if( getMatchMode() == ID_MATCH_FP_REF && m_currentModule ) if( getMatchMode() == ID_MATCH_FP_REF && m_currentModule )
result = changeCurrentFootprint(); result = changeCurrentFootprint();
@ -334,7 +334,7 @@ void DIALOG_EXCHANGE_FOOTPRINTS::RebuildCmpList( wxCommandEvent& event )
wxString msg; wxString msg;
REPORTER& reporter = m_MessageWindow->Reporter(); REPORTER& reporter = m_MessageWindow->Reporter();
m_MessageWindow->Clear(); m_MessageWindow->Clear();
m_MessageWindow->Flush(); m_MessageWindow->Flush( true );
// Build the .cmp file name from the board name // Build the .cmp file name from the board name
wxFileName fn = m_parent->GetBoard()->GetFileName(); wxFileName fn = m_parent->GetBoard()->GetFileName();

View File

@ -309,7 +309,7 @@ void DIALOG_EXPORT_STEP::onExportButton( wxCommandEvent& aEvent )
bool success = false; bool success = false;
wxArrayString output, errors; wxArrayString output, errors;
REPORTER& reporter = m_messagesPanel->Reporter(); REPORTER& reporter = m_messagesPanel->Reporter();
reporter.Report( wxString::Format( _( "Executing '%s'" ), cmdK2S ), REPORTER::RPT_ACTION ); reporter.ReportHead( wxString::Format( _( "Executing '%s'" ), cmdK2S ), REPORTER::RPT_ACTION );
{ {
wxBusyCursor dummy; wxBusyCursor dummy;
@ -334,17 +334,17 @@ void DIALOG_EXPORT_STEP::onExportButton( wxCommandEvent& aEvent )
{ {
if( !success ) if( !success )
{ {
reporter.Report( _( "Unable to create STEP file. Check that the board has a " reporter.ReportTail( _( "Unable to create STEP file. Check that the board has a "
"valid outline and models." ), REPORTER::RPT_ERROR ); "valid outline and models." ), REPORTER::RPT_ERROR );
} }
else else
{ {
reporter.Report( _( "STEP file has been created, but there are warnings." ), reporter.ReportTail( _( "STEP file has been created, but there are warnings." ),
REPORTER::RPT_INFO ); REPORTER::RPT_INFO );
} }
} }
else else
{ {
reporter.Report( _( "STEP file has been created successfully." ), REPORTER::RPT_INFO ); reporter.ReportTail( _( "STEP file has been created successfully." ), REPORTER::RPT_INFO );
} }
} }

View File

@ -188,14 +188,14 @@ void DIALOG_NETLIST::OnReadNetlistFileClick( wxCommandEvent& event )
wxString msg; wxString msg;
msg.Printf( _( "Reading netlist file \"%s\".\n" ), GetChars( netlistFileName ) ); msg.Printf( _( "Reading netlist file \"%s\".\n" ), GetChars( netlistFileName ) );
reporter.Report( msg, REPORTER::RPT_INFO ); reporter.ReportHead( msg, REPORTER::RPT_INFO );
if( m_Select_By_Timestamp->GetSelection() == 1 ) if( m_Select_By_Timestamp->GetSelection() == 1 )
msg = _( "Using time stamps to match components and footprints.\n" ); msg = _( "Using time stamps to match components and footprints.\n" );
else else
msg = _( "Using references to match components and footprints.\n" ); msg = _( "Using references to match components and footprints.\n" );
reporter.Report( msg, REPORTER::RPT_INFO ); reporter.ReportHead( msg, REPORTER::RPT_INFO );
m_MessageWindow->SetLazyUpdate( true ); // use a "lazy" update to speed up the creation of the report m_MessageWindow->SetLazyUpdate( true ); // use a "lazy" update to speed up the creation of the report
// (The window is not updated for each message) // (The window is not updated for each message)
@ -208,7 +208,7 @@ void DIALOG_NETLIST::OnReadNetlistFileClick( wxCommandEvent& event )
m_checkDryRun->GetValue() ); m_checkDryRun->GetValue() );
// The creation of the report was made without window update: // The creation of the report was made without window update:
// the full page must be displayed // the full page must be displayed
m_MessageWindow->Flush(); m_MessageWindow->Flush( true );
} }

View File

@ -95,9 +95,9 @@ void DIALOG_UPDATE_PCB::PerformUpdate( bool aDryRun )
{ {
wxString msg; wxString msg;
reporter.Report( _( "Failed to load one or more footprints. Please add the missing libraries in PCBNew configuration. " reporter.ReportTail( _( "Failed to load one or more footprints. Please add the missing libraries in PCBNew configuration. "
"The PCB will not update completely." ), REPORTER::RPT_ERROR ); "The PCB will not update completely." ), REPORTER::RPT_ERROR );
reporter.Report( error.What(), REPORTER::RPT_INFO ); reporter.ReportTail( error.What(), REPORTER::RPT_INFO );
} }
BOARD_NETLIST_UPDATER updater( m_frame, m_frame->GetBoard() ); BOARD_NETLIST_UPDATER updater( m_frame, m_frame->GetBoard() );
@ -109,7 +109,7 @@ void DIALOG_UPDATE_PCB::PerformUpdate( bool aDryRun )
updater.SetDeleteSinglePadNets( false ); updater.SetDeleteSinglePadNets( false );
updater.UpdateNetlist( *m_netlist ); updater.UpdateNetlist( *m_netlist );
m_messagePanel->Flush(); m_messagePanel->Flush( true );
if( aDryRun ) if( aDryRun )
return; return;