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 ); }
int TestMultiunitFootprints( SCH_SHEET_LIST& aSheetList ) { int errors = 0; std::map<wxString, LIB_ID> footprints; SCH_MULTI_UNIT_REFERENCE_MAP refMap; aSheetList.GetMultiUnitComponents( refMap, true ); for( auto& component : refMap ) { auto& refList = component.second; if( refList.GetCount() == 0 ) { wxFAIL; // it should not happen continue; } // Reference footprint wxString fp; wxString unitName; for( unsigned i = 0; i < component.second.GetCount(); ++i ) { SCH_COMPONENT* cmp = refList.GetItem( i ).GetComp(); SCH_SHEET_PATH sheetPath = refList.GetItem( i ).GetSheetPath(); fp = cmp->GetField( FOOTPRINT )->GetText(); if( !fp.IsEmpty() ) { unitName = cmp->GetRef( &sheetPath ) + LIB_PART::SubReference( cmp->GetUnit(), false ); break; } } for( unsigned i = 0; i < component.second.GetCount(); ++i ) { SCH_REFERENCE& ref = refList.GetItem( i ); SCH_COMPONENT* unit = ref.GetComp(); SCH_SHEET_PATH sheetPath = refList.GetItem( i ).GetSheetPath(); const wxString curFp = unit->GetField( FOOTPRINT )->GetText(); if( !curFp.IsEmpty() && fp != curFp ) { wxString curUnitName = unit->GetRef( &sheetPath ) + LIB_PART::SubReference( unit->GetUnit(), false ); wxString msg = wxString::Format( _( "Unit %s has '%s' assigned, " "whereas unit %s has '%s' assigned" ), unitName, fp, curUnitName, curFp ); wxPoint pos = unit->GetPosition(); SCH_MARKER* marker = new SCH_MARKER(); marker->SetTimeStamp( GetNewTimeStamp() ); marker->SetData( ERCE_DIFFERENT_UNIT_FP, pos, msg, pos ); marker->SetMarkerType( MARKER_BASE::MARKER_ERC ); marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_WARNING ); ref.GetSheetPath().LastScreen()->Append( marker ); ++errors; } } } return errors; }