From 78670eebb006f30ea2a01268ea48b363d29fbf8a Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Fri, 22 Nov 2013 20:47:10 +0100 Subject: [PATCH] Pcbnew: Fix a crash on exit when an item was previously deleted. Fix not working footprint exchange functions --- include/wxBasePcbFrame.h | 10 ++ pcbnew/loadcmp.cpp | 37 ++++- pcbnew/pcbframe.cpp | 10 +- pcbnew/xchgmod.cpp | 298 +++++++++++++++++++-------------------- 4 files changed, 201 insertions(+), 154 deletions(-) diff --git a/include/wxBasePcbFrame.h b/include/wxBasePcbFrame.h index f28fe191a2..f89a4ed383 100644 --- a/include/wxBasePcbFrame.h +++ b/include/wxBasePcbFrame.h @@ -127,6 +127,16 @@ public: ~PCB_BASE_FRAME(); + /** + * Function LoadFootprint + * attempts to load \a aFootprintId from the footprint library table. + * + * @param aFootprintId is the #FPID of component footprint to load. + * @return the #MODULE if found or NULL if \a aFootprintId not found in any of the + * libraries in #m_footprintLibTable. + */ + MODULE* LoadFootprint( const FPID& aFootprintId ); + /** * Function GetBoardBoundingBox * calculates the bounding box containing all board items (or board edge segments). diff --git a/pcbnew/loadcmp.cpp b/pcbnew/loadcmp.cpp index 4400c2d7d5..a38c5aa9f9 100644 --- a/pcbnew/loadcmp.cpp +++ b/pcbnew/loadcmp.cpp @@ -336,7 +336,22 @@ MODULE* PCB_BASE_FRAME::loadFootprintFromLibrary( const wxString& aLibraryPath, { PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::LEGACY ) ); - wxString libPath = wxGetApp().FindLibraryPath( aLibraryPath ); + // Ensure the library name has the right extension + // (sometimes the name is given without ext) + wxString libname = aLibraryPath; + + if( !libname.EndsWith( wxT(".") + LegacyFootprintLibPathExtension) ) + libname << wxT(".") << LegacyFootprintLibPathExtension; + + wxString libPath = wxGetApp().FindLibraryPath( libname ); + + if( libPath.IsEmpty() ) + { + wxString msg = wxString::Format( _( "Library '%s' not found." ), + libname.GetData() ); + DisplayError( NULL, msg ); + return NULL; + } MODULE* footprint = pi->FootprintLoad( libPath, aFootprintName ); @@ -429,6 +444,26 @@ MODULE* PCB_BASE_FRAME::loadFootprintFromLibraries( return NULL; } +/* attempts to load aFootprintId from the footprint library table. + * return the #MODULE if found or NULL if not found or error. + */ +MODULE* PCB_BASE_FRAME::LoadFootprint( const FPID& aFootprintId ) +{ + MODULE* module = NULL; + + try + { + module = loadFootprint( aFootprintId ); + } + catch( IO_ERROR ioe ) + { + wxLogDebug( wxT( "An error occurred attemping to load footprint '%s'.\n\nError: %s" ), + aFootprintId.Format().c_str(), GetChars( ioe.errorText ) ); + } + + return module; +} + MODULE* PCB_BASE_FRAME::loadFootprint( const FPID& aFootprintId ) throw( IO_ERROR, PARSE_ERROR ) diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 473e0c736b..7e415cd831 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -119,14 +119,14 @@ BEGIN_EVENT_TABLE( PCB_EDIT_FRAME, PCB_BASE_FRAME ) EVT_MENU( wxID_EXIT, PCB_EDIT_FRAME::OnQuit ) // menu Config - - /* Tom's hacks start */ + + /* Tom's hacks start */ EVT_MENU ( ID_SELECTION_TOOL, PCB_EDIT_FRAME::onGenericCommand ) EVT_TOOL ( ID_SELECTION_TOOL, PCB_EDIT_FRAME::onGenericCommand ) EVT_MENU ( ID_PNS_ROUTER_TOOL, PCB_EDIT_FRAME::onGenericCommand ) EVT_TOOL ( ID_PNS_ROUTER_TOOL, PCB_EDIT_FRAME::onGenericCommand ) /* Tom's hacks end */ - + EVT_MENU( ID_PCB_DRAWINGS_WIDTHS_SETUP, PCB_EDIT_FRAME::OnConfigurePcbOptions ) EVT_MENU( ID_CONFIG_REQ, PCB_EDIT_FRAME::Process_Config ) EVT_MENU( ID_PCB_LIB_TABLE_EDIT, PCB_EDIT_FRAME::Process_Config ) @@ -598,6 +598,10 @@ void PCB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event ) SaveSettings(); + // Delete board structs and undo/redo lists, to avoid crash on exit + // when deleting some structs (mainly in undo/redo lists) too late + Clear_Pcb( false ); + // do not show the window because ScreenPcb will be deleted and we do not // want any paint event Show( false ); diff --git a/pcbnew/xchgmod.cpp b/pcbnew/xchgmod.cpp index b2cc016880..afa8218587 100644 --- a/pcbnew/xchgmod.cpp +++ b/pcbnew/xchgmod.cpp @@ -5,8 +5,10 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr - * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2013 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr + * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck + * Copyright (C) 2013 Wayne Stambaugh + * Copyright (C) 1992-2013 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -43,15 +45,15 @@ static char* quiet_gcc_4_4_3; // GCC 4.4.3 and next .. -int s_SelectionMode = 0; // Remember the last exchange option, when exit dialog. +static bool RecreateCmpFile( BOARD * aBrd, const wxString& aFullCmpFileName ); class DIALOG_EXCHANGE_MODULE : public DIALOG_EXCHANGE_MODULE_BASE { private: - - PCB_EDIT_FRAME* m_Parent; - MODULE* m_CurrentModule; + PCB_EDIT_FRAME* m_parent; + MODULE* m_currentModule; + static int m_selectionMode; // Remember the last exchange option public: DIALOG_EXCHANGE_MODULE( PCB_EDIT_FRAME* aParent, MODULE* aModule ); @@ -62,26 +64,27 @@ private: void OnOkClick( wxCommandEvent& event ); void OnQuit( wxCommandEvent& event ); void BrowseAndSelectFootprint( wxCommandEvent& event ); - void Init(); + void init(); - void Change_Current_Module(); - void Change_ModuleId( bool aUseValue ); - void Change_ModuleAll(); - int Maj_ListeCmp( const wxString& reference, const FPID& old_name, - const FPID& new_name, bool ShowError ); - bool Change_1_Module( MODULE* Module, - const FPID& new_module, + void ChangeCurrentFootprint(); + void ChangeSameFootprints( bool aUseValue ); + void ChangeAllFootprints(); + int Maj_ListeCmp( const wxString& aReference, const FPID& aOldFootprintFPID, + const FPID& aNewFootprintFPID, bool aShowError ); + bool Change_1_Module( MODULE* aModule, + const FPID& aNewFootprintFPID, PICKED_ITEMS_LIST* aUndoPickList, - bool ShowError ); + bool eShowError ); }; +int DIALOG_EXCHANGE_MODULE::m_selectionMode = 0; DIALOG_EXCHANGE_MODULE::DIALOG_EXCHANGE_MODULE( PCB_EDIT_FRAME* parent, MODULE* Module ) : DIALOG_EXCHANGE_MODULE_BASE( parent ) { - m_Parent = parent; - m_CurrentModule = Module; - Init(); + m_parent = parent; + m_currentModule = Module; + init(); GetSizer()->Fit( this ); GetSizer()->SetSizeHints( this ); } @@ -97,19 +100,19 @@ void PCB_EDIT_FRAME::InstallExchangeModuleFrame( MODULE* Module ) void DIALOG_EXCHANGE_MODULE::OnQuit( wxCommandEvent& event ) { - s_SelectionMode = m_Selection->GetSelection(); + m_selectionMode = m_Selection->GetSelection(); EndModal( 0 ); } -void DIALOG_EXCHANGE_MODULE::Init() +void DIALOG_EXCHANGE_MODULE::init() { SetFocus(); - m_OldModule->AppendText( FROM_UTF8( m_CurrentModule->GetFPID().Format().c_str() ) ); - m_NewModule->AppendText( FROM_UTF8( m_CurrentModule->GetFPID().Format().c_str() ) ); - m_OldValue->AppendText( m_CurrentModule->GetValue() ); - m_Selection->SetSelection( s_SelectionMode ); + m_OldModule->AppendText( FROM_UTF8( m_currentModule->GetFPID().Format().c_str() ) ); + m_NewModule->AppendText( FROM_UTF8( m_currentModule->GetFPID().Format().c_str() ) ); + m_OldValue->AppendText( m_currentModule->GetValue() ); + m_Selection->SetSelection( m_selectionMode ); // Enable/disable widgets: wxCommandEvent event; @@ -119,23 +122,23 @@ void DIALOG_EXCHANGE_MODULE::Init() void DIALOG_EXCHANGE_MODULE::OnOkClick( wxCommandEvent& event ) { - s_SelectionMode = m_Selection->GetSelection(); + m_selectionMode = m_Selection->GetSelection(); switch( m_Selection->GetSelection() ) { case 0: - Change_Current_Module(); + ChangeCurrentFootprint(); break; case 1: - Change_ModuleId( false ); + ChangeSameFootprints( false ); break; case 2: - Change_ModuleId( true ); + ChangeSameFootprints( true ); break; case 3: - Change_ModuleAll(); + ChangeAllFootprints(); break; } } @@ -167,10 +170,10 @@ void DIALOG_EXCHANGE_MODULE::OnSelectionClicked( wxCommandEvent& event ) * If ShowError! = 0 displays error message if the file. Cmp is not found. * Return 1 if error */ -int DIALOG_EXCHANGE_MODULE::Maj_ListeCmp( const wxString& reference, - const FPID& old_name, - const FPID& new_name, - bool ShowError ) +int DIALOG_EXCHANGE_MODULE::Maj_ListeCmp( const wxString& aReference, + const FPID& aOldFootprintFPID, + const FPID& aNewFootprintFPID, + bool aShowError ) { wxFileName fn; wxFileName tmpFileName; @@ -178,18 +181,18 @@ int DIALOG_EXCHANGE_MODULE::Maj_ListeCmp( const wxString& reference, char line[1024]; wxString msg; - if( old_name == new_name ) + if( aOldFootprintFPID == aNewFootprintFPID ) return 0; // Build CMP file name by changing the extension of NetList filename - fn = m_Parent->GetBoard()->GetFileName(); + fn = m_parent->GetBoard()->GetFileName(); fn.SetExt( ComponentFileExtension ); FichCmp = wxFopen( fn.GetFullPath(), wxT( "rt" ) ); if( FichCmp == NULL ) { - if( ShowError ) + if( aShowError ) { msg.Printf( _( "file <%s> not found" ), GetChars( fn.GetFullPath() ) ); m_WinMessages->AppendText( msg ); @@ -204,7 +207,7 @@ int DIALOG_EXCHANGE_MODULE::Maj_ListeCmp( const wxString& reference, if( NewFile == NULL ) { - if( ShowError ) + if( aShowError ) { msg.Printf( _( "Unable to create file <%s>" ), GetChars( tmpFileName.GetFullPath() ) ); @@ -228,7 +231,7 @@ int DIALOG_EXCHANGE_MODULE::Maj_ListeCmp( const wxString& reference, strcpy( buf, line + 12 ); strtok( buf, ";\n\r" ); - if( stricmp( buf, TO_UTF8( reference ) ) == 0 ) + if( stricmp( buf, TO_UTF8( aReference ) ) == 0 ) { start_descr = true; } @@ -241,7 +244,7 @@ int DIALOG_EXCHANGE_MODULE::Maj_ListeCmp( const wxString& reference, if( start_descr && strnicmp( line, "IdModule", 8 ) == 0 ) { - sprintf( line + 8, " = %s;\n", new_name.Format().c_str() ); + sprintf( line + 8, " = %s;\n", aNewFootprintFPID.Format().c_str() ); msg = wxT( " * in <" ) + fn.GetFullPath() + wxT( ">.\n" ); m_WinMessages->AppendText( msg ); @@ -260,14 +263,13 @@ int DIALOG_EXCHANGE_MODULE::Maj_ListeCmp( const wxString& reference, } -/* Change the module at the current cursor position. +/* Change the current footprint at the current cursor position. * Retains the following: - * - Same direction - * - Same position - * - Same text value and ref - * - Same NetNames for pads same name + * - position, orientation and side + * - value and ref + * - pads net names */ -void DIALOG_EXCHANGE_MODULE::Change_Current_Module() +void DIALOG_EXCHANGE_MODULE::ChangeCurrentFootprint() { wxString newmodulename = m_NewModule->GetValue(); @@ -276,31 +278,31 @@ void DIALOG_EXCHANGE_MODULE::Change_Current_Module() PICKED_ITEMS_LIST pickList; - if( Change_1_Module( m_CurrentModule, newmodulename, &pickList, true ) ) + if( Change_1_Module( m_currentModule, newmodulename, &pickList, true ) ) { - if( m_Parent->GetBoard()->IsElementVisible( RATSNEST_VISIBLE ) ) - m_Parent->Compile_Ratsnest( NULL, true ); + if( m_parent->GetBoard()->IsElementVisible( RATSNEST_VISIBLE ) ) + m_parent->Compile_Ratsnest( NULL, true ); - m_Parent->GetCanvas()->Refresh(); + m_parent->GetCanvas()->Refresh(); } if( pickList.GetCount() ) - m_Parent->SaveCopyInUndoList( pickList, UR_UNSPECIFIED ); + m_parent->SaveCopyInUndoList( pickList, UR_UNSPECIFIED ); } /* - * Change of all modules with the same name as that lib + * Change all footprints having the same fpid by a new one from lib * Retains: - * - Same direction - * - Same position - * - Same text value and ref - * - Same NetNames for pads same name - * And replacing the old module with the new module - * Note: m_CurrentModule no longer on the module reference + * - direction, position, side + * - value and ref + * - pads net names + * Note: m_currentModule is no longer the current footprint * since it has been changed! + * if aUseValue is true, footprints having the same fpid should + * also have the same value */ -void DIALOG_EXCHANGE_MODULE::Change_ModuleId( bool aUseValue ) +void DIALOG_EXCHANGE_MODULE::ChangeSameFootprints( bool aUseValue ) { wxString msg; MODULE* Module, * PtBack; @@ -311,22 +313,22 @@ void DIALOG_EXCHANGE_MODULE::Change_ModuleId( bool aUseValue ) bool check_module_value = false; int ShowErr = 3; // Post 3 error messages max. - if( m_Parent->GetBoard()->m_Modules == NULL ) + if( m_parent->GetBoard()->m_Modules == NULL ) return; if( newmodulename == wxEmptyString ) return; - lib_reference = m_CurrentModule->GetFPID(); + lib_reference = m_currentModule->GetFPID(); if( aUseValue ) { check_module_value = true; - value = m_CurrentModule->GetValue(); + value = m_currentModule->GetValue(); msg.Printf( _( "Change modules %s -> %s (for value = %s)?" ), - GetChars( FROM_UTF8( m_CurrentModule->GetFPID().Format().c_str() ) ), + GetChars( FROM_UTF8( m_currentModule->GetFPID().Format().c_str() ) ), GetChars( newmodulename ), - GetChars( m_CurrentModule->GetValue() ) ); + GetChars( m_currentModule->GetValue() ) ); } else { @@ -338,15 +340,15 @@ void DIALOG_EXCHANGE_MODULE::Change_ModuleId( bool aUseValue ) if( !IsOK( this, msg ) ) return; - /* The change is done from the last module for the routine - * Change_1_Module () modifies the last module in the list. + /* The change is done from the last module because + * Change_1_Module () modifies the last item in the list. */ PICKED_ITEMS_LIST pickList; /* note: for the first module in chain (the last here), Module->Back() * points the board or is NULL */ - Module = m_Parent->GetBoard()->m_Modules.GetLast(); + Module = m_parent->GetBoard()->m_Modules.GetLast(); for( ; Module && ( Module->Type() == PCB_MODULE_T ); Module = PtBack ) { @@ -369,32 +371,31 @@ void DIALOG_EXCHANGE_MODULE::Change_ModuleId( bool aUseValue ) if( change ) { - if( m_Parent->GetBoard()->IsElementVisible( RATSNEST_VISIBLE ) ) - m_Parent->Compile_Ratsnest( NULL, true ); + if( m_parent->GetBoard()->IsElementVisible( RATSNEST_VISIBLE ) ) + m_parent->Compile_Ratsnest( NULL, true ); - m_Parent->GetCanvas()->Refresh(); + m_parent->GetCanvas()->Refresh(); } if( pickList.GetCount() ) - m_Parent->SaveCopyInUndoList( pickList, UR_UNSPECIFIED ); + m_parent->SaveCopyInUndoList( pickList, UR_UNSPECIFIED ); } /* * Change all modules with module of the same name in library. * Maintains: - * - Same direction - * - Same position - * - Same text value and ref - * - Same NetNames for pads same name + * - direction, position, side + * - value and ref + * - pads net names */ -void DIALOG_EXCHANGE_MODULE::Change_ModuleAll() +void DIALOG_EXCHANGE_MODULE::ChangeAllFootprints() { MODULE* Module, * PtBack; bool change = false; - int ShowErr = 3; // Post 3 error messages max. + int ShowErr = 3; // Post 3 error max. - if( m_Parent->GetBoard()->m_Modules == NULL ) + if( m_parent->GetBoard()->m_Modules == NULL ) return; if( !IsOK( this, _( "Change ALL modules ?" ) ) ) @@ -408,7 +409,7 @@ void DIALOG_EXCHANGE_MODULE::Change_ModuleAll() /* note: for the first module in chain (the last here), Module->Back() * points the board or is NULL */ - Module = m_Parent->GetBoard()->m_Modules.GetLast(); + Module = m_parent->GetBoard()->m_Modules.GetLast(); for( ; Module && ( Module->Type() == PCB_MODULE_T ); Module = PtBack ) { @@ -422,72 +423,74 @@ void DIALOG_EXCHANGE_MODULE::Change_ModuleAll() if( change ) { - if( m_Parent->GetBoard()->IsElementVisible( RATSNEST_VISIBLE ) ) - m_Parent->Compile_Ratsnest( NULL, true ); + if( m_parent->GetBoard()->IsElementVisible( RATSNEST_VISIBLE ) ) + m_parent->Compile_Ratsnest( NULL, true ); - m_Parent->GetCanvas()->Refresh(); + m_parent->GetCanvas()->Refresh(); } if( pickList.GetCount() ) - m_Parent->SaveCopyInUndoList( pickList, UR_UNSPECIFIED ); + m_parent->SaveCopyInUndoList( pickList, UR_UNSPECIFIED ); } /* - * Change the number empr module with the module name new_module - * - Same direction - * - Same position - * - Same text value and ref - * - Same NetNames for pads same name - * Returns: - * False if no change (if the new module is not free) - * True if OK - * Ratsnest must be recalculated after module exchange + * Change aModule to a new, fresh one from lib + * Retains + * - direction, position, side + * - value and ref + * - pads net names + * Returns: false if no change (if the new module is not found) + * true if OK */ -bool DIALOG_EXCHANGE_MODULE::Change_1_Module( MODULE* Module, - const FPID& new_module, +bool DIALOG_EXCHANGE_MODULE::Change_1_Module( MODULE* aModule, + const FPID& aNewFootprintFPID, PICKED_ITEMS_LIST* aUndoPickList, - bool ShowError ) + bool aShowError ) { - FPID namecmp, oldnamecmp; - MODULE* NewModule; + MODULE* newModule; wxString line; - if( Module == NULL ) + if( aModule == NULL ) return false; wxBusyCursor dummy; // Copy parameters from the old module. - oldnamecmp = Module->GetFPID(); - namecmp = new_module; + FPID oldFootprintFPID = aModule->GetFPID(); // Load module. line.Printf( _( "Change module %s (from %s) " ), - GetChars( Module->GetReference() ), - oldnamecmp.Format().c_str() ); + GetChars( aModule->GetReference() ), + oldFootprintFPID.Format().c_str() ); m_WinMessages->AppendText( line ); - NewModule = m_Parent->GetModuleLibrary( FROM_UTF8( namecmp.GetLibNickname().c_str() ), - FROM_UTF8( namecmp.GetFootprintName().c_str() ), - ShowError ); + wxString moduleName = FROM_UTF8( aNewFootprintFPID.GetFootprintName().c_str() ); + wxString libName = FROM_UTF8( aNewFootprintFPID.GetLibNickname().c_str() ); - if( NewModule == NULL ) // New module not found, redraw the old one. +#if !defined( USE_FP_LIB_TABLE ) + newModule = m_parent->GetModuleLibrary( libName, moduleName, aShowError ); +#else + newModule = m_parent->LoadFootprint( aNewFootprintFPID ); +#endif + + if( newModule == NULL ) // New module not found, redraw the old one. { m_WinMessages->AppendText( wxT( "No\n" ) ); return false; } - m_Parent->GetBoard()->Add( NewModule, ADD_APPEND ); + m_parent->GetBoard()->Add( newModule, ADD_APPEND ); - if( Module == m_CurrentModule ) - m_CurrentModule = NewModule; + if( aModule == m_currentModule ) + m_currentModule = newModule; m_WinMessages->AppendText( wxT( "OK\n" ) ); - m_Parent->Exchange_Module( Module, NewModule, aUndoPickList ); + m_parent->Exchange_Module( aModule, newModule, aUndoPickList ); - Maj_ListeCmp( NewModule->GetReference(), oldnamecmp, namecmp, ShowError ); + Maj_ListeCmp( newModule->GetReference(), + oldFootprintFPID, aNewFootprintFPID, aShowError ); return true; } @@ -497,24 +500,13 @@ void PCB_EDIT_FRAME::Exchange_Module( MODULE* aOldModule, MODULE* aNewModule, PICKED_ITEMS_LIST* aUndoPickList ) { - wxPoint oldpos; - D_PAD* pad, * old_pad; - - if( ( aOldModule->Type() != PCB_MODULE_T ) || ( aNewModule->Type() != PCB_MODULE_T ) ) - { - wxMessageBox( wxT( "PCB_EDIT_FRAME::Exchange_Module() StuctType error" ) ); - return; - } - aNewModule->SetParent( GetBoard() ); - GetBoard()->m_Status_Pcb = 0; - oldpos = GetCrossHairPosition(); - SetCrossHairPosition( aOldModule->GetPosition(), false ); - /* place module without ratsnest refresh: this will be made later * when all modules are on board */ + wxPoint oldpos = GetCrossHairPosition(); + SetCrossHairPosition( aOldModule->GetPosition(), false ); PlaceModule( aNewModule, NULL, true ); SetCrossHairPosition( oldpos, false ); @@ -539,13 +531,11 @@ void PCB_EDIT_FRAME::Exchange_Module( MODULE* aOldModule, aNewModule->SetPath( aOldModule->GetPath() ); // Update pad netnames ( when possible) - pad = aNewModule->Pads(); - - for( ; pad != NULL; pad = pad->Next() ) + for( D_PAD* pad = aNewModule->Pads(); pad != NULL; pad = pad->Next() ) { pad->SetNetname( wxEmptyString ); pad->SetNet( 0 ); - old_pad = aOldModule->Pads(); + D_PAD* old_pad = aOldModule->Pads(); for( ; old_pad != NULL; old_pad = old_pad->Next() ) { @@ -583,8 +573,8 @@ void DIALOG_EXCHANGE_MODULE::BrowseAndSelectFootprint( wxCommandEvent& event ) { wxString newname; - newname = m_Parent->SelectFootprint( m_Parent, wxEmptyString, wxEmptyString, wxEmptyString, - m_Parent->GetFootprintLibraryTable() ); + newname = m_parent->SelectFootprint( m_parent, wxEmptyString, wxEmptyString, wxEmptyString, + m_parent->GetFootprintLibraryTable() ); if( newname != wxEmptyString ) m_NewModule->SetValue( newname ); @@ -594,8 +584,6 @@ void DIALOG_EXCHANGE_MODULE::BrowseAndSelectFootprint( wxCommandEvent& event ) void PCB_EDIT_FRAME::RecreateCmpFileFromBoard( wxCommandEvent& aEvent ) { wxFileName fn; - FILE* FichCmp; - char line[1024]; MODULE* Module = GetBoard()->m_Modules; wxString msg; wxString wildcard; @@ -620,33 +608,43 @@ void PCB_EDIT_FRAME::RecreateCmpFileFromBoard( wxCommandEvent& aEvent ) fn = dlg.GetPath(); - FichCmp = wxFopen( fn.GetFullPath(), wxT( "wt" ) ); - - if( FichCmp == NULL ) + if( ! RecreateCmpFile( GetBoard(), fn.GetFullPath() ) ) { msg = _( "Unable to create file " ) + fn.GetFullPath(); DisplayError( this, msg ); return; } +} - quiet_gcc_4_4_3 = fgets( line, sizeof(line), FichCmp ); - fprintf( FichCmp, "Cmp-Mod V01 Genere par PcbNew le %s\n", TO_UTF8( DateAndTime() ) ); +bool RecreateCmpFile( BOARD * aBrd, const wxString& aFullCmpFileName ) +{ + FILE* cmpFile; - for( ; Module != NULL; Module = Module->Next() ) + cmpFile = wxFopen( aFullCmpFileName, wxT( "wt" ) ); + + if( cmpFile == NULL ) + return false; + + fprintf( cmpFile, "Cmp-Mod V01 Genere par PcbNew le %s\n", TO_UTF8( DateAndTime() ) ); + + MODULE* module = aBrd->m_Modules; + for( ; module != NULL; module = module->Next() ) { - fprintf( FichCmp, "\nBeginCmp\n" ); - fprintf( FichCmp, "TimeStamp = %8.8lX\n", Module->GetTimeStamp() ); - fprintf( FichCmp, "Path = %s\n", TO_UTF8( Module->GetPath() ) ); - fprintf( FichCmp, "Reference = %s;\n", - !Module->GetReference().IsEmpty() ? - TO_UTF8( Module->GetReference() ) : "[NoRef]" ); - fprintf( FichCmp, "ValeurCmp = %s;\n", - !Module->GetValue().IsEmpty() ? - TO_UTF8( Module->GetValue() ) : "[NoVal]" ); - fprintf( FichCmp, "IdModule = %s;\n", Module->GetFPID().Format().c_str() ); - fprintf( FichCmp, "EndCmp\n" ); + fprintf( cmpFile, "\nBeginCmp\n" ); + fprintf( cmpFile, "TimeStamp = %8.8lX\n", module->GetTimeStamp() ); + fprintf( cmpFile, "Path = %s\n", TO_UTF8( module->GetPath() ) ); + fprintf( cmpFile, "Reference = %s;\n", + !module->GetReference().IsEmpty() ? + TO_UTF8( module->GetReference() ) : "[NoRef]" ); + fprintf( cmpFile, "ValeurCmp = %s;\n", + !module->GetValue().IsEmpty() ? + TO_UTF8( module->GetValue() ) : "[NoVal]" ); + fprintf( cmpFile, "IdModule = %s;\n", module->GetFPID().Format().c_str() ); + fprintf( cmpFile, "EndCmp\n" ); } - fprintf( FichCmp, "\nEndListe\n" ); - fclose( FichCmp ); + fprintf( cmpFile, "\nEndListe\n" ); + fclose( cmpFile ); + + return true; }