diff --git a/eeschema/dialogs/dialog_symbol_fields_table.cpp b/eeschema/dialogs/dialog_symbol_fields_table.cpp index 71746c9868..69adec59ae 100644 --- a/eeschema/dialogs/dialog_symbol_fields_table.cpp +++ b/eeschema/dialogs/dialog_symbol_fields_table.cpp @@ -2034,7 +2034,24 @@ void DIALOG_SYMBOL_FIELDS_TABLE::OnSchItemsAdded( SCHEMATIC& aSch, for( SCH_FIELD& field : symbol->GetFields() ) AddField( field.GetCanonicalName(), field.GetName(), true, false, true ); - m_dataModel->AddReferences( *symbol, getSymbolReferences( symbol ) ); + m_dataModel->AddReferences( getSymbolReferences( symbol ) ); + } + else if( item->Type() == SCH_SHEET_T ) + { + std::set symbols; + SCH_REFERENCE_LIST refs = getSheetSymbolReferences( *static_cast( item ) ); + + for( SCH_REFERENCE& ref : refs ) + symbols.insert( ref.GetSymbol() ); + + for( SCH_SYMBOL* symbol : symbols ) + { + // Add all fields again in case this symbol has a new one + for( SCH_FIELD& field : symbol->GetFields() ) + AddField( field.GetCanonicalName(), field.GetName(), true, false, true ); + } + + m_dataModel->AddReferences( refs ); } } @@ -2046,8 +2063,13 @@ void DIALOG_SYMBOL_FIELDS_TABLE::OnSchItemsRemoved( SCHEMATIC& aSch std::vector& aSchItem ) { for( SCH_ITEM* item : aSchItem ) + { if( item->Type() == SCH_SYMBOL_T ) m_dataModel->RemoveSymbol( *static_cast( item ) ); + else if( item->Type() == SCH_SHEET_T ) + m_dataModel->RemoveReferences( + getSheetSymbolReferences( *static_cast( item ) ) ); + } m_dataModel->RebuildRows(); } @@ -2066,7 +2088,24 @@ void DIALOG_SYMBOL_FIELDS_TABLE::OnSchItemsChanged( SCHEMATIC& aSch for( SCH_FIELD& field : symbol->GetFields() ) AddField( field.GetCanonicalName(), field.GetName(), true, false, true ); - m_dataModel->UpdateReferences( *symbol, getSymbolReferences( symbol ) ); + m_dataModel->UpdateReferences( getSymbolReferences( symbol ) ); + } + else if( item->Type() == SCH_SHEET_T ) + { + std::set symbols; + SCH_REFERENCE_LIST refs = getSheetSymbolReferences( *static_cast( item ) ); + + for( SCH_REFERENCE& ref : refs ) + symbols.insert( ref.GetSymbol() ); + + for( SCH_SYMBOL* symbol : symbols ) + { + // Add all fields again in case this symbol has a new one + for( SCH_FIELD& field : symbol->GetFields() ) + AddField( field.GetCanonicalName(), field.GetName(), true, false, true ); + } + + m_dataModel->UpdateReferences( refs ); } } @@ -2076,11 +2115,11 @@ void DIALOG_SYMBOL_FIELDS_TABLE::OnSchItemsChanged( SCHEMATIC& aSch SCH_REFERENCE_LIST DIALOG_SYMBOL_FIELDS_TABLE::getSymbolReferences( SCH_SYMBOL* aSymbol ) { - SCH_SHEET_LIST sheets = m_parent->Schematic().GetSheets(); + SCH_SHEET_LIST allSheets = m_parent->Schematic().GetSheets(); SCH_REFERENCE_LIST allRefs; SCH_REFERENCE_LIST symbolRefs; - sheets.GetSymbols( allRefs ); + allSheets.GetSymbols( allRefs ); for( size_t i = 0; i < allRefs.GetCount(); i++ ) { @@ -2095,3 +2134,39 @@ SCH_REFERENCE_LIST DIALOG_SYMBOL_FIELDS_TABLE::getSymbolReferences( SCH_SYMBOL* return symbolRefs; } + + +SCH_REFERENCE_LIST DIALOG_SYMBOL_FIELDS_TABLE::getSheetSymbolReferences( SCH_SHEET& aSheet ) +{ + SCH_SHEET_LIST allSheets = m_parent->Schematic().GetSheets(); + SCH_REFERENCE_LIST sheetRefs; + + // We need to operate on all instances of the sheet + for( const SCH_SHEET_INSTANCE& instance : aSheet.GetInstances() ) + { + // For every sheet instance we need to get the current schematic sheet + // instance that matches that particular sheet path from the root + for( SCH_SHEET_PATH& basePath : allSheets ) + { + if( basePath.Path() == instance.m_Path ) + { + SCH_SHEET_PATH sheetPath = basePath; + sheetPath.push_back( &aSheet ); + + // Create a list of all sheets in this path, starting with the path + // of the sheet that we just deleted, then all of its subsheets + SCH_SHEET_LIST subSheets; + subSheets.push_back( sheetPath ); + allSheets.GetSheetsWithinPath( subSheets, sheetPath ); + + subSheets.GetSymbolsWithinPath( sheetRefs, sheetPath, false, false ); + break; + } + } + } + + for( SCH_REFERENCE& ref : sheetRefs ) + ref.Split(); + + return sheetRefs; +} diff --git a/eeschema/dialogs/dialog_symbol_fields_table.h b/eeschema/dialogs/dialog_symbol_fields_table.h index 30174b1850..c54ccc766c 100644 --- a/eeschema/dialogs/dialog_symbol_fields_table.h +++ b/eeschema/dialogs/dialog_symbol_fields_table.h @@ -111,6 +111,7 @@ private: private: SCH_REFERENCE_LIST getSymbolReferences( SCH_SYMBOL* aSymbol ); + SCH_REFERENCE_LIST getSheetSymbolReferences( SCH_SHEET& aSheet ); void syncBomPresetSelection(); void rebuildBomPresetsWidget(); diff --git a/eeschema/fields_data_model.cpp b/eeschema/fields_data_model.cpp index dcb6be90bf..1b7b334669 100644 --- a/eeschema/fields_data_model.cpp +++ b/eeschema/fields_data_model.cpp @@ -882,22 +882,25 @@ wxString FIELDS_EDITOR_GRID_DATA_MODEL::Export( const BOM_FMT_PRESET& settings ) } -void FIELDS_EDITOR_GRID_DATA_MODEL::AddReferences( const SCH_SYMBOL& aSymbol, - const SCH_REFERENCE_LIST& aRefs ) +void FIELDS_EDITOR_GRID_DATA_MODEL::AddReferences( const SCH_REFERENCE_LIST& aRefs ) { - // Update the fields of every reference - for( const SCH_FIELD& field : aSymbol.GetFields() ) - m_dataStore[aSymbol.m_Uuid][field.GetCanonicalName()] = field.GetText(); - for( const SCH_REFERENCE& ref : aRefs ) + { if( !m_symbolsList.Contains( ref ) ) + { m_symbolsList.AddItem( ref ); + + // Update the fields of every reference + for( const SCH_FIELD& field : ref.GetSymbol()->GetFields() ) + m_dataStore[ref.GetSymbol()->m_Uuid][field.GetCanonicalName()] = field.GetText(); + } + } } void FIELDS_EDITOR_GRID_DATA_MODEL::RemoveSymbol( const SCH_SYMBOL& aSymbol ) { - // The schematic event listener passes us the item after it has been removed, + // The schematic event listener passes us the symbol after it has been removed, // so we can't just work with a SCH_REFERENCE_LIST like the other handlers as the // references are already gone. Instead we need to prune our list. m_dataStore[aSymbol.m_Uuid].clear(); @@ -912,19 +915,35 @@ void FIELDS_EDITOR_GRID_DATA_MODEL::RemoveSymbol( const SCH_SYMBOL& aSymbol ) } -void FIELDS_EDITOR_GRID_DATA_MODEL::UpdateReferences( const SCH_SYMBOL& aSymbol, - const SCH_REFERENCE_LIST& aRefs ) +void FIELDS_EDITOR_GRID_DATA_MODEL::RemoveReferences( const SCH_REFERENCE_LIST& aRefs ) { - wxCHECK_RET( m_dataStore.count( aSymbol.m_Uuid ) == 1, - "Trying to update a symbol that doesn't exist" ); - - // Update the fields of every reference. Do this by iterating through the data model - // colums; we must have all fields in the symbol added to the data model at this point, - // and some of the data model columns may be variables that are not present in the symbol - for( const DATA_MODEL_COL& col : m_cols ) - updateDataStoreSymbolField( aSymbol, col.m_fieldName ); - for( const SCH_REFERENCE& ref : aRefs ) + { + int index = m_symbolsList.FindRefByFullPath( ref.GetFullPath() ); + + if( index != -1 ) + { + m_symbolsList.RemoveItem( index ); + + // If we're out of instances then remove the symbol, too + if( ref.GetSymbol()->GetInstanceReferences().empty() ) + m_dataStore.erase( ref.GetSymbol()->m_Uuid ); + } + } +} + + +void FIELDS_EDITOR_GRID_DATA_MODEL::UpdateReferences( const SCH_REFERENCE_LIST& aRefs ) +{ + for( const SCH_REFERENCE& ref : aRefs ) + { + // Update the fields of every reference. Do this by iterating through the data model + // colums; we must have all fields in the symbol added to the data model at this point, + // and some of the data model columns may be variables that are not present in the symbol + for( const DATA_MODEL_COL& col : m_cols ) + updateDataStoreSymbolField( *ref.GetSymbol(), col.m_fieldName ); + if( !m_symbolsList.Contains( ref ) ) m_symbolsList.AddItem( ref ); + } } diff --git a/eeschema/fields_data_model.h b/eeschema/fields_data_model.h index 397ccddcb5..48101f43c7 100644 --- a/eeschema/fields_data_model.h +++ b/eeschema/fields_data_model.h @@ -210,9 +210,10 @@ public: BOM_PRESET GetBomSettings(); wxString Export( const BOM_FMT_PRESET& settings ); - void AddReferences( const SCH_SYMBOL& aSymbol, const SCH_REFERENCE_LIST& aRefs ); + void AddReferences( const SCH_REFERENCE_LIST& aRefs ); + void RemoveReferences( const SCH_REFERENCE_LIST& aRefs ); void RemoveSymbol( const SCH_SYMBOL& aSymbol ); - void UpdateReferences( const SCH_SYMBOL& aSymbol, const SCH_REFERENCE_LIST& aRefs ); + void UpdateReferences( const SCH_REFERENCE_LIST& aRefs ); private: diff --git a/eeschema/sch_symbol.h b/eeschema/sch_symbol.h index 3dcb1de69d..ead72e13ab 100644 --- a/eeschema/sch_symbol.h +++ b/eeschema/sch_symbol.h @@ -137,7 +137,7 @@ public: */ bool IsMissingLibSymbol() const; - const std::vector& GetInstanceReferences() + const std::vector& GetInstanceReferences() const { return m_instanceReferences; }