Commit 78670eeb authored by jean-pierre charras's avatar jean-pierre charras

Pcbnew: Fix a crash on exit when an item was previously deleted. Fix not...

Pcbnew: Fix a crash on exit when an item was previously deleted. Fix not working footprint exchange functions
parent 44bb2e6d
...@@ -127,6 +127,16 @@ public: ...@@ -127,6 +127,16 @@ public:
~PCB_BASE_FRAME(); ~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 * Function GetBoardBoundingBox
* calculates the bounding box containing all board items (or board edge segments). * calculates the bounding box containing all board items (or board edge segments).
......
...@@ -336,7 +336,22 @@ MODULE* PCB_BASE_FRAME::loadFootprintFromLibrary( const wxString& aLibraryPath, ...@@ -336,7 +336,22 @@ MODULE* PCB_BASE_FRAME::loadFootprintFromLibrary( const wxString& aLibraryPath,
{ {
PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::LEGACY ) ); 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 ); MODULE* footprint = pi->FootprintLoad( libPath, aFootprintName );
...@@ -429,6 +444,26 @@ MODULE* PCB_BASE_FRAME::loadFootprintFromLibraries( ...@@ -429,6 +444,26 @@ MODULE* PCB_BASE_FRAME::loadFootprintFromLibraries(
return NULL; 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 ) MODULE* PCB_BASE_FRAME::loadFootprint( const FPID& aFootprintId )
throw( IO_ERROR, PARSE_ERROR ) throw( IO_ERROR, PARSE_ERROR )
......
...@@ -119,14 +119,14 @@ BEGIN_EVENT_TABLE( PCB_EDIT_FRAME, PCB_BASE_FRAME ) ...@@ -119,14 +119,14 @@ BEGIN_EVENT_TABLE( PCB_EDIT_FRAME, PCB_BASE_FRAME )
EVT_MENU( wxID_EXIT, PCB_EDIT_FRAME::OnQuit ) EVT_MENU( wxID_EXIT, PCB_EDIT_FRAME::OnQuit )
// menu Config // menu Config
/* Tom's hacks start */ /* Tom's hacks start */
EVT_MENU ( ID_SELECTION_TOOL, PCB_EDIT_FRAME::onGenericCommand ) EVT_MENU ( ID_SELECTION_TOOL, PCB_EDIT_FRAME::onGenericCommand )
EVT_TOOL ( 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_MENU ( ID_PNS_ROUTER_TOOL, PCB_EDIT_FRAME::onGenericCommand )
EVT_TOOL ( ID_PNS_ROUTER_TOOL, PCB_EDIT_FRAME::onGenericCommand ) EVT_TOOL ( ID_PNS_ROUTER_TOOL, PCB_EDIT_FRAME::onGenericCommand )
/* Tom's hacks end */ /* Tom's hacks end */
EVT_MENU( ID_PCB_DRAWINGS_WIDTHS_SETUP, PCB_EDIT_FRAME::OnConfigurePcbOptions ) EVT_MENU( ID_PCB_DRAWINGS_WIDTHS_SETUP, PCB_EDIT_FRAME::OnConfigurePcbOptions )
EVT_MENU( ID_CONFIG_REQ, PCB_EDIT_FRAME::Process_Config ) EVT_MENU( ID_CONFIG_REQ, PCB_EDIT_FRAME::Process_Config )
EVT_MENU( ID_PCB_LIB_TABLE_EDIT, 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 ) ...@@ -598,6 +598,10 @@ void PCB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event )
SaveSettings(); 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 // do not show the window because ScreenPcb will be deleted and we do not
// want any paint event // want any paint event
Show( false ); Show( false );
......
...@@ -5,8 +5,10 @@ ...@@ -5,8 +5,10 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * 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) 2013 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
* Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors. * 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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
...@@ -43,15 +45,15 @@ ...@@ -43,15 +45,15 @@
static char* quiet_gcc_4_4_3; // GCC 4.4.3 and next .. 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 class DIALOG_EXCHANGE_MODULE : public DIALOG_EXCHANGE_MODULE_BASE
{ {
private: private:
PCB_EDIT_FRAME* m_parent;
PCB_EDIT_FRAME* m_Parent; MODULE* m_currentModule;
MODULE* m_CurrentModule; static int m_selectionMode; // Remember the last exchange option
public: public:
DIALOG_EXCHANGE_MODULE( PCB_EDIT_FRAME* aParent, MODULE* aModule ); DIALOG_EXCHANGE_MODULE( PCB_EDIT_FRAME* aParent, MODULE* aModule );
...@@ -62,26 +64,27 @@ private: ...@@ -62,26 +64,27 @@ private:
void OnOkClick( wxCommandEvent& event ); void OnOkClick( wxCommandEvent& event );
void OnQuit( wxCommandEvent& event ); void OnQuit( wxCommandEvent& event );
void BrowseAndSelectFootprint( wxCommandEvent& event ); void BrowseAndSelectFootprint( wxCommandEvent& event );
void Init(); void init();
void Change_Current_Module(); void ChangeCurrentFootprint();
void Change_ModuleId( bool aUseValue ); void ChangeSameFootprints( bool aUseValue );
void Change_ModuleAll(); void ChangeAllFootprints();
int Maj_ListeCmp( const wxString& reference, const FPID& old_name, int Maj_ListeCmp( const wxString& aReference, const FPID& aOldFootprintFPID,
const FPID& new_name, bool ShowError ); const FPID& aNewFootprintFPID, bool aShowError );
bool Change_1_Module( MODULE* Module, bool Change_1_Module( MODULE* aModule,
const FPID& new_module, const FPID& aNewFootprintFPID,
PICKED_ITEMS_LIST* aUndoPickList, 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::DIALOG_EXCHANGE_MODULE( PCB_EDIT_FRAME* parent, MODULE* Module ) :
DIALOG_EXCHANGE_MODULE_BASE( parent ) DIALOG_EXCHANGE_MODULE_BASE( parent )
{ {
m_Parent = parent; m_parent = parent;
m_CurrentModule = Module; m_currentModule = Module;
Init(); init();
GetSizer()->Fit( this ); GetSizer()->Fit( this );
GetSizer()->SetSizeHints( this ); GetSizer()->SetSizeHints( this );
} }
...@@ -97,19 +100,19 @@ void PCB_EDIT_FRAME::InstallExchangeModuleFrame( MODULE* Module ) ...@@ -97,19 +100,19 @@ void PCB_EDIT_FRAME::InstallExchangeModuleFrame( MODULE* Module )
void DIALOG_EXCHANGE_MODULE::OnQuit( wxCommandEvent& event ) void DIALOG_EXCHANGE_MODULE::OnQuit( wxCommandEvent& event )
{ {
s_SelectionMode = m_Selection->GetSelection(); m_selectionMode = m_Selection->GetSelection();
EndModal( 0 ); EndModal( 0 );
} }
void DIALOG_EXCHANGE_MODULE::Init() void DIALOG_EXCHANGE_MODULE::init()
{ {
SetFocus(); SetFocus();
m_OldModule->AppendText( FROM_UTF8( m_CurrentModule->GetFPID().Format().c_str() ) ); m_OldModule->AppendText( FROM_UTF8( m_currentModule->GetFPID().Format().c_str() ) );
m_NewModule->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_OldValue->AppendText( m_currentModule->GetValue() );
m_Selection->SetSelection( s_SelectionMode ); m_Selection->SetSelection( m_selectionMode );
// Enable/disable widgets: // Enable/disable widgets:
wxCommandEvent event; wxCommandEvent event;
...@@ -119,23 +122,23 @@ void DIALOG_EXCHANGE_MODULE::Init() ...@@ -119,23 +122,23 @@ void DIALOG_EXCHANGE_MODULE::Init()
void DIALOG_EXCHANGE_MODULE::OnOkClick( wxCommandEvent& event ) void DIALOG_EXCHANGE_MODULE::OnOkClick( wxCommandEvent& event )
{ {
s_SelectionMode = m_Selection->GetSelection(); m_selectionMode = m_Selection->GetSelection();
switch( m_Selection->GetSelection() ) switch( m_Selection->GetSelection() )
{ {
case 0: case 0:
Change_Current_Module(); ChangeCurrentFootprint();
break; break;
case 1: case 1:
Change_ModuleId( false ); ChangeSameFootprints( false );
break; break;
case 2: case 2:
Change_ModuleId( true ); ChangeSameFootprints( true );
break; break;
case 3: case 3:
Change_ModuleAll(); ChangeAllFootprints();
break; break;
} }
} }
...@@ -167,10 +170,10 @@ void DIALOG_EXCHANGE_MODULE::OnSelectionClicked( wxCommandEvent& event ) ...@@ -167,10 +170,10 @@ void DIALOG_EXCHANGE_MODULE::OnSelectionClicked( wxCommandEvent& event )
* If ShowError! = 0 displays error message if the file. Cmp is not found. * If ShowError! = 0 displays error message if the file. Cmp is not found.
* Return 1 if error * Return 1 if error
*/ */
int DIALOG_EXCHANGE_MODULE::Maj_ListeCmp( const wxString& reference, int DIALOG_EXCHANGE_MODULE::Maj_ListeCmp( const wxString& aReference,
const FPID& old_name, const FPID& aOldFootprintFPID,
const FPID& new_name, const FPID& aNewFootprintFPID,
bool ShowError ) bool aShowError )
{ {
wxFileName fn; wxFileName fn;
wxFileName tmpFileName; wxFileName tmpFileName;
...@@ -178,18 +181,18 @@ int DIALOG_EXCHANGE_MODULE::Maj_ListeCmp( const wxString& reference, ...@@ -178,18 +181,18 @@ int DIALOG_EXCHANGE_MODULE::Maj_ListeCmp( const wxString& reference,
char line[1024]; char line[1024];
wxString msg; wxString msg;
if( old_name == new_name ) if( aOldFootprintFPID == aNewFootprintFPID )
return 0; return 0;
// Build CMP file name by changing the extension of NetList filename // Build CMP file name by changing the extension of NetList filename
fn = m_Parent->GetBoard()->GetFileName(); fn = m_parent->GetBoard()->GetFileName();
fn.SetExt( ComponentFileExtension ); fn.SetExt( ComponentFileExtension );
FichCmp = wxFopen( fn.GetFullPath(), wxT( "rt" ) ); FichCmp = wxFopen( fn.GetFullPath(), wxT( "rt" ) );
if( FichCmp == NULL ) if( FichCmp == NULL )
{ {
if( ShowError ) if( aShowError )
{ {
msg.Printf( _( "file <%s> not found" ), GetChars( fn.GetFullPath() ) ); msg.Printf( _( "file <%s> not found" ), GetChars( fn.GetFullPath() ) );
m_WinMessages->AppendText( msg ); m_WinMessages->AppendText( msg );
...@@ -204,7 +207,7 @@ int DIALOG_EXCHANGE_MODULE::Maj_ListeCmp( const wxString& reference, ...@@ -204,7 +207,7 @@ int DIALOG_EXCHANGE_MODULE::Maj_ListeCmp( const wxString& reference,
if( NewFile == NULL ) if( NewFile == NULL )
{ {
if( ShowError ) if( aShowError )
{ {
msg.Printf( _( "Unable to create file <%s>" ), msg.Printf( _( "Unable to create file <%s>" ),
GetChars( tmpFileName.GetFullPath() ) ); GetChars( tmpFileName.GetFullPath() ) );
...@@ -228,7 +231,7 @@ int DIALOG_EXCHANGE_MODULE::Maj_ListeCmp( const wxString& reference, ...@@ -228,7 +231,7 @@ int DIALOG_EXCHANGE_MODULE::Maj_ListeCmp( const wxString& reference,
strcpy( buf, line + 12 ); strcpy( buf, line + 12 );
strtok( buf, ";\n\r" ); strtok( buf, ";\n\r" );
if( stricmp( buf, TO_UTF8( reference ) ) == 0 ) if( stricmp( buf, TO_UTF8( aReference ) ) == 0 )
{ {
start_descr = true; start_descr = true;
} }
...@@ -241,7 +244,7 @@ int DIALOG_EXCHANGE_MODULE::Maj_ListeCmp( const wxString& reference, ...@@ -241,7 +244,7 @@ int DIALOG_EXCHANGE_MODULE::Maj_ListeCmp( const wxString& reference,
if( start_descr && strnicmp( line, "IdModule", 8 ) == 0 ) 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" ); msg = wxT( " * in <" ) + fn.GetFullPath() + wxT( ">.\n" );
m_WinMessages->AppendText( msg ); m_WinMessages->AppendText( msg );
...@@ -260,14 +263,13 @@ int DIALOG_EXCHANGE_MODULE::Maj_ListeCmp( const wxString& reference, ...@@ -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: * Retains the following:
* - Same direction * - position, orientation and side
* - Same position * - value and ref
* - Same text value and ref * - pads net names
* - Same NetNames for pads same name
*/ */
void DIALOG_EXCHANGE_MODULE::Change_Current_Module() void DIALOG_EXCHANGE_MODULE::ChangeCurrentFootprint()
{ {
wxString newmodulename = m_NewModule->GetValue(); wxString newmodulename = m_NewModule->GetValue();
...@@ -276,31 +278,31 @@ void DIALOG_EXCHANGE_MODULE::Change_Current_Module() ...@@ -276,31 +278,31 @@ void DIALOG_EXCHANGE_MODULE::Change_Current_Module()
PICKED_ITEMS_LIST pickList; 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 ) ) if( m_parent->GetBoard()->IsElementVisible( RATSNEST_VISIBLE ) )
m_Parent->Compile_Ratsnest( NULL, true ); m_parent->Compile_Ratsnest( NULL, true );
m_Parent->GetCanvas()->Refresh(); m_parent->GetCanvas()->Refresh();
} }
if( pickList.GetCount() ) 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: * Retains:
* - Same direction * - direction, position, side
* - Same position * - value and ref
* - Same text value and ref * - pads net names
* - Same NetNames for pads same name * Note: m_currentModule is no longer the current footprint
* And replacing the old module with the new module
* Note: m_CurrentModule no longer on the module reference
* since it has been changed! * 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; wxString msg;
MODULE* Module, * PtBack; MODULE* Module, * PtBack;
...@@ -311,22 +313,22 @@ void DIALOG_EXCHANGE_MODULE::Change_ModuleId( bool aUseValue ) ...@@ -311,22 +313,22 @@ void DIALOG_EXCHANGE_MODULE::Change_ModuleId( bool aUseValue )
bool check_module_value = false; bool check_module_value = false;
int ShowErr = 3; // Post 3 error messages max. int ShowErr = 3; // Post 3 error messages max.
if( m_Parent->GetBoard()->m_Modules == NULL ) if( m_parent->GetBoard()->m_Modules == NULL )
return; return;
if( newmodulename == wxEmptyString ) if( newmodulename == wxEmptyString )
return; return;
lib_reference = m_CurrentModule->GetFPID(); lib_reference = m_currentModule->GetFPID();
if( aUseValue ) if( aUseValue )
{ {
check_module_value = true; check_module_value = true;
value = m_CurrentModule->GetValue(); value = m_currentModule->GetValue();
msg.Printf( _( "Change modules %s -> %s (for value = %s)?" ), 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( newmodulename ),
GetChars( m_CurrentModule->GetValue() ) ); GetChars( m_currentModule->GetValue() ) );
} }
else else
{ {
...@@ -338,15 +340,15 @@ void DIALOG_EXCHANGE_MODULE::Change_ModuleId( bool aUseValue ) ...@@ -338,15 +340,15 @@ void DIALOG_EXCHANGE_MODULE::Change_ModuleId( bool aUseValue )
if( !IsOK( this, msg ) ) if( !IsOK( this, msg ) )
return; return;
/* The change is done from the last module for the routine /* The change is done from the last module because
* Change_1_Module () modifies the last module in the list. * Change_1_Module () modifies the last item in the list.
*/ */
PICKED_ITEMS_LIST pickList; PICKED_ITEMS_LIST pickList;
/* note: for the first module in chain (the last here), Module->Back() /* note: for the first module in chain (the last here), Module->Back()
* points the board or is NULL * 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 ) for( ; Module && ( Module->Type() == PCB_MODULE_T ); Module = PtBack )
{ {
...@@ -369,32 +371,31 @@ void DIALOG_EXCHANGE_MODULE::Change_ModuleId( bool aUseValue ) ...@@ -369,32 +371,31 @@ void DIALOG_EXCHANGE_MODULE::Change_ModuleId( bool aUseValue )
if( change ) if( change )
{ {
if( m_Parent->GetBoard()->IsElementVisible( RATSNEST_VISIBLE ) ) if( m_parent->GetBoard()->IsElementVisible( RATSNEST_VISIBLE ) )
m_Parent->Compile_Ratsnest( NULL, true ); m_parent->Compile_Ratsnest( NULL, true );
m_Parent->GetCanvas()->Refresh(); m_parent->GetCanvas()->Refresh();
} }
if( pickList.GetCount() ) 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. * Change all modules with module of the same name in library.
* Maintains: * Maintains:
* - Same direction * - direction, position, side
* - Same position * - value and ref
* - Same text value and ref * - pads net names
* - Same NetNames for pads same name
*/ */
void DIALOG_EXCHANGE_MODULE::Change_ModuleAll() void DIALOG_EXCHANGE_MODULE::ChangeAllFootprints()
{ {
MODULE* Module, * PtBack; MODULE* Module, * PtBack;
bool change = false; 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; return;
if( !IsOK( this, _( "Change ALL modules ?" ) ) ) if( !IsOK( this, _( "Change ALL modules ?" ) ) )
...@@ -408,7 +409,7 @@ void DIALOG_EXCHANGE_MODULE::Change_ModuleAll() ...@@ -408,7 +409,7 @@ void DIALOG_EXCHANGE_MODULE::Change_ModuleAll()
/* note: for the first module in chain (the last here), Module->Back() /* note: for the first module in chain (the last here), Module->Back()
* points the board or is NULL * 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 ) for( ; Module && ( Module->Type() == PCB_MODULE_T ); Module = PtBack )
{ {
...@@ -422,72 +423,74 @@ void DIALOG_EXCHANGE_MODULE::Change_ModuleAll() ...@@ -422,72 +423,74 @@ void DIALOG_EXCHANGE_MODULE::Change_ModuleAll()
if( change ) if( change )
{ {
if( m_Parent->GetBoard()->IsElementVisible( RATSNEST_VISIBLE ) ) if( m_parent->GetBoard()->IsElementVisible( RATSNEST_VISIBLE ) )
m_Parent->Compile_Ratsnest( NULL, true ); m_parent->Compile_Ratsnest( NULL, true );
m_Parent->GetCanvas()->Refresh(); m_parent->GetCanvas()->Refresh();
} }
if( pickList.GetCount() ) 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 * Change aModule to a new, fresh one from lib
* - Same direction * Retains
* - Same position * - direction, position, side
* - Same text value and ref * - value and ref
* - Same NetNames for pads same name * - pads net names
* Returns: * Returns: false if no change (if the new module is not found)
* False if no change (if the new module is not free) * true if OK
* True if OK
* Ratsnest must be recalculated after module exchange
*/ */
bool DIALOG_EXCHANGE_MODULE::Change_1_Module( MODULE* Module, bool DIALOG_EXCHANGE_MODULE::Change_1_Module( MODULE* aModule,
const FPID& new_module, const FPID& aNewFootprintFPID,
PICKED_ITEMS_LIST* aUndoPickList, PICKED_ITEMS_LIST* aUndoPickList,
bool ShowError ) bool aShowError )
{ {
FPID namecmp, oldnamecmp; MODULE* newModule;
MODULE* NewModule;
wxString line; wxString line;
if( Module == NULL ) if( aModule == NULL )
return false; return false;
wxBusyCursor dummy; wxBusyCursor dummy;
// Copy parameters from the old module. // Copy parameters from the old module.
oldnamecmp = Module->GetFPID(); FPID oldFootprintFPID = aModule->GetFPID();
namecmp = new_module;
// Load module. // Load module.
line.Printf( _( "Change module %s (from %s) " ), line.Printf( _( "Change module %s (from %s) " ),
GetChars( Module->GetReference() ), GetChars( aModule->GetReference() ),
oldnamecmp.Format().c_str() ); oldFootprintFPID.Format().c_str() );
m_WinMessages->AppendText( line ); m_WinMessages->AppendText( line );
NewModule = m_Parent->GetModuleLibrary( FROM_UTF8( namecmp.GetLibNickname().c_str() ), wxString moduleName = FROM_UTF8( aNewFootprintFPID.GetFootprintName().c_str() );
FROM_UTF8( namecmp.GetFootprintName().c_str() ), wxString libName = FROM_UTF8( aNewFootprintFPID.GetLibNickname().c_str() );
ShowError );
#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. if( newModule == NULL ) // New module not found, redraw the old one.
{ {
m_WinMessages->AppendText( wxT( "No\n" ) ); m_WinMessages->AppendText( wxT( "No\n" ) );
return false; return false;
} }
m_Parent->GetBoard()->Add( NewModule, ADD_APPEND ); m_parent->GetBoard()->Add( newModule, ADD_APPEND );
if( Module == m_CurrentModule ) if( aModule == m_currentModule )
m_CurrentModule = NewModule; m_currentModule = newModule;
m_WinMessages->AppendText( wxT( "OK\n" ) ); 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; return true;
} }
...@@ -497,24 +500,13 @@ void PCB_EDIT_FRAME::Exchange_Module( MODULE* aOldModule, ...@@ -497,24 +500,13 @@ void PCB_EDIT_FRAME::Exchange_Module( MODULE* aOldModule,
MODULE* aNewModule, MODULE* aNewModule,
PICKED_ITEMS_LIST* aUndoPickList ) 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() ); aNewModule->SetParent( GetBoard() );
GetBoard()->m_Status_Pcb = 0;
oldpos = GetCrossHairPosition();
SetCrossHairPosition( aOldModule->GetPosition(), false );
/* place module without ratsnest refresh: this will be made later /* place module without ratsnest refresh: this will be made later
* when all modules are on board * when all modules are on board
*/ */
wxPoint oldpos = GetCrossHairPosition();
SetCrossHairPosition( aOldModule->GetPosition(), false );
PlaceModule( aNewModule, NULL, true ); PlaceModule( aNewModule, NULL, true );
SetCrossHairPosition( oldpos, false ); SetCrossHairPosition( oldpos, false );
...@@ -539,13 +531,11 @@ void PCB_EDIT_FRAME::Exchange_Module( MODULE* aOldModule, ...@@ -539,13 +531,11 @@ void PCB_EDIT_FRAME::Exchange_Module( MODULE* aOldModule,
aNewModule->SetPath( aOldModule->GetPath() ); aNewModule->SetPath( aOldModule->GetPath() );
// Update pad netnames ( when possible) // Update pad netnames ( when possible)
pad = aNewModule->Pads(); for( D_PAD* pad = aNewModule->Pads(); pad != NULL; pad = pad->Next() )
for( ; pad != NULL; pad = pad->Next() )
{ {
pad->SetNetname( wxEmptyString ); pad->SetNetname( wxEmptyString );
pad->SetNet( 0 ); pad->SetNet( 0 );
old_pad = aOldModule->Pads(); D_PAD* old_pad = aOldModule->Pads();
for( ; old_pad != NULL; old_pad = old_pad->Next() ) for( ; old_pad != NULL; old_pad = old_pad->Next() )
{ {
...@@ -583,8 +573,8 @@ void DIALOG_EXCHANGE_MODULE::BrowseAndSelectFootprint( wxCommandEvent& event ) ...@@ -583,8 +573,8 @@ void DIALOG_EXCHANGE_MODULE::BrowseAndSelectFootprint( wxCommandEvent& event )
{ {
wxString newname; wxString newname;
newname = m_Parent->SelectFootprint( m_Parent, wxEmptyString, wxEmptyString, wxEmptyString, newname = m_parent->SelectFootprint( m_parent, wxEmptyString, wxEmptyString, wxEmptyString,
m_Parent->GetFootprintLibraryTable() ); m_parent->GetFootprintLibraryTable() );
if( newname != wxEmptyString ) if( newname != wxEmptyString )
m_NewModule->SetValue( newname ); m_NewModule->SetValue( newname );
...@@ -594,8 +584,6 @@ void DIALOG_EXCHANGE_MODULE::BrowseAndSelectFootprint( wxCommandEvent& event ) ...@@ -594,8 +584,6 @@ void DIALOG_EXCHANGE_MODULE::BrowseAndSelectFootprint( wxCommandEvent& event )
void PCB_EDIT_FRAME::RecreateCmpFileFromBoard( wxCommandEvent& aEvent ) void PCB_EDIT_FRAME::RecreateCmpFileFromBoard( wxCommandEvent& aEvent )
{ {
wxFileName fn; wxFileName fn;
FILE* FichCmp;
char line[1024];
MODULE* Module = GetBoard()->m_Modules; MODULE* Module = GetBoard()->m_Modules;
wxString msg; wxString msg;
wxString wildcard; wxString wildcard;
...@@ -620,33 +608,43 @@ void PCB_EDIT_FRAME::RecreateCmpFileFromBoard( wxCommandEvent& aEvent ) ...@@ -620,33 +608,43 @@ void PCB_EDIT_FRAME::RecreateCmpFileFromBoard( wxCommandEvent& aEvent )
fn = dlg.GetPath(); fn = dlg.GetPath();
FichCmp = wxFopen( fn.GetFullPath(), wxT( "wt" ) ); if( ! RecreateCmpFile( GetBoard(), fn.GetFullPath() ) )
if( FichCmp == NULL )
{ {
msg = _( "Unable to create file " ) + fn.GetFullPath(); msg = _( "Unable to create file " ) + fn.GetFullPath();
DisplayError( this, msg ); DisplayError( this, msg );
return; return;
} }
}
quiet_gcc_4_4_3 = fgets( line, sizeof(line), FichCmp ); bool RecreateCmpFile( BOARD * aBrd, const wxString& aFullCmpFileName )
fprintf( FichCmp, "Cmp-Mod V01 Genere par PcbNew le %s\n", TO_UTF8( DateAndTime() ) ); {
FILE* cmpFile;
cmpFile = wxFopen( aFullCmpFileName, wxT( "wt" ) );
for( ; Module != NULL; Module = Module->Next() ) 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( cmpFile, "\nBeginCmp\n" );
fprintf( FichCmp, "TimeStamp = %8.8lX\n", Module->GetTimeStamp() ); fprintf( cmpFile, "TimeStamp = %8.8lX\n", module->GetTimeStamp() );
fprintf( FichCmp, "Path = %s\n", TO_UTF8( Module->GetPath() ) ); fprintf( cmpFile, "Path = %s\n", TO_UTF8( module->GetPath() ) );
fprintf( FichCmp, "Reference = %s;\n", fprintf( cmpFile, "Reference = %s;\n",
!Module->GetReference().IsEmpty() ? !module->GetReference().IsEmpty() ?
TO_UTF8( Module->GetReference() ) : "[NoRef]" ); TO_UTF8( module->GetReference() ) : "[NoRef]" );
fprintf( FichCmp, "ValeurCmp = %s;\n", fprintf( cmpFile, "ValeurCmp = %s;\n",
!Module->GetValue().IsEmpty() ? !module->GetValue().IsEmpty() ?
TO_UTF8( Module->GetValue() ) : "[NoVal]" ); TO_UTF8( module->GetValue() ) : "[NoVal]" );
fprintf( FichCmp, "IdModule = %s;\n", Module->GetFPID().Format().c_str() ); fprintf( cmpFile, "IdModule = %s;\n", module->GetFPID().Format().c_str() );
fprintf( FichCmp, "EndCmp\n" ); fprintf( cmpFile, "EndCmp\n" );
} }
fprintf( FichCmp, "\nEndListe\n" ); fprintf( cmpFile, "\nEndListe\n" );
fclose( FichCmp ); fclose( cmpFile );
return true;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment