handle circular reference on delete
This commit is contained in:
committed by
Jeff Young
parent
2044e2ff43
commit
598beacaf3
@@ -186,10 +186,7 @@ public:
|
||||
{
|
||||
if( cell->GetFlags() & STRUCT_DELETED )
|
||||
{
|
||||
fprintf( stderr, "DELETE_ROW: Removing cell UUID=%s from table (commit system will delete)\n",
|
||||
cell->m_Uuid.AsString().c_str().AsChar() );
|
||||
// Don't delete here! The commit system handles deletion.
|
||||
// delete cell;
|
||||
delete cell;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -253,10 +253,14 @@ wxString SCH_TABLECELL::GetShownText( const RENDER_SETTINGS* aSettings, const SC
|
||||
SCH_TABLECELL* targetCell = table->GetCell( targetRow, targetCol );
|
||||
if( targetCell )
|
||||
{
|
||||
// Return the fully evaluated/displayed text from the target cell
|
||||
// Variables and expressions are evaluated in the target cell's context
|
||||
// (e.g., ${ROW} in the target cell refers to the target's row, not the referencing cell's row)
|
||||
// Increment aDepth to prevent infinite recursion in circular references
|
||||
// Check for excessive recursion depth (circular references)
|
||||
const int maxDepth = ADVANCED_CFG::GetCfg().m_ResolveTextRecursionDepth;
|
||||
if( aDepth >= maxDepth )
|
||||
{
|
||||
*token = wxT( "<Circular reference>" );
|
||||
return true;
|
||||
}
|
||||
|
||||
*token = targetCell->GetShownText( aSettings, aPath, aAllowExtraText, aDepth + 1 );
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1746,21 +1746,6 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
|
||||
|
||||
if( clipboardTable )
|
||||
{
|
||||
// Regenerate UUIDs for the clipboard table and all its cells to avoid duplicates
|
||||
wxLogDebug( "Regenerating UUIDs for clipboard table %s", clipboardTable->m_Uuid.AsString() );
|
||||
const_cast<KIID&>( clipboardTable->m_Uuid ) = KIID();
|
||||
wxLogDebug( " New table UUID: %s", clipboardTable->m_Uuid.AsString() );
|
||||
|
||||
clipboardTable->RunOnChildren(
|
||||
[]( SCH_ITEM* aChild )
|
||||
{
|
||||
KIID oldUuid = aChild->m_Uuid;
|
||||
const_cast<KIID&>( aChild->m_Uuid ) = KIID();
|
||||
wxLogDebug( " Cell UUID changed from %s to %s",
|
||||
oldUuid.AsString(), aChild->m_Uuid.AsString() );
|
||||
},
|
||||
RECURSE_MODE::RECURSE );
|
||||
|
||||
SCH_EDIT_TABLE_TOOL* tableEditTool = m_toolMgr->GetTool<SCH_EDIT_TABLE_TOOL>();
|
||||
|
||||
if( tableEditTool )
|
||||
@@ -1867,18 +1852,10 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
|
||||
|
||||
for( SCH_ITEM* item : tempScreen->Items() )
|
||||
{
|
||||
fprintf( stderr, "PASTE: Item from clipboard: type=%s, UUID=%s\n",
|
||||
item->GetTypeDesc().c_str().AsChar(), item->m_Uuid.AsString().c_str().AsChar() );
|
||||
|
||||
if( item->Type() == SCH_SHEET_T )
|
||||
sortedLoadedItems.push_back( item );
|
||||
else
|
||||
{
|
||||
loadedItems.push_back( item );
|
||||
|
||||
if( item->Type() == SCH_TABLE_T )
|
||||
fprintf( stderr, "PASTE: -> TABLE added to loadedItems\n" );
|
||||
}
|
||||
}
|
||||
|
||||
sort( sortedLoadedItems.begin(), sortedLoadedItems.end(),
|
||||
@@ -1921,9 +1898,6 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
|
||||
|
||||
for( EDA_ITEM* item : loadedItems )
|
||||
{
|
||||
fprintf( stderr, "PASTE: Processing loadedItem: type=%s, UUID=%s\n",
|
||||
item->GetTypeDesc().c_str().AsChar(), item->m_Uuid.AsString().c_str().AsChar() );
|
||||
|
||||
KIID_PATH clipPath( wxT( "/" ) ); // clipboard is at root
|
||||
|
||||
SCH_ITEM* schItem = static_cast<SCH_ITEM*>( item );
|
||||
@@ -1935,7 +1909,6 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
|
||||
|
||||
if( item->Type() == SCH_SYMBOL_T )
|
||||
{
|
||||
wxLogDebug( " -> Taking SYMBOL path" );
|
||||
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
|
||||
|
||||
// The library symbol gets set from the cached library symbols in the current
|
||||
@@ -2019,7 +1992,6 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
|
||||
}
|
||||
else if( item->Type() == SCH_SHEET_T )
|
||||
{
|
||||
wxLogDebug( " -> Taking SHEET path" );
|
||||
SCH_SHEET* sheet = (SCH_SHEET*) item;
|
||||
SCH_FIELD* nameField = sheet->GetField( FIELD_T::SHEET_NAME );
|
||||
wxString baseName = nameField->GetText();
|
||||
@@ -2104,28 +2076,11 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( stderr, "PASTE: -> Taking ELSE path (should be tables, labels, etc.)\n" );
|
||||
SCH_ITEM* srcItem = dynamic_cast<SCH_ITEM*>( itemMap[item->m_Uuid] );
|
||||
SCH_ITEM* destItem = dynamic_cast<SCH_ITEM*>( item );
|
||||
|
||||
// Everything gets a new KIID
|
||||
KIID oldUuid = item->m_Uuid;
|
||||
const_cast<KIID&>( item->m_Uuid ) = KIID();
|
||||
fprintf( stderr, "PASTE: Changed UUID from %s to %s for %s\n",
|
||||
oldUuid.AsString().c_str().AsChar(), item->m_Uuid.AsString().c_str().AsChar(),
|
||||
item->GetTypeDesc().c_str().AsChar() );
|
||||
|
||||
destItem->RunOnChildren(
|
||||
[]( SCH_ITEM* aChild )
|
||||
{
|
||||
KIID oldChildUuid = aChild->m_Uuid;
|
||||
const_cast<KIID&>( aChild->m_Uuid ) = KIID();
|
||||
fprintf( stderr, "PASTE: Child: Changed UUID from %s to %s for %s\n",
|
||||
oldChildUuid.AsString().c_str().AsChar(),
|
||||
aChild->m_Uuid.AsString().c_str().AsChar(),
|
||||
aChild->GetTypeDesc().c_str().AsChar() );
|
||||
},
|
||||
RECURSE_MODE::RECURSE );
|
||||
|
||||
if( srcItem && destItem )
|
||||
{
|
||||
|
||||
@@ -360,9 +360,7 @@ protected:
|
||||
}
|
||||
else
|
||||
{
|
||||
// Don't call commit.Modify(table) - we're removing individual cells
|
||||
// The table structure changes when cells are removed, which confuses the commit system
|
||||
// commit.Modify( table, getScreen() );
|
||||
commit.Modify( table, getScreen() );
|
||||
|
||||
VECTOR2I pos = table->GetPosition();
|
||||
|
||||
@@ -371,27 +369,9 @@ protected:
|
||||
for( int row = 0; row < table->GetRowCount(); ++row )
|
||||
oldRowHeights[row] = table->GetRowHeight( row );
|
||||
|
||||
fprintf( stderr, "DELETE_ROW: Before DeleteMarkedCells: rows=%d, cells=%zu\n",
|
||||
table->GetRowCount(), table->GetCells().size() );
|
||||
|
||||
// Tell commit system about each cell being removed BEFORE deleting them
|
||||
for( T_TABLECELL* cell : table->GetCells() )
|
||||
{
|
||||
if( cell->GetFlags() & STRUCT_DELETED )
|
||||
{
|
||||
fprintf( stderr, "DELETE_ROW: Calling commit.Remove() for cell UUID=%s\n",
|
||||
cell->m_Uuid.AsString().c_str().AsChar() );
|
||||
// commit.Remove() should handle removing from view
|
||||
commit.Remove( cell, this->getScreen() );
|
||||
}
|
||||
}
|
||||
|
||||
clearSelection();
|
||||
table->DeleteMarkedCells();
|
||||
|
||||
fprintf( stderr, "DELETE_ROW: After DeleteMarkedCells: rows=%d, cells=%zu\n",
|
||||
table->GetRowCount(), table->GetCells().size() );
|
||||
|
||||
for( int row = 0; row < table->GetRowCount(); ++row )
|
||||
{
|
||||
int old_row = row;
|
||||
@@ -402,29 +382,21 @@ protected:
|
||||
old_row++;
|
||||
}
|
||||
|
||||
fprintf( stderr, "DELETE_ROW: Remapping row %d -> old_row %d (rowCount=%d)\n",
|
||||
row, old_row, table->GetRowCount() );
|
||||
// Use saved old heights instead of querying the modified table
|
||||
int height = ( oldRowHeights.count( old_row ) ) ? oldRowHeights[old_row] : 0;
|
||||
table->SetRowHeight( row, height );
|
||||
}
|
||||
|
||||
fprintf( stderr, "DELETE_ROW: Before Normalize\n" );
|
||||
table->SetPosition( pos );
|
||||
table->Normalize();
|
||||
fprintf( stderr, "DELETE_ROW: After Normalize\n" );
|
||||
|
||||
fprintf( stderr, "DELETE_ROW: Before PostEvent\n" );
|
||||
getToolMgr()->PostEvent( EVENTS::SelectedEvent );
|
||||
fprintf( stderr, "DELETE_ROW: After PostEvent\n" );
|
||||
}
|
||||
|
||||
fprintf( stderr, "DELETE_ROW: Before commit.Push()\n" );
|
||||
if( deleted.size() > 1 )
|
||||
commit.Push( _( "Delete Rows" ) );
|
||||
else
|
||||
commit.Push( _( "Delete Row" ) );
|
||||
fprintf( stderr, "DELETE_ROW: After commit.Push()\n" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user