From 6d39b53efb54cd8432a153264a8ac9d593e7561a Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Mon, 16 Jan 2012 15:43:07 -0600 Subject: [PATCH] try and support Electra *.ses files --- pcbnew/specctra.cpp | 44 +++++++++++++++- pcbnew/specctra.h | 1 + pcbnew/specctra_import.cpp | 105 ++++++++++++++++++------------------- 3 files changed, 95 insertions(+), 55 deletions(-) diff --git a/pcbnew/specctra.cpp b/pcbnew/specctra.cpp index d1920db789..222c316bce 100644 --- a/pcbnew/specctra.cpp +++ b/pcbnew/specctra.cpp @@ -872,6 +872,41 @@ void SPECCTRA_DB::doKEEPOUT( KEEPOUT* growth ) throw( IO_ERROR ) } +void SPECCTRA_DB::doCONNECT( CONNECT* growth ) throw( IO_ERROR ) +{ + /* from page 143 of specctra spec: + + (connect + {(terminal [ ])} + ) + */ + + T tok = NextTok(); + + while( tok != T_RIGHT ) + { + if( tok!=T_LEFT ) + Expecting( T_LEFT ); + + tok = NextTok(); + + switch( tok ) + { + case T_terminal: + // since we do not use the terminal information, simlpy toss it. + while( ( tok = NextTok() ) != T_RIGHT && tok != T_EOF ) + ; + break; + + default: + Unexpected( CurText() ); + } + + tok = NextTok(); + } +} + + void SPECCTRA_DB::doWINDOW( WINDOW* growth ) throw( IO_ERROR ) { T tok = NextTok(); @@ -2823,10 +2858,8 @@ void SPECCTRA_DB::doWIRE( WIRE* growth ) throw( IO_ERROR ) case T_connect: if( growth->connect ) Unexpected( tok ); -/* @todo growth->connect = new CONNECT( growth ); doCONNECT( growth->connect ); -*/ break; case T_supply: @@ -3245,7 +3278,14 @@ void SPECCTRA_DB::doROUTE( ROUTE* growth ) throw( IO_ERROR ) case T_parser: if( growth->parser ) + { +#if 0 // Electra 2.9.1 emits two (parser ) elements in a row. + // Work around their bug for now. Unexpected( tok ); +#else + delete growth->parser; +#endif + } growth->parser = new PARSER( growth ); doPARSER( growth->parser ); break; diff --git a/pcbnew/specctra.h b/pcbnew/specctra.h index bfc8ba2f43..79d10bf7f0 100644 --- a/pcbnew/specctra.h +++ b/pcbnew/specctra.h @@ -3668,6 +3668,7 @@ class SPECCTRA_DB : public SPECCTRA_LEXER void doCIRCLE( CIRCLE* growth ) throw( IO_ERROR ); void doQARC( QARC* growth ) throw( IO_ERROR ); void doWINDOW( WINDOW* growth ) throw( IO_ERROR ); + void doCONNECT( CONNECT* growth ) throw( IO_ERROR ); void doREGION( REGION* growth ) throw( IO_ERROR ); void doCLASS_CLASS( CLASS_CLASS* growth ) throw( IO_ERROR ); void doLAYER_RULE( LAYER_RULE* growth ) throw( IO_ERROR ); diff --git a/pcbnew/specctra_import.cpp b/pcbnew/specctra_import.cpp index bf777c03ee..c72552d69d 100644 --- a/pcbnew/specctra_import.cpp +++ b/pcbnew/specctra_import.cpp @@ -95,7 +95,7 @@ void PCB_EDIT_FRAME::ImportSpecctraSession( wxCommandEvent& event ) SPECCTRA_DB db; - SetLocaleTo_C_standard( ); // Switch the locale to standard C + LOCALE_IO toggle; try { @@ -104,8 +104,6 @@ void PCB_EDIT_FRAME::ImportSpecctraSession( wxCommandEvent& event ) } catch( IO_ERROR& ioe ) { - SetLocaleTo_Default( ); // revert to the current locale - ioe.errorText += '\n'; ioe.errorText += _("BOARD may be corrupted, do not save it."); ioe.errorText += '\n'; @@ -115,8 +113,6 @@ void PCB_EDIT_FRAME::ImportSpecctraSession( wxCommandEvent& event ) return; } - SetLocaleTo_Default( ); // revert to the current locale - OnModify(); GetBoard()->m_Status_Pcb = 0; @@ -363,8 +359,10 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IO_ERROR ) if( !session ) ThrowIOError( _("Session file is missing the \"session\" section") ); + /* Dick 16-Jan-2012: session need not have a placement section. if( !session->placement ) ThrowIOError( _("Session file is missing the \"placement\" section") ); + */ if( !session->route ) ThrowIOError( _("Session file is missing the \"routes\" section") ); @@ -379,65 +377,66 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IO_ERROR ) buildLayerMaps( aBoard ); -#if 1 - // Walk the PLACEMENT object's COMPONENTs list, and for each PLACE within - // each COMPONENT, reposition and re-orient each component and put on - // correct side of the board. - COMPONENTS& components = session->placement->components; - for( COMPONENTS::iterator comp=components.begin(); comp!=components.end(); ++comp ) + if( session->placement ) { - PLACES& places = comp->places; - for( unsigned i=0; iplacement->components; + for( COMPONENTS::iterator comp=components.begin(); comp!=components.end(); ++comp ) { - PLACE* place = &places[i]; // '&' even though places[] holds a pointer! - - wxString reference = FROM_UTF8( place->component_id.c_str() ); - MODULE* module = aBoard->FindModuleByReference( reference ); - if( !module ) + PLACES& places = comp->places; + for( unsigned i=0; ihasVertex ) - continue; - - UNIT_RES* resolution = place->GetUnits(); - wxASSERT( resolution ); - - wxPoint newPos = mapPt( place->vertex, resolution ); - module->SetPosition( newPos ); - - if( place->side == T_front ) - { - // convert from degrees to tenths of degrees used in KiCad. - int orientation = (int) (place->rotation * 10.0); - if( module->GetLayer() != LAYER_N_FRONT ) + wxString reference = FROM_UTF8( place->component_id.c_str() ); + MODULE* module = aBoard->FindModuleByReference( reference ); + if( !module ) { - // module is on copper layer (back) - module->Flip( module->m_Pos ); + ThrowIOError( + _("Session file has 'reference' to non-existent component \"%s\""), + GetChars( reference ) ); } - module->SetOrientation( orientation ); - } - else if( place->side == T_back ) - { - int orientation = (int) ((place->rotation + 180.0) * 10.0); - if( module->GetLayer() != LAYER_N_BACK ) + + if( !place->hasVertex ) + continue; + + UNIT_RES* resolution = place->GetUnits(); + wxASSERT( resolution ); + + wxPoint newPos = mapPt( place->vertex, resolution ); + module->SetPosition( newPos ); + + if( place->side == T_front ) { - // module is on component layer (front) - module->Flip( module->m_Pos ); + // convert from degrees to tenths of degrees used in KiCad. + int orientation = (int) (place->rotation * 10.0); + if( module->GetLayer() != LAYER_N_FRONT ) + { + // module is on copper layer (back) + module->Flip( module->m_Pos ); + } + module->SetOrientation( orientation ); + } + else if( place->side == T_back ) + { + int orientation = (int) ((place->rotation + 180.0) * 10.0); + if( module->GetLayer() != LAYER_N_BACK ) + { + // module is on component layer (front) + module->Flip( module->m_Pos ); + } + module->SetOrientation( orientation ); + } + else + { + // as I write this, the PARSER *is* catching this, so we should never see below: + wxFAIL_MSG( wxT("DSN::PARSER did not catch an illegal side := 'back|front'") ); } - module->SetOrientation( orientation ); - } - else - { - // as I write this, the PARSER *is* catching this, so we should never see below: - wxFAIL_MSG( wxT("DSN::PARSER did not catch an illegal side := 'back|front'") ); } } } -#endif routeResolution = session->route->GetUnits();