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 500abd0ac4
commit 7e8c5b9574
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() ); destFn.MakeAbsolute( Prj().GetProjectPath() );
// Make sure any sheets in the block to be pasted will not cause recursion in // 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++ ) for( i = 0; i < m_blockItems.GetCount(); i++ )
{ {
item = (SCH_ITEM*) m_blockItems.GetItem( 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->SetName( wxString::Format( wxT( "sheet%8.8lX" ), (unsigned long)timeStamp ) );
sheet->SetTimeStamp( timeStamp ); sheet->SetTimeStamp( timeStamp );
hasSheetPasted = true;
} }
} }
@ -550,6 +556,14 @@ void SCH_EDIT_FRAME::PasteListOfItems( wxDC* DC )
MoveItemsInList( picklist, GetScreen()->m_BlockLocate.GetMoveVector() ); 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. // Clear flags for all items.
GetScreen()->ClearDrawingState(); GetScreen()->ClearDrawingState();

View File

@ -239,6 +239,11 @@ void DuplicateItemsInList( SCH_SCREEN* screen, PICKED_ITEMS_LIST& aItemsList,
if( aItemsList.GetCount() == 0 ) if( aItemsList.GetCount() == 0 )
return; 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++ ) for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
{ {
newitem = DuplicateStruct( (SCH_ITEM*) aItemsList.GetPickedItem( 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->SetName( wxString::Format( wxT( "sheet%8.8lX" ), (unsigned long)timeStamp ) );
sheet->SetTimeStamp( timeStamp ); sheet->SetTimeStamp( timeStamp );
hasSheetCopied = true;
break; break;
} }
@ -285,6 +291,14 @@ void DuplicateItemsInList( SCH_SCREEN* screen, PICKED_ITEMS_LIST& aItemsList,
} }
MoveItemsInList( aItemsList, aMoveVector ); 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

@ -1111,10 +1111,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() ) // a empty sheet path is illegal:
return; wxCHECK( !aSheetPathName.IsEmpty(), false );
wxString reference_path; wxString reference_path;
@ -1129,11 +1129,12 @@ void SCH_COMPONENT::AddSheetPathReferenceEntry( const wxString& aSheetPathName )
// if aSheetPath is found, nothing to do: // if aSheetPath is found, nothing to do:
if( reference_path.Cmp( full_AR_path ) == 0 ) 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) // 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 ); AddHierarchicalReference( full_AR_path, m_Fields[REFERENCE].GetText(), m_unit );
return true;
} }

View File

@ -306,8 +306,11 @@ public:
* In component lists shared by more than one sheet path, an entry for each * In component lists shared by more than one sheet path, an entry for each
* sheet path must exist to manage references * sheet path must exist to manage references
* @param aSheetPathName is the candidate sheet path name * @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. * Change the time stamp to \a aNewTimeStamp and updates the reference path.

View File

@ -746,8 +746,7 @@ void SCH_SCREEN::EnsureAlternateReferencesExist()
// Add (when not existing) all sheet path entries // Add (when not existing) all sheet path entries
for( unsigned int ii = 0; ii < m_clientSheetPathList.GetCount(); ii++ ) for( unsigned int ii = 0; ii < m_clientSheetPathList.GetCount(); ii++ )
((SCH_COMPONENT*)item)->AddSheetPathReferenceEntry( m_clientSheetPathList[ii] ); ((SCH_COMPONENT*)item)->AddSheetPathReferenceEntryIfMissing( m_clientSheetPathList[ii] );
} }
} }
@ -1395,11 +1394,7 @@ void SCH_SCREENS::ClearAnnotationOfNewSheetPaths( SCH_SHEET_LIST& aInitialSheetP
{ {
// A new sheet path is found: clear the annotation corresponding to this new path: // A new sheet path is found: clear the annotation corresponding to this new path:
SCH_SCREEN* curr_screen = sheetpath.LastScreen(); 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, // Clear annotation and create the AR for this path, if not exists,
// when the screen is shared by sheet paths. // when the screen is shared by sheet paths.
// Otherwise ClearAnnotation do nothing, because the F1 field is used as // Otherwise ClearAnnotation do nothing, because the F1 field is used as