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:
parent
3a0dbf48c8
commit
78daaa8825
|
@ -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" ) );
|
||||
|
|
|
@ -134,6 +134,8 @@ enum PCB_LAYER_ID: int
|
|||
B_Fab,
|
||||
F_Fab,
|
||||
|
||||
Rescue,
|
||||
|
||||
PCB_LAYER_ID_COUNT
|
||||
};
|
||||
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue