diff --git a/eeschema/files-io.cpp b/eeschema/files-io.cpp index 498785eefa..aab67d2b3c 100644 --- a/eeschema/files-io.cpp +++ b/eeschema/files-io.cpp @@ -450,6 +450,15 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, in // Restore all of the loaded symbol and sheet instances from the root sheet. sheetList.UpdateSymbolInstances( Schematic().RootScreen()->GetSymbolInstances() ); sheetList.UpdateSheetInstances( Schematic().RootScreen()->GetSheetInstances() ); + + for( SCH_SCREEN* screen = schematic.GetFirst(); screen; screen = schematic.GetNext() ) + { + if( screen->GetFileFormatVersionAtLoad() <= 20220622 ) + { + if( screen->AllSymbolDefaultInstancesNotSet() ) + screen->SetAllSymbolDefaultInstances(); + } + } } Schematic().ConnectionGraph()->Reset(); diff --git a/eeschema/sch_file_versions.h b/eeschema/sch_file_versions.h index 2c44cd77c3..2954b56586 100644 --- a/eeschema/sch_file_versions.h +++ b/eeschema/sch_file_versions.h @@ -81,4 +81,5 @@ //#define SEXPR_SCHEMATIC_FILE_VERSION 20220328 // Text box start/end -> at/size //#define SEXPR_SCHEMATIC_FILE_VERSION 20220331 // Text colors //#define SEXPR_SCHEMATIC_FILE_VERSION 20220404 // Default schematic symbol instance data. -#define SEXPR_SCHEMATIC_FILE_VERSION 20220622 // New simulation model format. +//#define SEXPR_SCHEMATIC_FILE_VERSION 20220622 // New simulation model format. +#define SEXPR_SCHEMATIC_FILE_VERSION 20220820 // Fix broken default symbol instance data. diff --git a/eeschema/sch_plugins/kicad/sch_sexpr_plugin.cpp b/eeschema/sch_plugins/kicad/sch_sexpr_plugin.cpp index 36a5e271bc..bd330a6af0 100644 --- a/eeschema/sch_plugins/kicad/sch_sexpr_plugin.cpp +++ b/eeschema/sch_plugins/kicad/sch_sexpr_plugin.cpp @@ -682,9 +682,11 @@ void SCH_SEXPR_PLUGIN::saveSymbol( SCH_SYMBOL* aSymbol, SCH_SHEET_PATH* aSheetPa m_out->Print( 0, ")" ); } - // The symbol unit is always set to the default instance regardless of the sheet instance - // to prevent file churn. - int unit = aSymbol->GetDefaultInstance().m_Unit; + // The symbol unit is always set to the first instance regardless of the current sheet + // instance to prevent file churn. + int unit = ( aSymbol->GetInstanceReferences().size() == 0 ) ? + aSymbol->GetUnit() : + aSymbol->GetInstanceReferences()[0].m_Unit; m_out->Print( 0, " (unit %d)", unit ); @@ -703,6 +705,17 @@ void SCH_SEXPR_PLUGIN::saveSymbol( SCH_SYMBOL* aSymbol, SCH_SHEET_PATH* aSheetPa m_out->Print( aNestLevel + 1, "(uuid %s)\n", TO_UTF8( aSymbol->m_Uuid.AsString() ) ); + // On the first save, if the default instance is not set, use the first instance data as + // the default. + if( aSymbol->GetDefaultInstance().m_Reference == wxEmptyString && + aSymbol->GetDefaultInstance().m_Unit == -1 && + aSymbol->GetDefaultInstance().m_Value == wxEmptyString && + aSymbol->GetDefaultInstance().m_Footprint == wxEmptyString ) + { + if( !aSymbol->GetInstanceReferences().empty() ) + aSymbol->SetDefaultInstance( aSymbol->GetInstanceReferences()[0] ); + } + m_out->Print( aNestLevel + 1, "(default_instance (reference %s) (unit %d) (value %s) (footprint %s))\n", m_out->Quotew( aSymbol->GetDefaultInstance().m_Reference ).c_str(), diff --git a/eeschema/sch_screen.cpp b/eeschema/sch_screen.cpp index 6a8e6dbda3..88d64544f2 100644 --- a/eeschema/sch_screen.cpp +++ b/eeschema/sch_screen.cpp @@ -1437,6 +1437,46 @@ void SCH_SCREEN::SetLegacySymbolInstanceData() } +bool SCH_SCREEN::AllSymbolDefaultInstancesNotSet() +{ + for( SCH_ITEM* item : Items().OfType( SCH_SYMBOL_T ) ) + { + SCH_SYMBOL* symbol = static_cast( item ); + + wxCHECK2( symbol, continue ); + + SYMBOL_INSTANCE_REFERENCE symbolDefaultReference = symbol->GetDefaultInstance(); + + const std::unique_ptr& libSymbol = symbol->GetLibSymbolRef(); + + if( !libSymbol ) + continue; + + if( symbolDefaultReference.m_Unit != 1 || + symbolDefaultReference.m_Reference != symbol->GetPrefix() || + symbolDefaultReference.m_Value != libSymbol->GetValueField().GetText() || + symbolDefaultReference.m_Footprint != libSymbol->GetFootprintField().GetText() ) + return false; + } + + return true; +} + + +void SCH_SCREEN::SetAllSymbolDefaultInstances() +{ + for( SCH_ITEM* item : Items().OfType( SCH_SYMBOL_T ) ) + { + SCH_SYMBOL* symbol = static_cast( item ); + + wxCHECK2( symbol, continue ); + + if( !symbol->GetInstanceReferences().empty() ) + symbol->SetDefaultInstance( symbol->GetInstanceReferences()[0] ); + } +} + + #if defined(DEBUG) void SCH_SCREEN::Show( int nestLevel, std::ostream& os ) const { diff --git a/eeschema/sch_screen.h b/eeschema/sch_screen.h index 1596dca3a4..d72a683bae 100644 --- a/eeschema/sch_screen.h +++ b/eeschema/sch_screen.h @@ -100,8 +100,9 @@ public: * Gets the full RTree, usually for iterating. * N.B. The iteration order of the RTree is not readily apparent and will change * if/when you add or move items and the RTree is re-balanced. Any exposure of the - * RTree contents to the user MUST be sorted before being presented. See SCH_SEXPR_PLUGIN::Format - * or SCH_EDITOR_CONTROL::nextMatch for examples. + * RTree contents to the user MUST be sorted before being presented. See + * SCH_SEXPR_PLUGIN::Format() or SCH_EDITOR_CONTROL::nextMatch() for examples. + * * @return Complete RTree of the screen's items */ EE_RTREE& Items() { return m_rtree; } @@ -503,6 +504,18 @@ public: */ void SetLegacySymbolInstanceData(); + /** + * Check all symbol default instance to see if they are not set yet. + */ + bool AllSymbolDefaultInstancesNotSet(); + + /** + * Set symbol default instances to the first instance in the instance list. + * + * @warning The schematic symbol instance data must be loaded before this method is called. + */ + void SetAllSymbolDefaultInstances(); + #if defined(DEBUG) void Show( int nestLevel, std::ostream& os ) const override; #endif diff --git a/eeschema/sch_symbol.cpp b/eeschema/sch_symbol.cpp index cefb12b754..39a8df0ad5 100644 --- a/eeschema/sch_symbol.cpp +++ b/eeschema/sch_symbol.cpp @@ -131,10 +131,7 @@ SCH_SYMBOL::SCH_SYMBOL( const LIB_SYMBOL& aSymbol, const LIB_ID& aLibId, m_prefix = UTIL::GetRefDesPrefix( m_part->GetReferenceField().GetText() ); // Set initial default symbol instance data from library symbol and initial unit. - m_defaultInstance.m_Reference = m_prefix; - m_defaultInstance.m_Unit = aUnit; - m_defaultInstance.m_Value = m_part->GetValueField().GetText(); - m_defaultInstance.m_Footprint = m_part->GetFootprintField().GetText(); + m_defaultInstance.m_Unit = -1; if( aSheet ) { @@ -224,7 +221,6 @@ void SCH_SYMBOL::Init( const VECTOR2I& pos ) } m_prefix = wxString( wxT( "U" ) ); - m_defaultInstance.m_Reference = m_prefix; m_isInNetlist = true; m_inBom = true; m_onBoard = true; @@ -240,8 +236,8 @@ EDA_ITEM* SCH_SYMBOL::Clone() const void SCH_SYMBOL::ViewGetLayers( int aLayers[], int& aCount ) const { aCount = 7; - aLayers[0] = LAYER_DANGLING; // Pins are drawn by their parent symbol, so the parent - // symbol needs to draw to LAYER_DANGLING + aLayers[0] = LAYER_DANGLING; // Pins are drawn by their parent symbol, so the parent + // symbol needs to draw to LAYER_DANGLING aLayers[1] = LAYER_DEVICE; aLayers[2] = LAYER_REFERENCEPART; aLayers[3] = LAYER_VALUEPART;