103
102
// Set the new description and deselect the processed component
104
m_ListCmp->SetString( componentIndex, description );
105
m_ListCmp->SetSelection( componentIndex, false );
103
m_compListBox->SetString( componentIndex, description );
104
m_compListBox->SetSelection( componentIndex, false );
108
107
// Mark this "session" as modified
109
108
m_modified = true;
111
110
// select the next component, if there is one
112
if( componentIndex < (m_ListCmp->GetCount() - 1) )
111
if( componentIndex < (m_compListBox->GetCount() - 1) )
113
112
componentIndex++;
115
m_ListCmp->SetSelection( componentIndex, true );
114
m_compListBox->SetSelection( componentIndex, true );
117
116
// update the statusbar
126
This code block was based on two major assumptions that are no longer true:
127
1) Footprint library basenames would remain the same.
128
(But no, basenames have been renamed in the github repo.)
129
2) *.mod files would still be around and merely reside in the FP_LIB_TABLE.
130
(But no, they have been converted to *.pretty.)
132
There is a newer replacement code block in the #else region.
137
* Function missingLegacyLibs
138
* tests the list of \a aLibNames by URI to determine if any of them are missing from
141
* @note The missing legacy footprint library test is performed by using old library
142
* file path lookup method. If the library is found, it is compared against all
143
* of the URIs in the table rather than the nickname. This was done because the
144
* user could change the nicknames from the default table. Using the full path
147
* @param aLibNames is the list of legacy library names.
148
* @param aErrorMsg is a pointer to a wxString object to store the URIs of any missing
149
* legacy library paths. Can be NULL.
150
* @return true if there are missing legacy libraries. Otherwise false.
152
static bool missingLegacyLibs( FP_LIB_TABLE* aTbl, SEARCH_STACK& aSStack,
153
const wxArrayString& aLibNames, wxString* aErrorMsg )
155
bool missing = false;
157
for( unsigned i = 0; i < aLibNames.GetCount(); i++ )
159
wxFileName fn( wxEmptyString, aLibNames[i], LegacyFootprintLibPathExtension );
161
wxString legacyLibPath = aSStack.FindValidPath( fn.GetFullPath() );
164
if( legacyLibPath.IsEmpty() )
168
if( !aTbl->FindRowByURI( legacyLibPath ) )
174
*aErrorMsg += wxChar( '"' );
177
*aErrorMsg += !legacyLibPath ? aLibNames[i] : legacyLibPath;
179
*aErrorMsg += wxT( "\"\n" );
189
* Function convertFromLegacy
190
* converts the footprint names in \a aNetList from the legacy format to the #FPID format.
192
* @param aNetList is the #NETLIST object to convert.
193
* @param aLibNames is the list of legacy footprint library names from the currently loaded
195
* @param aReporter is the #REPORTER object to dump messages into.
196
* @return true if all footprint names were successfully converted to a valid FPID.
198
static bool convertFromLegacy( FP_LIB_TABLE* aTbl, SEARCH_STACK& aSStack, NETLIST& aNetList,
199
const wxArrayString& aLibNames, REPORTER* aReporter = NULL ) throw( IO_ERROR )
203
COMPONENT* component;
207
if( aNetList.IsEmpty() )
210
aNetList.SortByFPID();
214
PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::LEGACY ) );
216
for( unsigned ii = 0; ii < aNetList.GetCount(); ii++ )
218
component = aNetList.GetComponent( ii );
220
// The footprint hasn't been assigned yet so ignore it.
221
if( component->GetFPID().empty() )
224
if( component->GetFPID() != lastFPID )
228
for( unsigned ii = 0; ii < aLibNames.GetCount(); ii++ )
230
wxFileName fn( wxEmptyString, aLibNames[ii], LegacyFootprintLibPathExtension );
232
libPath = aSStack.FindValidPath( fn.GetFullPath() );
238
msg.Printf( _( "Cannot find footprint library file '%s' in any of the "
239
"KiCad legacy library search paths.\n" ),
240
GetChars( fn.GetFullPath() ) );
241
aReporter->Report( msg );
248
module = pi->FootprintLoad( libPath, component->GetFPID().GetFootprintName() );
252
lastFPID = component->GetFPID();
262
msg.Printf( _( "Component '%s' footprint '%s' was not found in any legacy "
264
GetChars( component->GetReference() ),
265
GetChars( component->GetFPID().Format() ) );
266
aReporter->Report( msg );
269
// Clear the footprint assignment since the old library lookup method is no
273
component->SetFPID( emptyFPID );
279
wxString libNickname;
281
const FP_LIB_TABLE::ROW* row;
283
if( ( row = aTbl->FindRowByURI( libPath ) ) != NULL )
284
libNickname = row->GetNickName();
286
if( libNickname.IsEmpty() )
290
msg.Printf( _( "Component '%s' with footprint '%s' and legacy library path '%s' "
291
"was not found in the footprint library table.\n" ),
292
GetChars( component->GetReference() ),
293
GetChars( component->GetFPID().Format() ),
296
aReporter->Report( msg );
303
FPID newFPID = lastFPID;
304
newFPID.SetLibNickname( libNickname );
306
if( !newFPID.IsValid() )
310
msg.Printf( _( "Component '%s' FPID '%s' is not valid.\n" ),
311
GetChars( component->GetReference() ),
312
GetChars( newFPID.Format() ) );
313
aReporter->Report( msg );
320
// The footprint name should already be set.
321
component->SetFPID( newFPID );
331
bool CVPCB_MAINFRAME::ReadNetListAndLinkFiles()
333
COMPONENT* component;
335
bool isLegacy = true;
337
ReadSchematicNetlist();
339
if( m_ListCmp == NULL )
342
LoadProjectFile( m_NetlistFileName.GetFullPath() );
343
LoadFootprintFiles();
344
BuildFOOTPRINTS_LISTBOX();
345
BuildLIBRARY_LISTBOX();
348
m_undefinedComponentCnt = 0;
350
if( m_netlist.AnyFootprintsLinked() )
352
for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
354
component = m_netlist.GetComponent( i );
356
if( component->GetFPID().empty() )
361
if( !component->GetFPID().IsLegacy() )
368
isLegacy = false; // None of the components have footprints assigned.
371
wxString missingLibs;
373
// Check if footprint links were generated before the footprint library table was implemented.
376
if( missingLegacyLibs( FootprintLibs(), Prj().PcbSearchS(), m_ModuleLibNames, &missingLibs ) )
378
msg = wxT( "The following legacy libraries are defined in the project file "
379
"but were not found in the footprint library table:\n\n" ) + missingLibs;
380
msg += wxT( "\nDo you want to update the footprint library table before "
381
"attempting to update the assigned footprints?" );
383
if( IsOK( this, msg ) )
387
OnEditFootprintLibraryTable( cmd );
391
msg = wxT( "Some or all of the assigned footprints contain legacy entries. Would you "
392
"like CvPcb to attempt to convert them to the new footprint library table "
395
if( IsOK( this, msg ) )
398
WX_STRING_REPORTER reporter( &msg );
400
SEARCH_STACK& search = Prj().SchSearchS();
402
if( !convertFromLegacy( FootprintLibs(), search, m_netlist, m_ModuleLibNames, &reporter ) )
404
HTML_MESSAGE_BOX dlg( this, wxEmptyString );
406
dlg.MessageSet( wxT( "The following errors occurred attempting to convert the "
407
"footprint assignments:\n\n" ) );
409
dlg.MessageSet( wxT( "\nYou will need to reassign them manually if you want them "
410
"to be updated correctly the next time you import the "
411
"netlist in Pcbnew." ) );
419
// Clear the legacy footprint assignments.
420
for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
423
component = m_netlist.GetComponent( i );
424
component->SetFPID( emptyFPID );
430
for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
432
component = m_netlist.GetComponent( i );
434
msg.Printf( CMP_FORMAT, m_ListCmp->GetCount() + 1,
435
GetChars( component->GetReference() ),
436
GetChars( component->GetValue() ),
437
GetChars( FROM_UTF8( component->GetFPID().Format().c_str() ) ) );
439
m_ListCmp->AppendLine( msg );
441
if( component->GetFPID().empty() )
443
m_undefinedComponentCnt += 1;
448
if( !m_netlist.IsEmpty() )
449
m_ListCmp->SetSelection( 0, true );
455
UpdateFileHistory( m_NetlistFileName.GetFullPath() );
460
#else // new strategy
462
121
/// Return true if the resultant FPID has a certain nickname. The guess
463
122
/// is only made if this footprint resides in only one library.
464
123
/// @return int - 0 on success, 1 on not found, 2 on ambiguous i.e. multiple matches