void CVPCB_MAINFRAME::SetNewPkg( const wxString& aFootprintName ) { COMPONENT* component; bool hasFootprint = false; int componentIndex; wxString description; if( m_netlist.IsEmpty() ) return; // If no component is selected, select the first one if( m_ListCmp->GetFirstSelected() < 0 ) { componentIndex = 0; m_ListCmp->SetSelection( componentIndex, true ); } // iterate over the selection while( m_ListCmp->GetFirstSelected() != -1 ) { // Get the component for the current iteration componentIndex = m_ListCmp->GetFirstSelected(); component = m_netlist.GetComponent( componentIndex ); if( component == NULL ) return; // Check to see if the component has already a footprint set. hasFootprint = !component->GetFPID().empty(); FPID fpid; if( !aFootprintName.IsEmpty() ) { wxCHECK_RET( fpid.Parse( aFootprintName ) < 0, wxString::Format( wxT( "<%s> is not a valid FPID." ), GetChars( aFootprintName ) ) ); } component->SetFPID( fpid ); // create the new component description description.Printf( CMP_FORMAT, componentIndex + 1, GetChars( component->GetReference() ), GetChars( component->GetValue() ), GetChars( FROM_UTF8( component->GetFPID().Format().c_str() ) ) ); // If the component hasn't had a footprint associated with it // it now has, so we decrement the count of components without // a footprint assigned. if( !hasFootprint ) { hasFootprint = true; m_undefinedComponentCnt -= 1; } // Set the new description and deselect the processed component m_ListCmp->SetString( componentIndex, description ); m_ListCmp->SetSelection( componentIndex, false ); } // Mark this "session" as modified m_modified = true; // select the next component, if there is one if( componentIndex < (m_ListCmp->GetCount() - 1) ) componentIndex++; m_ListCmp->SetSelection( componentIndex, true ); // update the statusbar DisplayStatus(); }
bool CMP_READER::Load( NETLIST* aNetlist ) { wxCHECK_MSG( aNetlist != NULL,true, wxT( "No netlist passed to CMP_READER::Load()" ) ); wxString reference; // Stores value read from line like Reference = BUS1; wxString timestamp; // Stores value read from line like TimeStamp = /32307DE2/AA450F67; wxString footprint; // Stores value read from line like IdModule = CP6; wxString buffer; wxString value; bool ok = true; while( m_lineReader->ReadLine() ) { buffer = FROM_UTF8( m_lineReader->Line() ); if( !buffer.StartsWith( wxT( "BeginCmp" ) ) ) continue; // Begin component description. reference.Empty(); footprint.Empty(); timestamp.Empty(); while( m_lineReader->ReadLine() ) { buffer = FROM_UTF8( m_lineReader->Line() ); if( buffer.StartsWith( wxT( "EndCmp" ) ) ) break; // store string value, stored between '=' and ';' delimiters. value = buffer.AfterFirst( '=' ); value = value.BeforeLast( ';' ); value.Trim( true ); value.Trim( false ); if( buffer.StartsWith( wxT( "Reference" ) ) ) { reference = value; continue; } if( buffer.StartsWith( wxT( "IdModule =" ) ) ) { footprint = value; continue; } if( buffer.StartsWith( wxT( "TimeStamp =" ) ) ) { timestamp = value; continue; } } // Find the corresponding item in component list: COMPONENT* component = aNetlist->GetComponentByReference( reference ); // The corresponding component could no longer existing in the netlist. This // can happen when it is removed from schematic and still exists in footprint // assignment list. This is an usual case during the life of a design. if( component ) { LIB_ID fpid; if( !footprint.IsEmpty() && fpid.Parse( footprint ) >= 0 ) { wxString error; error.Printf( _( "invalid footprint ID in\nfile: \"%s\"\nline: %d" ), GetChars( m_lineReader->GetSource() ), m_lineReader->LineNumber() ); THROW_IO_ERROR( error ); } // For checking purpose, store the existing LIB_ID (if any) in the alternate fpid copy // if this existing LIB_ID differs from the LIB_ID read from the .cmp file. // CvPcb can ask for user to chose the right LIB_ID. // It happens if the LIB_ID was modified outside CvPcb. if( fpid != component->GetFPID() && !component->GetFPID().empty() ) component->SetAltFPID( component->GetFPID() ); component->SetFPID( fpid ); } else { ok = false; // can be used to display a warning in Pcbnew. } } return ok; }
bool CVPCB_MAINFRAME::ReadNetListAndLinkFiles() { COMPONENT* component; wxString msg; bool isLegacy = true; ReadSchematicNetlist(); if( m_ListCmp == NULL ) return false; LoadProjectFile( m_NetlistFileName.GetFullPath() ); LoadFootprintFiles(); BuildFOOTPRINTS_LISTBOX(); BuildLIBRARY_LISTBOX(); m_ListCmp->Clear(); m_undefinedComponentCnt = 0; if( m_netlist.AnyFootprintsLinked() ) { for( unsigned i = 0; i < m_netlist.GetCount(); i++ ) { component = m_netlist.GetComponent( i ); if( component->GetFPID().empty() ) continue; if( isLegacy ) { if( !component->GetFPID().IsLegacy() ) isLegacy = false; } } } else { isLegacy = false; // None of the components have footprints assigned. } wxString missingLibs; // Check if footprint links were generated before the footprint library table was implemented. if( isLegacy ) { if( m_footprintLibTable->MissingLegacyLibs( m_ModuleLibNames, &missingLibs ) ) { msg = wxT( "The following legacy libraries are defined in the project file " "were not found in the footprint library table:\n\n" ) + missingLibs; msg += wxT( "\nDo you want to update the footprint library table before " "attempting to update the assigned footprints?" ); if( IsOK( this, msg ) ) { wxCommandEvent cmd; OnEditFootprintLibraryTable( cmd ); } } msg = wxT( "Some or all of the assigned footprints contain legacy entries. Would you " "like CvPcb to attempt to convert them to the new footprint library table " "format?" ); if( IsOK( this, msg ) ) { msg.Clear(); WX_STRING_REPORTER reporter( &msg ); if( !m_footprintLibTable->ConvertFromLegacy( m_netlist, m_ModuleLibNames, &reporter ) ) { HTML_MESSAGE_BOX dlg( this, wxEmptyString ); dlg.MessageSet( wxT( "The following errors occurred attempt to convert the " "footprint assignments:\n\n" ) ); dlg.ListSet( msg ); dlg.MessageSet( wxT( "\nYou will need to reassign them manually if you want them " "to be updated correctly the next time you import the " "netlist in Pcbnew." ) ); dlg.ShowModal(); } m_modified = true; } else { // Clear the legacy footprint assignments. for( unsigned i = 0; i < m_netlist.GetCount(); i++ ) { FPID emptyFPID; component = m_netlist.GetComponent( i ); component->SetFPID( emptyFPID ); m_modified = true; } } } for( unsigned i = 0; i < m_netlist.GetCount(); i++ ) { component = m_netlist.GetComponent( i ); msg.Printf( CMP_FORMAT, m_ListCmp->GetCount() + 1, GetChars( component->GetReference() ), GetChars( component->GetValue() ), GetChars( FROM_UTF8( component->GetFPID().Format().c_str() ) ) ); m_ListCmp->AppendLine( msg ); if( component->GetFPID().empty() ) { m_undefinedComponentCnt += 1; continue; } } if( !m_netlist.IsEmpty() ) m_ListCmp->SetSelection( 0, true ); DisplayStatus(); UpdateTitle(); UpdateFileHistory( m_NetlistFileName.GetFullPath() ); return true; }
/** * Function convertFromLegacy * converts the footprint names in \a aNetList from the legacy format to the #FPID format. * * @param aNetList is the #NETLIST object to convert. * @param aLibNames is the list of legacy footprint library names from the currently loaded * project. * @param aReporter is the #REPORTER object to dump messages into. * @return true if all footprint names were successfully converted to a valid FPID. */ static bool convertFromLegacy( FP_LIB_TABLE* aTbl, SEARCH_STACK& aSStack, NETLIST& aNetList, const wxArrayString& aLibNames, REPORTER* aReporter = NULL ) throw( IO_ERROR ) { wxString msg; FPID lastFPID; COMPONENT* component; MODULE* module = 0; bool retv = true; if( aNetList.IsEmpty() ) return true; aNetList.SortByFPID(); wxString libPath; PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::LEGACY ) ); for( unsigned ii = 0; ii < aNetList.GetCount(); ii++ ) { component = aNetList.GetComponent( ii ); // The footprint hasn't been assigned yet so ignore it. if( component->GetFPID().empty() ) continue; if( component->GetFPID() != lastFPID ) { module = NULL; for( unsigned ii = 0; ii < aLibNames.GetCount(); ii++ ) { wxFileName fn( wxEmptyString, aLibNames[ii], LegacyFootprintLibPathExtension ); libPath = aSStack.FindValidPath( fn.GetFullPath() ); if( !libPath ) { if( aReporter ) { msg.Printf( _( "Cannot find footprint library file '%s' in any of the " "KiCad legacy library search paths.\n" ), GetChars( fn.GetFullPath() ) ); aReporter->Report( msg ); } retv = false; continue; } module = pi->FootprintLoad( libPath, component->GetFPID().GetFootprintName() ); if( module ) { lastFPID = component->GetFPID(); break; } } } if( !module ) { if( aReporter ) { msg.Printf( _( "Component '%s' footprint '%s' was not found in any legacy " "library.\n" ), GetChars( component->GetReference() ), GetChars( component->GetFPID().Format() ) ); aReporter->Report( msg ); } // Clear the footprint assignment since the old library lookup method is no // longer valid. FPID emptyFPID; component->SetFPID( emptyFPID ); retv = false; continue; } else { wxString libNickname; const FP_LIB_TABLE::ROW* row; if( ( row = aTbl->FindRowByURI( libPath ) ) != NULL ) libNickname = row->GetNickName(); if( libNickname.IsEmpty() ) { if( aReporter ) { msg.Printf( _( "Component '%s' with footprint '%s' and legacy library path '%s' " "was not found in the footprint library table.\n" ), GetChars( component->GetReference() ), GetChars( component->GetFPID().Format() ), GetChars( libPath ) ); aReporter->Report( msg ); } retv = false; } else { FPID newFPID = lastFPID; newFPID.SetLibNickname( libNickname ); if( !newFPID.IsValid() ) { if( aReporter ) { msg.Printf( _( "Component '%s' FPID '%s' is not valid.\n" ), GetChars( component->GetReference() ), GetChars( newFPID.Format() ) ); aReporter->Report( msg ); } retv = false; } else { // The footprint name should already be set. component->SetFPID( newFPID ); } } } } return retv; }