7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-21 00:21:25 +00:00

Fix schematic hierarchy navigator refresh issues.

The hierarchy navigator was failing to update properly on undo/redo and
when the referenced schematic file of a sheet was changed.
This commit is contained in:
Wayne Stambaugh 2024-10-02 11:05:34 -04:00
parent c5120cc3a1
commit a871311b6f
5 changed files with 111 additions and 7 deletions

View File

@ -184,6 +184,7 @@ void SCH_COMMIT::pushSchEdit( const wxString& aMessage, int aCommitFlags )
bool itemsDeselected = false;
bool selectedModified = false;
bool dirtyConnectivity = false;
bool refreshHierarchy = false;
SCH_CLEANUP_FLAGS connectivityCleanUp = NO_CLEANUP;
if( Empty() )
@ -261,6 +262,9 @@ void SCH_COMMIT::pushSchEdit( const wxString& aMessage, int aCommitFlags )
bulkAddedItems.push_back( schItem );
if( schItem->Type() == SCH_SHEET_T )
refreshHierarchy = true;
break;
}
@ -298,6 +302,9 @@ void SCH_COMMIT::pushSchEdit( const wxString& aMessage, int aCommitFlags )
bulkRemovedItems.push_back( schItem );
if( schItem->Type() == SCH_SHEET_T )
refreshHierarchy = true;
break;
}
@ -324,6 +331,17 @@ void SCH_COMMIT::pushSchEdit( const wxString& aMessage, int aCommitFlags )
updateConnectivityFlag();
}
if( schItem->Type() == SCH_SHEET_T )
{
const SCH_SHEET* modifiedSheet = static_cast<const SCH_SHEET*>( schItem );
const SCH_SHEET* originalSheet = static_cast<const SCH_SHEET*>( itemCopy );
wxCHECK2( modifiedSheet && originalSheet, continue );
if( originalSheet->HasPageNumberChanges( *modifiedSheet ) )
refreshHierarchy = true;
}
undoList.PushItem( itemWrapper );
ent.m_copy = nullptr; // We've transferred ownership to the undo list
}
@ -364,6 +382,9 @@ void SCH_COMMIT::pushSchEdit( const wxString& aMessage, int aCommitFlags )
if( itemsChanged.size() > 0 )
schematic->OnItemsChanged( itemsChanged );
if( frame && refreshHierarchy )
frame->UpdateHierarchyNavigator();
}
if( !( aCommitFlags & SKIP_UNDO ) )

View File

@ -1532,6 +1532,59 @@ void SCH_SHEET::setPageNumber( const KIID_PATH& aPath, const wxString& aPageNumb
}
bool SCH_SHEET::HasPageNumberChanges( const SCH_SHEET& aOther ) const
{
// Avoid self comparison.
if( &aOther == this )
return false;
// A difference in the instance data count implies a page numbering change.
if( GetInstances().size() != aOther.GetInstances().size() )
return true;
std::vector<SCH_SHEET_INSTANCE> instances = GetInstances();
std::vector<SCH_SHEET_INSTANCE> otherInstances = aOther.GetInstances();
// Sorting may not be necessary but there is no guaratee that sheet
// instance data will be in the correct KIID_PATH order. We should
// probably use a std::map instead of a std::vector to store the sheet
// instance data.
std::sort( instances.begin(), instances.end(),
[]( const SCH_SHEET_INSTANCE& aLhs, const SCH_SHEET_INSTANCE& aRhs )
{
if( aLhs.m_Path > aRhs.m_Path )
return true;
return false;
} );
std::sort( otherInstances.begin(), otherInstances.end(),
[]( const SCH_SHEET_INSTANCE& aLhs, const SCH_SHEET_INSTANCE& aRhs )
{
if( aLhs.m_Path > aRhs.m_Path )
return true;
return false;
} );
auto itThis = instances.begin();
auto itOther = otherInstances.begin();
while( itThis != instances.end() )
{
if( ( itThis->m_Path == itOther->m_Path )
&& ( itThis->m_PageNumber != itOther->m_PageNumber ) )
{
return true;
}
itThis++;
itOther++;
}
return false;
}
int SCH_SHEET::ComparePageNum( const wxString& aPageNumberA, const wxString& aPageNumberB )
{
if( aPageNumberA == aPageNumberB )

View File

@ -441,6 +441,14 @@ public:
void AddInstance( const SCH_SHEET_INSTANCE& aInstance );
/**
* Check if the instance data of this sheet has any changes compared to \a aOther.
*
* @param aOther is the sheet to compare against.
* @return true if there are page number changes with \a aOther otherwise false.
*/
bool HasPageNumberChanges( const SCH_SHEET& aOther ) const;
/**
* Compares page numbers of schematic sheets.
*

View File

@ -410,7 +410,13 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
}
if( schItem )
{
updateConnectivityFlag();
AddCopyForRepeatItem( schItem );
if( schItem->Type() == SCH_SHEET_T )
rebuildHierarchyNavigator = true;
}
}
else if( schItem )
{
@ -437,7 +443,8 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
wxCHECK2( origSheet && copySheet, continue );
if( ( origSheet->GetName() != copySheet->GetName() )
|| ( origSheet->GetFileName() != copySheet->GetFileName() ) )
|| ( origSheet->GetFileName() != copySheet->GetFileName() )
|| origSheet->HasPageNumberChanges( *copySheet ) )
{
rebuildHierarchyNavigator = true;
}
@ -507,15 +514,13 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
RecalculateConnections( &localCommit, connectivityCleanUp );
// Update the hierarchy navigator when there are sheet changes.
if( connectivityCleanUp == GLOBAL_CLEANUP )
{
SetSheetNumberAndCount();
if( rebuildHierarchyNavigator )
UpdateHierarchyNavigator();
}
}
// Update the hierarchy navigator when there are sheet changes.
if( rebuildHierarchyNavigator )
UpdateHierarchyNavigator();
}

View File

@ -191,6 +191,23 @@ public:
return false;
}
bool operator>( KIID_PATH const& rhs ) const
{
if( size() != rhs.size() )
return size() > rhs.size();
for( size_t i = 0; i < size(); ++i )
{
if( at( i ) > rhs.at( i ) )
return true;
if( at( i ) != rhs.at( i ) )
return false;
}
return false;
}
KIID_PATH& operator+=( const KIID_PATH& aRhs )
{
for( const KIID& kiid : aRhs )