Symbol Fields Table: handle recursive sheet add/delete/update

This commit is contained in:
Mike Williams 2023-08-14 14:19:00 -04:00
parent 11b469f16a
commit e1d5089c74
5 changed files with 121 additions and 25 deletions

View File

@ -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<SCH_SYMBOL*> symbols;
SCH_REFERENCE_LIST refs = getSheetSymbolReferences( *static_cast<SCH_SHEET*>( 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<SCH_ITEM*>& aSchItem )
{
for( SCH_ITEM* item : aSchItem )
{
if( item->Type() == SCH_SYMBOL_T )
m_dataModel->RemoveSymbol( *static_cast<SCH_SYMBOL*>( item ) );
else if( item->Type() == SCH_SHEET_T )
m_dataModel->RemoveReferences(
getSheetSymbolReferences( *static_cast<SCH_SHEET*>( 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<SCH_SYMBOL*> symbols;
SCH_REFERENCE_LIST refs = getSheetSymbolReferences( *static_cast<SCH_SHEET*>( 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;
}

View File

@ -111,6 +111,7 @@ private:
private:
SCH_REFERENCE_LIST getSymbolReferences( SCH_SYMBOL* aSymbol );
SCH_REFERENCE_LIST getSheetSymbolReferences( SCH_SHEET& aSheet );
void syncBomPresetSelection();
void rebuildBomPresetsWidget();

View File

@ -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 );
}
}

View File

@ -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:

View File

@ -137,7 +137,7 @@ public:
*/
bool IsMissingLibSymbol() const;
const std::vector<SCH_SYMBOL_INSTANCE>& GetInstanceReferences()
const std::vector<SCH_SYMBOL_INSTANCE>& GetInstanceReferences() const
{
return m_instanceReferences;
}