Allow cancel, delete or rescue when opening pcbs with undefined layers.

Fixes: lp:1796596
* https://bugs.launchpad.net/kicad/+bug/1796596
This commit is contained in:
Jeff Young 2018-12-07 00:24:27 +00:00
parent 3a0dbf48c8
commit 78daaa8825
6 changed files with 102 additions and 16 deletions

View File

@ -134,6 +134,9 @@ const wxChar* LSET::Name( PCB_LAYER_ID aLayerId )
case F_Fab: txt = wxT( "F.Fab" ); break;
case B_Fab: txt = wxT( "B.Fab" ); break;
// Rescue
case Rescue: txt = wxT( "Rescue" ); break;
default:
std::cout << aLayerId << std::endl;
wxASSERT_MSG( 0, wxT( "aLayerId out of range" ) );

View File

@ -134,6 +134,8 @@ enum PCB_LAYER_ID: int
B_Fab,
F_Fab,
Rescue,
PCB_LAYER_ID_COUNT
};

View File

@ -308,7 +308,9 @@ void KICAD_MANAGER_FRAME::RunEeschema( const wxString& aProjectSchematicFileName
if( !frame->IsShown() ) // A hidden frame might not have the project loaded.
{
frame->OpenProjectFiles( std::vector<wxString>( 1, aProjectSchematicFileName ) );
if( !frame->OpenProjectFiles( std::vector<wxString>( 1, aProjectSchematicFileName ) ) )
return;
frame->Show( true );
}
@ -377,7 +379,9 @@ void KICAD_MANAGER_FRAME::RunPcbNew( const wxString& aProjectBoardFileName )
if( !frame->IsVisible() ) // A hidden frame might not have the board loaded.
{
frame->OpenProjectFiles( std::vector<wxString>( 1, aProjectBoardFileName ) );
if( !frame->OpenProjectFiles( std::vector<wxString>( 1, aProjectBoardFileName ) ) )
return;
frame->Show( true );
}

View File

@ -505,9 +505,12 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
}
catch( const IO_ERROR& ioe )
{
DisplayErrorMessage( this,
wxString::Format( _( "Error loading board file:\n%s" ), fullFileName ),
ioe.What() );
if( ioe.Problem() != wxT( "CANCEL" ) )
{
wxString msg = wxString::Format( _( "Error loading board file:\n%s" ), fullFileName );
DisplayErrorMessage( this, msg, ioe.What() );
}
return false;
}

View File

@ -580,6 +580,88 @@ BOARD* PCB_PARSER::parseBOARD_unchecked()
}
}
if( m_undefinedLayers.size() > 0 )
{
bool deleteItems;
std::vector<BOARD_ITEM*> deleteList;
wxString msg = wxString::Format( _( "Items found on undefined layers. Do you wish to\n"
"rescue them to the Cmts.User layer?" ) );
wxString details = wxString::Format( _( "Undefined layers:" ) );
for( const wxString& undefinedLayer : m_undefinedLayers )
details += wxT( "\n " ) + undefinedLayer;
wxRichMessageDialog dlg( nullptr, msg, _( "Warning" ),
wxYES_NO | wxCANCEL | wxCENTRE | wxICON_WARNING | wxSTAY_ON_TOP );
dlg.ShowDetailedText( details );
dlg.SetYesNoCancelLabels( _( "Rescue" ), _( "Delete" ), _( "Cancel" ) );
switch( dlg.ShowModal() )
{
case wxID_YES: deleteItems = false; break;
case wxID_NO: deleteItems = true; break;
case wxID_CANCEL:
default: THROW_IO_ERROR( wxT( "CANCEL" ) );
}
auto visitItem = [&]( BOARD_ITEM* item )
{
if( item->GetLayer() == Rescue )
{
if( deleteItems )
deleteList.push_back( item );
else
item->SetLayer( Cmts_User );
}
};
for( TRACK* segm = m_board->m_Track; segm; segm = segm->Next() )
{
if( segm->Type() == PCB_VIA_T )
{
VIA* via = (VIA*) segm;
PCB_LAYER_ID top_layer, bottom_layer;
if( via->GetViaType() == VIA_THROUGH )
continue;
via->LayerPair( &top_layer, &bottom_layer );
if( top_layer == Rescue || bottom_layer == Rescue )
{
if( deleteItems )
deleteList.push_back( via );
else
{
if( top_layer == Rescue )
top_layer = F_Cu;
if( bottom_layer == Rescue )
bottom_layer = B_Cu;
via->SetLayerPair( top_layer, bottom_layer );
}
}
}
else
visitItem( segm );
}
for( TRACK* segm = m_board->m_SegZoneDeprecated; segm; segm = segm->Next() )
visitItem( segm );
for( BOARD_ITEM* zone : m_board->Zones() )
visitItem( zone );
for( BOARD_ITEM* drawing : m_board->Drawings() )
visitItem( drawing );
for( BOARD_ITEM* item : deleteList )
m_board->Delete( item );
m_undefinedLayers.clear();
}
return m_board;
}
@ -976,17 +1058,8 @@ T PCB_PARSER::lookUpLayer( const M& aMap )
}
#endif
wxString error = wxString::Format( _(
"Layer \"%s\" in file\n"
"\"%s\"\n"
"at line %d, position %d\n"
"was not defined in the layers section"
),
GetChars( FROM_UTF8( CurText() ) ),
GetChars( CurSource() ),
CurLineNumber(), CurOffset() );
THROW_IO_ERROR( error );
m_undefinedLayers.insert( curText );
return Rescue;
}
return it->second;

View File

@ -70,6 +70,7 @@ class PCB_PARSER : public PCB_LEXER
BOARD* m_board;
LAYER_ID_MAP m_layerIndices; ///< map layer name to it's index
LSET_MAP m_layerMasks; ///< map layer names to their masks
std::set<wxString> m_undefinedLayers; ///< set of layers not defined in layers section
std::vector<int> m_netCodes; ///< net codes mapping for boards being loaded
bool m_tooRecent; ///< true if version parses as later than supported
int m_requiredVersion; ///< set to the KiCad format version this board requires