diff --git a/eeschema/annotate.cpp b/eeschema/annotate.cpp index a792221a6a..7aa40c244f 100644 --- a/eeschema/annotate.cpp +++ b/eeschema/annotate.cpp @@ -60,7 +60,8 @@ void SCH_EDIT_FRAME::mapExistingAnnotation( std::map& aMap ) } -void SCH_EDIT_FRAME::DeleteAnnotation( ANNOTATE_SCOPE_T aAnnotateScope, bool* aAppendUndo ) +void SCH_EDIT_FRAME::DeleteAnnotation( ANNOTATE_SCOPE_T aAnnotateScope, bool aRecursive, + bool* aAppendUndo ) { auto clearSymbolAnnotation = [&]( EDA_ITEM* aItem, SCH_SCREEN* aScreen, SCH_SHEET_PATH* aSheet, bool aResetPrefixes ) @@ -79,14 +80,15 @@ void SCH_EDIT_FRAME::DeleteAnnotation( ANNOTATE_SCOPE_T aAnnotateScope, bool* aA clearSymbolAnnotation( item, aScreen, aSheet, aResetPrefixes ); }; - SCH_SCREEN* screen = GetScreen(); + SCH_SHEET_LIST sheets = Schematic().GetSheets(); + SCH_SCREEN* screen = GetScreen(); SCH_SHEET_PATH currentSheet = GetCurrentSheet(); switch( aAnnotateScope ) { case ANNOTATE_ALL: { - for( const SCH_SHEET_PATH& sheet : Schematic().GetSheets() ) + for( const SCH_SHEET_PATH& sheet : sheets ) clearSheetAnnotation( sheet.LastScreen(), nullptr, false ); break; @@ -94,6 +96,26 @@ void SCH_EDIT_FRAME::DeleteAnnotation( ANNOTATE_SCOPE_T aAnnotateScope, bool* aA case ANNOTATE_CURRENT_SHEET: { clearSheetAnnotation( screen, ¤tSheet, false ); + + if( aRecursive ) + { + SCH_SHEET_LIST subSheets; + + std::vector tempSubSheets; + currentSheet.LastScreen()->GetSheets( &tempSubSheets ); + + for( SCH_ITEM* item : tempSubSheets ) + { + SCH_SHEET_PATH subSheetPath = currentSheet; + subSheetPath.push_back( static_cast( item ) ); + + sheets.GetSheetsWithinPath( subSheets, subSheetPath ); + } + + for( SCH_SHEET_PATH sheet : subSheets ) + clearSheetAnnotation( sheet.LastScreen(), &sheet, false ); + } + break; } @@ -101,12 +123,25 @@ void SCH_EDIT_FRAME::DeleteAnnotation( ANNOTATE_SCOPE_T aAnnotateScope, bool* aA { EE_SELECTION_TOOL* selTool = m_toolManager->GetTool(); EE_SELECTION& selection = selTool->RequestSelection(); + SCH_SHEET_LIST selectedSheets; for( EDA_ITEM* item : selection.Items() ) { if( item->Type() == SCH_SYMBOL_T ) clearSymbolAnnotation( item, screen, ¤tSheet, false ); + + if( item->Type() == SCH_SHEET_T && aRecursive ) + { + SCH_SHEET_PATH subSheetPath = currentSheet; + subSheetPath.push_back( static_cast( item ) ); + + sheets.GetSheetsWithinPath( selectedSheets, subSheetPath ); + } } + + for( SCH_SHEET_PATH sheet : selectedSheets ) + clearSheetAnnotation( sheet.LastScreen(), &sheet, false ); + break; } } @@ -131,6 +166,7 @@ void SCH_EDIT_FRAME::DeleteAnnotation( ANNOTATE_SCOPE_T aAnnotateScope, bool* aA void SCH_EDIT_FRAME::AnnotateSymbols( ANNOTATE_SCOPE_T aAnnotateScope, ANNOTATE_ORDER_T aSortOption, ANNOTATE_ALGO_T aAlgoOption, + bool aRecursive, int aStartNumber, bool aResetAnnotation, bool aRepairTimestamps, @@ -145,6 +181,36 @@ void SCH_EDIT_FRAME::AnnotateSymbols( ANNOTATE_SCOPE_T aAnnotateScope, SCH_SHEET_LIST sheets = Schematic().GetSheets(); SCH_SHEET_PATH currentSheet = GetCurrentSheet(); + + // Store the selected sheets relative to the full hierarchy so we + // get the correct sheet numbers + SCH_SHEET_LIST selectedSheets; + for( EDA_ITEM* item : selection ) + if( item->Type() == SCH_SHEET_T ) + { + SCH_SHEET_PATH subSheetPath = currentSheet; + subSheetPath.push_back( static_cast( item ) ); + + sheets.GetSheetsWithinPath( selectedSheets, subSheetPath ); + } + + + // Like above, store subsheets relative to full hierarchy for + // recursive annotation from current sheet + SCH_SHEET_LIST subSheets; + + std::vector tempSubSheets; + currentSheet.LastScreen()->GetSheets( &tempSubSheets ); + + for( SCH_ITEM* item : tempSubSheets ) + { + SCH_SHEET_PATH subSheetPath = currentSheet; + subSheetPath.push_back( static_cast( item ) ); + + sheets.GetSheetsWithinPath( subSheets, subSheetPath ); + } + + // Map of locked symbols SCH_MULTI_UNIT_REFERENCE_MAP lockedSymbols; @@ -197,10 +263,18 @@ void SCH_EDIT_FRAME::AnnotateSymbols( ANNOTATE_SCOPE_T aAnnotateScope, case ANNOTATE_CURRENT_SHEET: GetCurrentSheet().GetSymbols( references ); + + if( aRecursive ) + subSheets.GetSymbolsWithinPath( references, currentSheet, true, true ); + break; case ANNOTATE_SELECTION: selection.GetSymbols( references, currentSheet ); + + if( aRecursive ) + selectedSheets.GetSymbolsWithinPath( references, currentSheet, true, true ); + break; } @@ -328,7 +402,7 @@ void SCH_EDIT_FRAME::AnnotateSymbols( ANNOTATE_SCOPE_T aAnnotateScope, { aReporter.Report( aMsg, RPT_SEVERITY_ERROR ); }, - aAnnotateScope ) ) + aAnnotateScope, aRecursive ) ) { aReporter.ReportTail( _( "Annotation complete." ), RPT_SEVERITY_ACTION ); } @@ -352,10 +426,13 @@ void SCH_EDIT_FRAME::AnnotateSymbols( ANNOTATE_SCOPE_T aAnnotateScope, int SCH_EDIT_FRAME::CheckAnnotate( ANNOTATION_ERROR_HANDLER aErrorHandler, - ANNOTATE_SCOPE_T aAnnotateScope ) + ANNOTATE_SCOPE_T aAnnotateScope, + bool aRecursive ) { SCH_REFERENCE_LIST referenceList; constexpr bool includePowerSymbols = false; + SCH_SHEET_LIST sheets = Schematic().GetSheets(); + SCH_SHEET_PATH currentSheet = GetCurrentSheet(); // Build the list of symbols switch( aAnnotateScope ) @@ -366,12 +443,53 @@ int SCH_EDIT_FRAME::CheckAnnotate( ANNOTATION_ERROR_HANDLER aErrorHandler, case ANNOTATE_CURRENT_SHEET: GetCurrentSheet().GetSymbols( referenceList, includePowerSymbols ); + + if( aRecursive ) + { + SCH_SHEET_LIST subSheets; + + std::vector tempSubSheets; + currentSheet.LastScreen()->GetSheets( &tempSubSheets ); + + for( SCH_ITEM* item : tempSubSheets ) + { + SCH_SHEET_PATH subSheetPath = currentSheet; + subSheetPath.push_back( static_cast( item ) ); + + sheets.GetSheetsWithinPath( subSheets, subSheetPath ); + } + + for( SCH_SHEET_PATH sheet : subSheets ) + sheet.GetSymbols( referenceList, includePowerSymbols ); + } + break; case ANNOTATE_SELECTION: EE_SELECTION_TOOL* selTool = m_toolManager->GetTool(); EE_SELECTION& selection = selTool->RequestSelection(); selection.GetSymbols( referenceList, GetCurrentSheet(), includePowerSymbols ); + + if( aRecursive ) + { + SCH_SHEET_LIST selectedSheets; + + for( EDA_ITEM* item : selection.Items() ) + { + if( item->Type() == SCH_SHEET_T ) + { + SCH_SHEET_PATH subSheetPath = currentSheet; + subSheetPath.push_back( static_cast( item ) ); + + sheets.GetSheetsWithinPath( selectedSheets, subSheetPath ); + } + } + + for( SCH_SHEET_PATH sheet : selectedSheets ) + sheet.GetSymbols( referenceList, includePowerSymbols ); + } + + break; } diff --git a/eeschema/dialogs/dialog_annotate.cpp b/eeschema/dialogs/dialog_annotate.cpp index 87a77619ce..1045b94044 100644 --- a/eeschema/dialogs/dialog_annotate.cpp +++ b/eeschema/dialogs/dialog_annotate.cpp @@ -59,6 +59,8 @@ private: ANNOTATE_SCOPE_T GetScope(); + bool GetRecursive(); + ANNOTATE_ORDER_T GetSortOrder(); ANNOTATE_ALGO_T GetAnnotateAlgo(); @@ -109,7 +111,7 @@ DIALOG_ANNOTATE::~DIALOG_ANNOTATE() if( m_rbScope_Schematic->IsEnabled() ) { cfg->m_AnnotatePanel.scope = GetScope(); - cfg->m_AnnotatePanel.recursive = m_checkRecursive->GetValue(); + cfg->m_AnnotatePanel.recursive = GetRecursive(); } cfg->m_AnnotatePanel.messages_filter = m_MessageWindow->GetVisibleSeverities(); @@ -216,7 +218,7 @@ void DIALOG_ANNOTATE::OnApplyClick( wxCommandEvent& event ) REPORTER& reporter = m_MessageWindow->Reporter(); m_MessageWindow->SetLazyUpdate( true ); // Don't update after each message - m_Parent->AnnotateSymbols( GetScope(), GetSortOrder(), GetAnnotateAlgo(), + m_Parent->AnnotateSymbols( GetScope(), GetSortOrder(), GetAnnotateAlgo(), GetRecursive(), GetStartNumber(), GetResetItems(), true, reporter ); m_MessageWindow->Flush( true ); // Now update to show all messages @@ -244,7 +246,7 @@ void DIALOG_ANNOTATE::OnClearAnnotationClick( wxCommandEvent& event ) { bool appendUndo = false; - m_Parent->DeleteAnnotation( GetScope(), &appendUndo ); + m_Parent->DeleteAnnotation( GetScope(), GetRecursive(), &appendUndo ); m_btnClear->Enable( false ); } @@ -273,6 +275,12 @@ ANNOTATE_SCOPE_T DIALOG_ANNOTATE::GetScope() } +bool DIALOG_ANNOTATE::GetRecursive() +{ + return m_checkRecursive->GetValue(); +} + + ANNOTATE_ORDER_T DIALOG_ANNOTATE::GetSortOrder() { if( m_rbSortBy_Y_Position->GetValue() ) diff --git a/eeschema/sch_edit_frame.h b/eeschema/sch_edit_frame.h index 1461a20c82..1e62a76da9 100644 --- a/eeschema/sch_edit_frame.h +++ b/eeschema/sch_edit_frame.h @@ -365,7 +365,7 @@ public: * @param aCurrentSheetOnly Where to clear the annotation. See #ANNOTATE_SCOPE_T * @param appendUndo true to add the action to the previous undo list */ - void DeleteAnnotation( ANNOTATE_SCOPE_T aAnnotateScope, bool* appendUndo ); + void DeleteAnnotation( ANNOTATE_SCOPE_T aAnnotateScope, bool aRecursive, bool* appendUndo ); /** * Annotate the symbols in the schematic that are not currently annotated. Multi-unit symbols @@ -375,6 +375,7 @@ public: * @param aAnnotateScope See #ANNOTATE_SCOPE_T * @param aSortOption Define the annotation order. See #ANNOTATE_ORDER_T. * @param aAlgoOption Define the annotation style. See #ANNOTATE_ALGO_T. + * @param aRecursive Annotation should descend into and annotate subsheets * @param aStartNumber The start number for non-sheet-based annotation styles. * @param aResetAnnotation Clear any previous annotation if true. Otherwise, keep the * existing symbol annotation. @@ -392,8 +393,9 @@ public: * 200 to 299, and so on. */ void AnnotateSymbols( ANNOTATE_SCOPE_T aAnnotateScope, ANNOTATE_ORDER_T aSortOption, - ANNOTATE_ALGO_T aAlgoOption, int aStartNumber, bool aResetAnnotation, - bool aRepairTimestamps, REPORTER& aReporter, bool appendUndo = false ); + ANNOTATE_ALGO_T aAlgoOption, bool aRecursive, int aStartNumber, + bool aResetAnnotation, bool aRepairTimestamps, REPORTER& aReporter, + bool appendUndo = false ); /** * Check for annotation errors. @@ -412,7 +414,8 @@ public: * Otherwise check the entire schematic. */ int CheckAnnotate( ANNOTATION_ERROR_HANDLER aErrorHandler, - ANNOTATE_SCOPE_T aAnnotateScope = ANNOTATE_ALL ); + ANNOTATE_SCOPE_T aAnnotateScope = ANNOTATE_ALL, + bool aRecursive = true ); /** * Run a modal version of the annotate dialog for a specific purpose. diff --git a/eeschema/tools/sch_drawing_tools.cpp b/eeschema/tools/sch_drawing_tools.cpp index 5a32aa9124..e241dd55e5 100644 --- a/eeschema/tools/sch_drawing_tools.cpp +++ b/eeschema/tools/sch_drawing_tools.cpp @@ -278,8 +278,8 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent ) NULL_REPORTER reporter; m_frame->AnnotateSymbols( ANNOTATE_SELECTION, (ANNOTATE_ORDER_T) annotate.sort_order, - (ANNOTATE_ALGO_T) annotate.method, annotateStartNum, - false, false, reporter, true ); + (ANNOTATE_ALGO_T) annotate.method, annotate.recursive, + annotateStartNum, false, false, reporter, true ); } if( m_frame->eeconfig()->m_AutoplaceFields.enable ) diff --git a/eeschema/tools/sch_edit_tool.cpp b/eeschema/tools/sch_edit_tool.cpp index 2eb43a27e2..153fbba2d0 100644 --- a/eeschema/tools/sch_edit_tool.cpp +++ b/eeschema/tools/sch_edit_tool.cpp @@ -983,8 +983,8 @@ int SCH_EDIT_TOOL::RepeatDrawItem( const TOOL_EVENT& aEvent ) static_cast( newItem )->ClearAnnotation( nullptr, false ); NULL_REPORTER reporter; m_frame->AnnotateSymbols( ANNOTATE_SELECTION, (ANNOTATE_ORDER_T) annotate.sort_order, - (ANNOTATE_ALGO_T) annotate.method, annotateStartNum, false, - false, reporter, true ); + (ANNOTATE_ALGO_T) annotate.method, annotate.recursive, + annotateStartNum, false, false, reporter, true ); } } diff --git a/eeschema/tools/sch_editor_control.cpp b/eeschema/tools/sch_editor_control.cpp index 262ef453b2..0550b62681 100644 --- a/eeschema/tools/sch_editor_control.cpp +++ b/eeschema/tools/sch_editor_control.cpp @@ -1670,7 +1670,7 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent ) return 0; } - bool forceKeepAnnotations = pasteMode == PASTE_MODE::KEEP_ANNOTATIONS; + bool forceKeepAnnotations = pasteMode != PASTE_MODE::REMOVE_ANNOTATIONS; // SCH_SEXP_PLUGIN added the items to the paste screen, but not to the view or anything // else. Pull them back out to start with. @@ -1873,7 +1873,7 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent ) for( SCH_SHEET_PATH& instance : pasteInstances ) { SCH_SHEET_PATH sheetPath = updatePastedSheet( instance, clipPath, sheet, - forceKeepAnnotations, + ( forceKeepAnnotations && annotate.recursive ), &pastedSheets[instance], &pastedSymbols[instance] ); @@ -1960,37 +1960,14 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent ) EE_SELECTION& selection = selTool->GetSelection(); - // We should have a new selection of only the pasted symbols with their annotations cleared + // We should have a new selection of only the pasted symbols and sheets if( pasteMode == PASTE_MODE::RESPECT_OPTIONS ) { - NULL_REPORTER reporter; - // Annotate the symbols on the current sheet with the selection m_frame->AnnotateSymbols( ANNOTATE_SELECTION, (ANNOTATE_ORDER_T) annotate.sort_order, - (ANNOTATE_ALGO_T) annotate.method, annotateStartNum, false, false, - reporter, true ); - - - // Annotate all the sheets we've copied and pasted - SCH_SHEET_PATH originalSheet = m_frame->GetCurrentSheet(); - - for( SCH_SHEET_PATH& instance : pasteInstances ) - { - for( SCH_SHEET_PATH& pastedSheet : pastedSheets[instance] ) - { - m_frame->SetCurrentSheet( pastedSheet ); - m_frame->GetCurrentSheet().UpdateAllScreenReferences(); - m_frame->SetSheetNumberAndCount(); - m_frame->AnnotateSymbols( ANNOTATE_CURRENT_SHEET, - (ANNOTATE_ORDER_T) annotate.sort_order, - (ANNOTATE_ALGO_T) annotate.method, annotateStartNum, - false, false, reporter, true ); - } - } - - m_frame->SetCurrentSheet( originalSheet ); - m_frame->GetCurrentSheet().UpdateAllScreenReferences(); - m_frame->SetSheetNumberAndCount(); + (ANNOTATE_ALGO_T) annotate.method, annotate.recursive, + annotateStartNum, true, false, NULL_REPORTER::GetInstance(), + true ); } if( !selection.Empty() )