Move GUI queries in PLUGIN to a callback.

Also makes sure legacy zone fills get deleted and re-filled (since
just dropping the outline will change them).
This commit is contained in:
Jeff Young 2022-02-11 21:38:31 +00:00
parent 300ee022fa
commit 00934fdd84
10 changed files with 139 additions and 54 deletions

View File

@ -58,6 +58,8 @@
#include <dialogs/dialog_imported_layers.h>
#include <tools/pcb_actions.h>
#include "footprint_info_impl.h"
#include "board_commit.h"
#include "zone_filler.h"
#include <wx_filename.h> // For ::ResolvePossibleSymlinks()
#include <wx/wupdlock.h>
@ -693,6 +695,19 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
props["page_width"] = xbuf;
props["page_height"] = ybuf;
pi->SetQueryUserCallback(
[&]( wxString aTitle, int aIcon, wxString aMessage, wxString aAction ) -> bool
{
KIDIALOG dlg( nullptr, aMessage, aTitle, wxOK | wxCANCEL | aIcon );
if( !aAction.IsEmpty() )
dlg.SetOKLabel( aAction );
dlg.DoNotShowCheckbox( aMessage, 0 );
return dlg.ShowModal() == wxID_OK;
} );
#if USE_INSTRUMENTATION
// measure the time to load a BOARD.
unsigned startTime = GetRunningMicroSecs();
@ -856,10 +871,9 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
wxT( "There is no project variable?" ) );
wxString result( newLibPath );
rel_path = result.Replace( env_path,
wxT( "$(" ) + project_env + wxT( ")" ) )
? result
: wxString( wxEmptyString );
if( result.Replace( env_path, wxT( "$(" ) + project_env + wxT( ")" ) ) )
rel_path = result;
FP_LIB_TABLE_ROW* row = new FP_LIB_TABLE_ROW( libNickName, rel_path,
wxT( "KiCad" ), wxEmptyString );
@ -912,6 +926,8 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
if( !converted )
UpdateFileHistory( GetBoard()->GetFileName() );
std::vector<ZONE*> toFill;
// Rebuild list of nets (full ratsnest rebuild)
progressReporter.Report( _( "Updating nets" ) );
GetBoard()->BuildConnectivity( &progressReporter );
@ -927,12 +943,38 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
if( draw3DFrame )
draw3DFrame->NewDisplay();
#if 0 && defined(DEBUG)
// Output the board object tree to stdout, but please run from command prompt:
GetBoard()->Show( 0, std::cout );
#endif
// Re-fill any zones which had their legacy fills deleted on open
for( ZONE* zone : GetBoard()->Zones() )
{
if( zone->GetFlags() & CANDIDATE )
{
toFill.push_back( zone );
zone->ClearTempFlags();
}
}
if( toFill.size() )
{
BOARD_COMMIT commit( this );
ZONE_FILLER filler( GetBoard(), &commit );
progressReporter.Report( _( "Converting zone fills" ) );
filler.SetProgressReporter( &progressReporter );
if( filler.Fill( toFill ) )
{
commit.Push( _( "Convert Zone(s)" ) );
progressReporter.Report( _( "Updating nets" ) );
GetBoard()->BuildConnectivity( &progressReporter );
}
}
// from EDA_APPL which was first loaded BOARD only:
{
/* For an obscure reason the focus is lost after loading a board file

View File

@ -279,6 +279,14 @@ public:
*/
virtual const wxString GetFileExtension() const = 0;
/**
* Registers a KIDIALOG callback for collecting info from the user.
*/
virtual void SetQueryUserCallback( std::function<bool( wxString aTitle, int aIcon,
wxString aMessage,
wxString aAction )> aCallback )
{ }
/**
* Load information from some input file format that this PLUGIN implementation
* knows about into either a new #BOARD or an existing one.

View File

@ -42,6 +42,7 @@
#include <plugins/kicad/pcb_plugin.h>
#include <kicad_clipboard.h>
#include "confirm.h"
CLIPBOARD_IO::CLIPBOARD_IO():
PCB_PLUGIN(CTL_FOR_CLIPBOARD ),
@ -415,8 +416,21 @@ BOARD* CLIPBOARD_IO::Load( const wxString& aFileName, BOARD* aAppendToMe,
result = data.GetText().mb_str();
}
std::function<bool( wxString, int, wxString, wxString )> queryUser =
[&]( wxString aTitle, int aIcon, wxString aMessage, wxString aAction ) -> bool
{
KIDIALOG dlg( nullptr, aMessage, aTitle, wxOK | wxCANCEL | aIcon );
if( !aAction.IsEmpty() )
dlg.SetOKLabel( aAction );
dlg.DoNotShowCheckbox( aMessage, 0 );
return dlg.ShowModal() == wxID_OK;
};
STRING_LINE_READER reader( result, wxT( "clipboard" ) );
PCB_PARSER parser( &reader, aAppendToMe );
PCB_PARSER parser( &reader, aAppendToMe, &queryUser );
init( aProperties );

View File

@ -5441,23 +5441,20 @@ ZONE* PCB_PARSER::parseZONE( BOARD_ITEM_CONTAINER* aParent )
case T_filled_areas_thickness:
if( parseBool() )
{
if( m_showLegacy5ZoneWarning )
if( m_showLegacy5ZoneWarning && m_queryUserCallback )
{
// Thick outline fill mode no longer supported. Make sure user is OK with
// converting fills.
KIDIALOG dlg( nullptr, _( "The legacy zone fill strategy is no longer "
"supported.\nConvert zones to smoothed polygon "
"fills?" ),
_( "Legacy Zone Warning" ), wxYES_NO | wxICON_WARNING );
dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
if( dlg.ShowModal() == wxID_NO )
if( !(*m_queryUserCallback)(
_( "Legacy Zone Warning" ), wxICON_WARNING,
_( "The legacy zone fill strategy is no longer supported.\n"
"Convert zones to smoothed polygon fills?" ),
_( "Convert" ) ) )
{
THROW_IO_ERROR( wxT( "CANCEL" ) );
m_showLegacy5ZoneWarning = false;
}
}
m_showLegacy5ZoneWarning = false;
zone->SetFlags( CANDIDATE );
dropFilledPolygons = true;
}
@ -5484,23 +5481,20 @@ ZONE* PCB_PARSER::parseZONE( BOARD_ITEM_CONTAINER* aParent )
if( token == T_segment ) // deprecated
{
// SEGMENT fill mode no longer supported. Make sure user is OK with
// converting them.
if( m_showLegacySegmentZoneWarning )
if( m_showLegacySegmentZoneWarning && m_queryUserCallback )
{
KIDIALOG dlg( nullptr, _( "The legacy segment fill mode is no longer "
"supported.\nConvert zones to smoothed "
"polygon fills?" ),
_( "Legacy Zone Warning" ), wxYES_NO | wxICON_WARNING );
dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
if( dlg.ShowModal() == wxID_NO )
if( !(*m_queryUserCallback)(
_( "Legacy Zone Warning" ), wxICON_WARNING,
_( "The segment zone fill mode is no longer supported.\n"
"Convert zones to smoothed polygon fills?" ),
_( "Convert" ) ) )
{
THROW_IO_ERROR( wxT( "CANCEL" ) );
m_showLegacySegmentZoneWarning = false;
}
}
m_showLegacySegmentZoneWarning = false;
zone->SetFlags( CANDIDATE );
zone->SetFillMode( ZONE_FILL_MODE::POLYGONS );
m_board->SetModified();
}

View File

@ -72,14 +72,16 @@ class PROGRESS_REPORTER;
class PCB_PARSER : public PCB_LEXER
{
public:
PCB_PARSER( LINE_READER* aReader, BOARD* aBoard = nullptr,
PCB_PARSER( LINE_READER* aReader, BOARD* aBoard,
std::function<bool( wxString, int, wxString, wxString )>* aQueryUserCallback,
PROGRESS_REPORTER* aProgressReporter = nullptr, unsigned aLineCount = 0 ) :
PCB_LEXER( aReader ),
m_board( aBoard ),
m_resetKIIDs( aBoard != nullptr ),
m_progressReporter( aProgressReporter ),
m_lastProgressTime( std::chrono::steady_clock::now() ),
m_lineCount( aLineCount )
m_lineCount( aLineCount ),
m_queryUserCallback( aQueryUserCallback )
{
init();
}
@ -376,6 +378,8 @@ private:
};
std::vector<GROUP_INFO> m_groupInfos;
std::function<bool( wxString aTitle, int aIcon, wxString aMsg, wxString aAction )>* m_queryUserCallback;
};

View File

@ -265,7 +265,7 @@ void FP_CACHE::Load()
try
{
FILE_LINE_READER reader( fn.GetFullPath() );
PCB_PARSER parser( &reader );
PCB_PARSER parser( &reader, nullptr, nullptr );
FOOTPRINT* footprint = (FOOTPRINT*) parser.Parse();
wxString fpName = fn.GetName();
@ -337,17 +337,16 @@ void PCB_PLUGIN::Save( const wxString& aFileName, BOARD* aBoard, const PROPERTIE
wxString sanityResult = aBoard->GroupsSanityCheck();
if( sanityResult != wxEmptyString )
if( sanityResult != wxEmptyString && m_queryUserCallback )
{
KIDIALOG dlg( nullptr, wxString::Format(
_( "Please report this bug. Error validating group structure: %s"
"\n\nSave anyway?" ), sanityResult ),
_( "Internal group data structure corrupt" ),
wxOK | wxCANCEL | wxICON_ERROR );
dlg.SetOKLabel( _( "Save Anyway" ) );
if( dlg.ShowModal() == wxID_CANCEL )
if( !(*m_queryUserCallback)(
_( "Internal Group Data Error" ), wxICON_ERROR,
wxString::Format( _( "Please report this bug. Error validating group "
"structure: %s\n\nSave anyway?" ), sanityResult ),
_( "Save Anyway" ) ) )
{
return;
}
}
init( aProperties );
@ -376,7 +375,7 @@ BOARD_ITEM* PCB_PLUGIN::Parse( const wxString& aClipboardSourceInput )
std::string input = TO_UTF8( aClipboardSourceInput );
STRING_LINE_READER reader( input, wxT( "clipboard" ) );
PCB_PARSER parser( &reader );
PCB_PARSER parser( &reader, nullptr, m_queryUserCallback );
try
{
@ -2241,7 +2240,8 @@ void PCB_PLUGIN::format( const ZONE* aZone, int aNestLevel ) const
PCB_PLUGIN::PCB_PLUGIN( int aControlFlags ) :
m_cache( nullptr ),
m_ctl( aControlFlags ),
m_mapping( new NETINFO_MAPPING() )
m_mapping( new NETINFO_MAPPING() ),
m_queryUserCallback( nullptr )
{
init( nullptr );
m_out = &m_sf;
@ -2255,8 +2255,9 @@ PCB_PLUGIN::~PCB_PLUGIN()
}
BOARD* PCB_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe, const PROPERTIES* aProperties,
PROJECT* aProject, PROGRESS_REPORTER* aProgressReporter )
BOARD* PCB_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe,
const PROPERTIES* aProperties, PROJECT* aProject,
PROGRESS_REPORTER* aProgressReporter )
{
FILE_LINE_READER reader( aFileName );
@ -2290,7 +2291,7 @@ BOARD* PCB_PLUGIN::DoLoad( LINE_READER& aReader, BOARD* aAppendToMe, const PROPE
{
init( aProperties );
PCB_PARSER parser( &aReader, aAppendToMe, aProgressReporter, aLineCount );
PCB_PARSER parser( &aReader, aAppendToMe, m_queryUserCallback, aProgressReporter, aLineCount );
BOARD* board;
try

View File

@ -28,6 +28,7 @@
#include <io_mgr.h>
#include <string>
#include <layer_ids.h>
#include "widgets/report_severity.h"
class BOARD;
class BOARD_ITEM;
@ -115,7 +116,7 @@ class SHAPE_LINE_CHAIN;
//#define SEXPR_BOARD_FILE_VERSION 20211231 // Private footprint layers
//#define SEXPR_BOARD_FILE_VERSION 20211232 // Fonts
//#define SEXPR_BOARD_FILE_VERSION 20220131 // Textboxes
#define SEXPR_BOARD_FILE_VERSION 20220211 // Deprecate V5 zone fill strategy
#define SEXPR_BOARD_FILE_VERSION 20220211 // End support for V5 zone fill strategy
#define BOARD_FILE_HOST_VERSION 20200825 ///< Earlier files than this include the host tag
#define LEGACY_ARC_FORMATTING 20210925 ///< These were the last to use old arc formatting
@ -168,8 +169,14 @@ public:
return wxT( "kicad_pcb" );
}
virtual void Save( const wxString& aFileName, BOARD* aBoard,
const PROPERTIES* aProperties = nullptr ) override;
void SetQueryUserCallback( std::function<bool( wxString aTitle, int aIcon, wxString aMessage,
wxString aOKButtonTitle )> aCallback ) override
{
m_queryUserCallback = &aCallback;
}
void Save( const wxString& aFileName, BOARD* aBoard,
const PROPERTIES* aProperties = nullptr ) override;
BOARD* Load( const wxString& aFileName, BOARD* aAppendToMe,
const PROPERTIES* aProperties = nullptr, PROJECT* aProject = nullptr,
@ -314,6 +321,8 @@ protected:
int m_ctl;
NETINFO_MAPPING* m_mapping; ///< mapping for net codes, so only not empty net codes
///< are stored with consecutive integers as net codes
std::function<bool( wxString aTitle, int aIcon, wxString aMsg, wxString aAction )>* m_queryUserCallback;
};
#endif // PCB_PLUGIN_H

View File

@ -1112,6 +1112,19 @@ int PCB_CONTROL::AppendBoard( PLUGIN& pi, wxString& fileName )
props["page_width"] = xbuf;
props["page_height"] = ybuf;
pi.SetQueryUserCallback(
[&]( wxString aTitle, int aIcon, wxString aMessage, wxString aAction ) -> bool
{
KIDIALOG dlg( editFrame, aMessage, aTitle, wxOK | wxCANCEL | aIcon );
if( !aAction.IsEmpty() )
dlg.SetOKLabel( aAction );
dlg.DoNotShowCheckbox( aMessage, 0 );
return dlg.ShowModal() == wxID_OK;
} );
WX_PROGRESS_REPORTER progressReporter( editFrame, _( "Loading PCB" ), 1 );
editFrame->GetDesignSettings().GetNetClasses().Clear();

View File

@ -52,7 +52,7 @@ bool parse( std::istream& aStream, bool aVerbose )
STDISTREAM_LINE_READER reader;
reader.SetStream( aStream );
PCB_PARSER parser( &reader );
PCB_PARSER parser( &reader, nullptr, nullptr );
BOARD_ITEM* board = nullptr;
PARSE_DURATION duration{};

View File

@ -75,7 +75,7 @@ std::unique_ptr<BOARD_ITEM> ReadBoardItemFromStream( std::istream& aStream )
STDISTREAM_LINE_READER reader;
reader.SetStream( aStream );
PCB_PARSER parser( &reader );
PCB_PARSER parser( &reader, nullptr, nullptr );
std::unique_ptr<BOARD_ITEM> board;
try