Eeschema: fix incorrect/incomplete annotation clearing in duplicate and paste block (happens in complex hierarchy)

This commit is contained in:
jean-pierre charras 2018-09-04 18:46:03 +02:00
parent 181ce46b91
commit 86f5d4e665
5 changed files with 40 additions and 13 deletions

View File

@ -478,7 +478,12 @@ void SCH_EDIT_FRAME::PasteListOfItems( wxDC* DC )
destFn.MakeAbsolute( Prj().GetProjectPath() );
// Make sure any sheets in the block to be pasted will not cause recursion in
// the destination sheet.
// the destination sheet. Moreover new sheets create new sheetpaths, and component
// alternante references must be created and cleared
bool hasSheetPasted = false;
// Keep trace of existing sheet paths. Paste block can modify this list
SCH_SHEET_LIST initial_sheetpathList( g_RootSheet );
for( i = 0; i < m_blockItems.GetCount(); i++ )
{
item = (SCH_ITEM*) m_blockItems.GetItem( i );
@ -512,6 +517,7 @@ void SCH_EDIT_FRAME::PasteListOfItems( wxDC* DC )
sheet->SetName( wxString::Format( wxT( "sheet%8.8lX" ), (unsigned long)timeStamp ) );
sheet->SetTimeStamp( timeStamp );
hasSheetPasted = true;
}
}
@ -550,6 +556,14 @@ void SCH_EDIT_FRAME::PasteListOfItems( wxDC* DC )
MoveItemsInList( picklist, GetScreen()->m_BlockLocate.GetMoveVector() );
if( hasSheetPasted )
{
// We clear annotation of new sheet paths.
// Annotation of new components added in current sheet is already cleared.
SCH_SCREENS screensList( g_RootSheet );
screensList.ClearAnnotationOfNewSheetPaths( initial_sheetpathList );
}
// Clear flags for all items.
GetScreen()->ClearDrawingState();

View File

@ -239,6 +239,11 @@ void DuplicateItemsInList( SCH_SCREEN* screen, PICKED_ITEMS_LIST& aItemsList,
if( aItemsList.GetCount() == 0 )
return;
// Keep trace of existing sheet paths. Duplicate block can modify this list
bool hasSheetCopied = false;
SCH_SHEET_LIST initial_sheetpathList( g_RootSheet );
for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
{
newitem = DuplicateStruct( (SCH_ITEM*) aItemsList.GetPickedItem( ii ) );
@ -270,6 +275,7 @@ void DuplicateItemsInList( SCH_SCREEN* screen, PICKED_ITEMS_LIST& aItemsList,
sheet->SetName( wxString::Format( wxT( "sheet%8.8lX" ), (unsigned long)timeStamp ) );
sheet->SetTimeStamp( timeStamp );
hasSheetCopied = true;
break;
}
@ -285,6 +291,14 @@ void DuplicateItemsInList( SCH_SCREEN* screen, PICKED_ITEMS_LIST& aItemsList,
}
MoveItemsInList( aItemsList, aMoveVector );
if( hasSheetCopied )
{
// We clear annotation of new sheet paths.
// Annotation of new components added in current sheet is already cleared.
SCH_SCREENS screensList( g_RootSheet );
screensList.ClearAnnotationOfNewSheetPaths( initial_sheetpathList );
}
}

View File

@ -1124,10 +1124,10 @@ void SCH_COMPONENT::ClearAnnotation( SCH_SHEET_PATH* aSheetPath )
}
void SCH_COMPONENT::AddSheetPathReferenceEntry( const wxString& aSheetPathName )
bool SCH_COMPONENT::AddSheetPathReferenceEntryIfMissing( const wxString& aSheetPathName )
{
if( aSheetPathName.IsEmpty() )
return;
// a empty sheet path is illegal:
wxCHECK( !aSheetPathName.IsEmpty(), false );
wxString reference_path;
@ -1142,11 +1142,12 @@ void SCH_COMPONENT::AddSheetPathReferenceEntry( const wxString& aSheetPathName )
// if aSheetPath is found, nothing to do:
if( reference_path.Cmp( full_AR_path ) == 0 )
return;
return false;
}
// This entry does not exist: add it, with a (temporary?) reference (last ref used for display)
AddHierarchicalReference( full_AR_path, m_Fields[REFERENCE].GetText(), m_unit );
return true;
}

View File

@ -304,8 +304,11 @@ public:
* In component lists shared by more than one sheet path, an entry for each
* sheet path must exist to manage references
* @param aSheetPathName is the candidate sheet path name
* this sheet path is the sheet path of the sheet containing the component,
* not the full component sheet path
* @return false if the alternate reference was existing, true if added.
*/
void AddSheetPathReferenceEntry( const wxString& aSheetPathName );
bool AddSheetPathReferenceEntryIfMissing( const wxString& aSheetPathName );
/**
* Change the time stamp to \a aNewTimeStamp and updates the reference path.

View File

@ -734,8 +734,7 @@ void SCH_SCREEN::EnsureAlternateReferencesExist()
// Add (when not existing) all sheet path entries
for( unsigned int ii = 0; ii < m_clientSheetPathList.GetCount(); ii++ )
((SCH_COMPONENT*)item)->AddSheetPathReferenceEntry( m_clientSheetPathList[ii] );
((SCH_COMPONENT*)item)->AddSheetPathReferenceEntryIfMissing( m_clientSheetPathList[ii] );
}
}
@ -1382,11 +1381,7 @@ void SCH_SCREENS::ClearAnnotationOfNewSheetPaths( SCH_SHEET_LIST& aInitialSheetP
{
// A new sheet path is found: clear the annotation corresponding to this new path:
SCH_SCREEN* curr_screen = sheetpath.LastScreen();
#if 0 // For test and debug only
wxLogMessage(">>>new path %s <%s> screen %p usage %d",
sheetpath.Path(), sheetpath.PathHumanReadable(),
curr_screen, curr_screen->GetClientSheetPathsCount() );
#endif
// Clear annotation and create the AR for this path, if not exists,
// when the screen is shared by sheet paths.
// Otherwise ClearAnnotation do nothing, because the F1 field is used as