Pcbnew: Fix a crash on exit when an item was previously deleted. Fix not working footprint exchange functions

This commit is contained in:
jean-pierre charras 2013-11-22 20:47:10 +01:00
parent 44bb2e6d4d
commit 78670eebb0
4 changed files with 201 additions and 154 deletions

View File

@ -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).

View File

@ -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 )

View File

@ -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 );

View File

@ -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 <dick@softplc.com>
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
* 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;
}