From 86f5d4e66562190e01822701dea86ac4c8691f18 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Tue, 4 Sep 2018 18:46:03 +0200 Subject: [PATCH] Eeschema: fix incorrect/incomplete annotation clearing in duplicate and paste block (happens in complex hierarchy) --- eeschema/block.cpp | 16 +++++++++++++++- eeschema/operations_on_items_lists.cpp | 14 ++++++++++++++ eeschema/sch_component.cpp | 9 +++++---- eeschema/sch_component.h | 5 ++++- eeschema/sch_screen.cpp | 9 ++------- 5 files changed, 40 insertions(+), 13 deletions(-) diff --git a/eeschema/block.cpp b/eeschema/block.cpp index ac84676903..443c3c96fa 100644 --- a/eeschema/block.cpp +++ b/eeschema/block.cpp @@ -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(); diff --git a/eeschema/operations_on_items_lists.cpp b/eeschema/operations_on_items_lists.cpp index 8564059703..586504f10a 100644 --- a/eeschema/operations_on_items_lists.cpp +++ b/eeschema/operations_on_items_lists.cpp @@ -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 ); + } } diff --git a/eeschema/sch_component.cpp b/eeschema/sch_component.cpp index e23c34a4ac..8c09d18c2c 100644 --- a/eeschema/sch_component.cpp +++ b/eeschema/sch_component.cpp @@ -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; } diff --git a/eeschema/sch_component.h b/eeschema/sch_component.h index 1a0cc53dbf..ce57fac18d 100644 --- a/eeschema/sch_component.h +++ b/eeschema/sch_component.h @@ -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. diff --git a/eeschema/sch_screen.cpp b/eeschema/sch_screen.cpp index 6e4c73c1d3..8d8146b624 100644 --- a/eeschema/sch_screen.cpp +++ b/eeschema/sch_screen.cpp @@ -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