int SCH_EDIT_FRAME::CheckAnnotate( wxArrayString* aMessageList, bool aOneSheetOnly ) { // build the screen list SCH_SHEET_LIST SheetList; SCH_REFERENCE_LIST ComponentsList; // Build the list of components if( !aOneSheetOnly ) SheetList.GetComponents( Prj().SchLibs(), ComponentsList ); else m_CurrentSheet->GetComponents( Prj().SchLibs(), ComponentsList ); return ComponentsList.CheckAnnotation( aMessageList ); }
bool SCH_EDIT_FRAME::ProcessCmpToFootprintLinkFile( wxString& aFullFilename, bool aForceFieldsVisibleAttribute, bool aFieldsVisibleAttributeState ) { // Build a flat list of components in schematic: SCH_REFERENCE_LIST referencesList; SCH_SHEET_LIST SheetList; SheetList.GetComponents( referencesList, false ); FILE* cmpFile = wxFopen( aFullFilename, wxT( "rt" ) ); if( cmpFile == NULL ) return false; // cmpFileReader dtor will close cmpFile FILE_LINE_READER cmpFileReader( cmpFile, aFullFilename ); // Now, for each component found in file, // replace footprint field value by the new value: wxString reference; wxString footprint; wxString buffer; wxString value; while( cmpFileReader.ReadLine() ) { buffer = FROM_UTF8( cmpFileReader.Line() ); if( ! buffer.StartsWith( wxT("BeginCmp") ) ) continue; // Begin component description. reference.Empty(); footprint.Empty(); while( cmpFileReader.ReadLine() ) { buffer = FROM_UTF8( cmpFileReader.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; } } // A block is read: initialize the footprint field of the correponding component // if the footprint name is not empty if( reference.IsEmpty() ) continue; // Search the component in the flat list for( unsigned ii = 0; ii < referencesList.GetCount(); ii++ ) { if( reference.CmpNoCase( referencesList[ii].GetRef() ) == 0 ) { // We have found a candidate. // Note: it can be not unique (multiple parts per package) // So we *do not* stop the search here SCH_COMPONENT* component = referencesList[ii].GetComponent(); SCH_FIELD * fpfield = component->GetField( FOOTPRINT ); fpfield->SetText( footprint ); if( aForceFieldsVisibleAttribute ) { component->GetField( FOOTPRINT ) ->SetVisible( aFieldsVisibleAttributeState ); } } } } return true; }
void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic, ANNOTATE_ORDER_T aSortOption, ANNOTATE_OPTION_T aAlgoOption, bool aResetAnnotation, bool aRepairTimestamps, bool aLockUnits ) { SCH_REFERENCE_LIST references; SCH_SCREENS screens; // Build the sheet list. SCH_SHEET_LIST sheets; // Map of locked components SCH_MULTI_UNIT_REFERENCE_MAP lockedComponents; // Test for and replace duplicate time stamps in components and sheets. Duplicate // time stamps can happen with old schematics, schematic conversions, or manual // editing of files. if( aRepairTimestamps ) { int count = screens.ReplaceDuplicateTimeStamps(); if( count ) { wxString msg; msg.Printf( _( "%d duplicate time stamps were found and replaced." ), count ); DisplayInfoMessage( NULL, msg, 2 ); } } // If units must be locked, collect all the sets that must be annotated together. if( aLockUnits ) { if( aAnnotateSchematic ) { sheets.GetMultiUnitComponents( Prj().SchLibs(), lockedComponents ); } else { m_CurrentSheet->GetMultiUnitComponents( Prj().SchLibs(), lockedComponents ); } } // If it is an annotation for all the components, reset previous annotation. if( aResetAnnotation ) DeleteAnnotation( !aAnnotateSchematic ); // Set sheet number and number of sheets. SetSheetNumberAndCount(); // Build component list if( aAnnotateSchematic ) { sheets.GetComponents( Prj().SchLibs(), references ); } else { m_CurrentSheet->GetComponents( Prj().SchLibs(), references ); } // Break full components reference in name (prefix) and number: // example: IC1 become IC, and 1 references.SplitReferences(); switch( aSortOption ) { default: case SORT_BY_X_POSITION: references.SortByXCoordinate(); break; case SORT_BY_Y_POSITION: references.SortByYCoordinate(); break; } bool useSheetNum = false; int idStep = 100; switch( aAlgoOption ) { default: case INCREMENTAL_BY_REF: break; case SHEET_NUMBER_X_100: useSheetNum = true; break; case SHEET_NUMBER_X_1000: useSheetNum = true; idStep = 1000; break; } // Recalculate and update reference numbers in schematic references.Annotate( useSheetNum, idStep, lockedComponents ); references.UpdateAnnotation(); wxArrayString errors; // Final control (just in case ... ). if( CheckAnnotate( &errors, !aAnnotateSchematic ) ) { wxString msg; for( size_t i = 0; i < errors.GetCount(); i++ ) msg += errors[i]; // wxLogWarning is a cheap and dirty way to dump a potentially long list of // strings to a dialog that can be saved to a file. This should be replaced // by a more elegant solution. wxLogWarning( msg ); } OnModify(); // Update on screen references, that can be modified by previous calculations: m_CurrentSheet->UpdateAllScreenReferences(); SetSheetNumberAndCount(); m_canvas->Refresh( true ); }
void SCH_EDIT_FRAME::backAnnotateFootprints( const std::string& aChangedSetOfReferences ) throw( IO_ERROR, boost::bad_pointer ) { // Build a flat list of components in schematic: SCH_REFERENCE_LIST refs; SCH_SHEET_LIST sheets; bool isChanged = false; sheets.GetComponents( Prj().SchLibs(), refs, false ); DSNLEXER lexer( aChangedSetOfReferences, FROM_UTF8( __func__ ) ); PTREE doc; try { Scan( &doc, &lexer ); #if defined(DEBUG) && 0 STRING_FORMATTER sf; Format( &sf, 0, 0, doc ); printf( "%s: '%s'\n", __func__, sf.GetString().c_str() ); #endif CPTREE& back_anno = doc.get_child( "back_annotation" ); wxString footprint; for( PTREE::const_iterator ref = back_anno.begin(); ref != back_anno.end(); ++ref ) { wxASSERT( ref->first == "ref" ); wxString reference = (UTF8&) ref->second.front().first; // Ensure the "fpid" node contains a footprint name, // and get it if exists if( ref->second.get_child( "fpid" ).size() ) { wxString tmp = (UTF8&) ref->second.get_child( "fpid" ).front().first; footprint = tmp; } else footprint.Empty(); // DBG( printf( "%s: ref:%s fpid:%s\n", __func__, TO_UTF8( reference ), TO_UTF8( footprint ) ); ) // Search the component in the flat list for( unsigned ii = 0; ii < refs.GetCount(); ++ii ) { if( Cmp_KEEPCASE( reference, refs[ii].GetRef() ) == 0 ) { // We have found a candidate. // Note: it can be not unique (multiple parts per package) // So we *do not* stop the search here SCH_COMPONENT* component = refs[ii].GetComp(); SCH_FIELD* fpfield = component->GetField( FOOTPRINT ); const wxString& oldfp = fpfield->GetText(); if( !oldfp && fpfield->IsVisible() ) { fpfield->SetVisible( false ); } // DBG( printf("%s: ref:%s fpid:%s\n", __func__, TO_UTF8( refs[ii].GetRef() ), TO_UTF8( footprint ) );) if( oldfp != footprint ) isChanged = true; fpfield->SetText( footprint ); } } } } catch( const PTREE_ERROR& ex ) { // remap the exception to something the caller is likely to understand. THROW_IO_ERROR( ex.what() ); } if( isChanged ) OnModify(); }