diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index b2d0443e35..5de90041b3 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -726,7 +726,37 @@ EQUIPOT* BOARD::FindNet( const wxString & aNetname ) const } +MODULE* BOARD::FindModuleByReference( const wxString& aReference ) const +{ + struct FindModule : public INSPECTOR + { + MODULE* found; + FindModule() : found(0) {} + // implement interface INSPECTOR + SEARCH_RESULT Inspect( EDA_BaseStruct* item, const void* data ) + { + MODULE* module = (MODULE*) item; + const wxString& ref = *(const wxString*) data; + + if( ref == module->GetReference() ) + { + found = module; + return SEARCH_QUIT; + } + return SEARCH_CONTINUE; + } + } inspector; + + // search only for MODULES + static const KICAD_T scanTypes[] = { TYPEMODULE, EOT }; + + // visit this BOARD with the above inspector + BOARD* nonconstMe = (BOARD*) this; + nonconstMe->Visit( &inspector, &aReference, scanTypes ); + + return inspector.found; +} /* Two sort functions used in BOARD::ReturnSortedNetnamesList */ diff --git a/pcbnew/class_board.h b/pcbnew/class_board.h index 054ba0ea78..6bff0a1c2c 100644 --- a/pcbnew/class_board.h +++ b/pcbnew/class_board.h @@ -203,6 +203,17 @@ public: */ EQUIPOT* FindNet( const wxString & aNetname ) const; + /** + * Function FindModuleByReference + * searches for a MODULE within this board with the given + * reference designator. Finds only the first one, if there + * is more than one such MODULE. + * @param aReference The reference designator of the MODULE to find. + * @return MODULE* - If found, the MODULE having the given reference + * designator, else NULL. + */ + MODULE* FindModuleByReference( const wxString& aReference ) const; + /** * Function ReturnSortedNetnamesList * searches for a net with the given netcode. diff --git a/pcbnew/specctra.cpp b/pcbnew/specctra.cpp index d1f8009023..35a3163dbe 100644 --- a/pcbnew/specctra.cpp +++ b/pcbnew/specctra.cpp @@ -3854,6 +3854,8 @@ int main( int argc, char** argv ) SPECCTRA_DB db; bool failed = false; + setlocale( LC_NUMERIC, "C" ); // Switch the locale to standard C + if( argc == 2 ) { filename = CONV_FROM_UTF8( argv[1] ); @@ -3882,6 +3884,8 @@ int main( int argc, char** argv ) // hose the beautified DSN file to stdout. db.SetFILE( stdout ); pcb->Format( &db, 0 ); + + setlocale( LC_NUMERIC, "" ); // revert to the current locale } #endif diff --git a/pcbnew/specctra_export.cpp b/pcbnew/specctra_export.cpp index e6658b3ec0..8a0b247f9b 100644 --- a/pcbnew/specctra_export.cpp +++ b/pcbnew/specctra_export.cpp @@ -72,6 +72,8 @@ void WinEDA_PcbFrame::ExportToSpecctra( wxCommandEvent& event ) db.SetPCB( SPECCTRA_DB::MakePCB() ); + setlocale( LC_NUMERIC, "C" ); // Switch the locale to standard C + try { db.FromBOARD( m_Pcb ); @@ -88,6 +90,8 @@ void WinEDA_PcbFrame::ExportToSpecctra( wxCommandEvent& event ) errorText = ioe.errorText; } + setlocale( LC_NUMERIC, "" ); // revert to the current locale + // The two calls below to BOARD::Change_Side_Module(), both set the // modified flag, yet their actions cancel each other out, so it should // be ok to clear the modify flag. diff --git a/pcbnew/specctra_import.cpp b/pcbnew/specctra_import.cpp index cbcc4203cb..e9579753e8 100644 --- a/pcbnew/specctra_import.cpp +++ b/pcbnew/specctra_import.cpp @@ -75,6 +75,8 @@ void WinEDA_PcbFrame::ImportSpecctraSession( wxCommandEvent& event ) SPECCTRA_DB db; + setlocale( LC_NUMERIC, "C" ); // Switch the locale to standard C + try { db.LoadSESSION( fileName ); @@ -82,9 +84,12 @@ void WinEDA_PcbFrame::ImportSpecctraSession( wxCommandEvent& event ) } catch( IOError ioe ) { + setlocale( LC_NUMERIC, "" ); // Switch the locale to standard C DisplayError( this, ioe.errorText ); return; } + + setlocale( LC_NUMERIC, "" ); // Switch the locale to standard C m_SelTrackWidthBox_Changed = TRUE; m_SelViaSizeBox_Changed = TRUE; @@ -100,21 +105,30 @@ void WinEDA_PcbFrame::ImportSpecctraSession( wxCommandEvent& event ) namespace DSN { + + +static wxPoint mapPt( const POINT& aPoint, double aResolution ) +{ + wxPoint ret; + + // the factor of 10.0 is used to convert mils to deci-mils, the units + // used within Kicad. + ret.x = (int) (10.0 * aPoint.x / aResolution); + ret.y = (int) -(10.0 * aPoint.y / aResolution); + + return ret; +} + // no UI code in this function, throw exception to report problems to the // UI handler: void WinEDA_PcbFrame::ImportSpecctraSession( wxCommandEvent& event ) void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IOError ) { - wxASSERT( session ); - - // delete all the old tracks and vias - aBoard->m_Track->DeleteStructList(); - aBoard->m_Track = NULL; - aBoard->m_NbSegmTrack = 0; - - aBoard->DeleteMARKERs(); + //wxASSERT( session ); + if( !session ) + ThrowIOError( _("Session file is missing the \"session\" section") ); if( !session->placement ) ThrowIOError( _("Session file is missing the \"placement\" section") ); @@ -125,12 +139,61 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IOError ) if( !session->route->library ) ThrowIOError( _("Session file is missing the \"library_out\" section") ); - - // Walk the PLACEMENT object's components list. + // delete all the old tracks and vias + aBoard->m_Track->DeleteStructList(); + aBoard->m_Track = NULL; + aBoard->m_NbSegmTrack = 0; + + aBoard->DeleteMARKERs(); + + // 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 i=components.begin(); i!=components.end(); ++i ) + for( COMPONENTS::iterator comp=components.begin(); comp!=components.end(); ++comp ) { - // reposition and re-orient each component and put on correct side of the board. + PLACES& places = comp->places; + for( unsigned i=0; icomponent_id.c_str() ); + MODULE* module = aBoard->FindModuleByReference( reference ); + if( !module ) + { + wxString errorMsg; + errorMsg.Printf( + _("Session file has reference to non-existing component \"%s\""), + reference.GetData() ); + ThrowIOError( errorMsg ); + } + + if( !place->hasVertex ) + continue; + + double resolution = 100; //place->GetResolution(); + + 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); + module->SetOrientation( orientation ); + + if( module->GetLayer() != CMP_N ) + aBoard->Change_Side_Module( module, 0 ); + } + else if( place->side == T_back ) + { + int orientation = (int) (-place->rotation * 10.0 - 1800); + module->SetOrientation( orientation ); + + if( module->GetLayer() != COPPER_LAYER_N ) + aBoard->Change_Side_Module( module, 0 ); + } + } } // Walk the NET_OUTs and create tracks and vias anew.