Schematic: better automatic/recursive annotate

This commit is contained in:
Mike Williams 2022-04-25 13:10:33 -04:00 committed by Seth Hillbrand
parent 7f3e5e9b79
commit efa23a5cbe
6 changed files with 151 additions and 45 deletions

View File

@ -60,7 +60,8 @@ void SCH_EDIT_FRAME::mapExistingAnnotation( std::map<wxString, wxString>& 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, &currentSheet, false );
if( aRecursive )
{
SCH_SHEET_LIST subSheets;
std::vector<SCH_ITEM*> tempSubSheets;
currentSheet.LastScreen()->GetSheets( &tempSubSheets );
for( SCH_ITEM* item : tempSubSheets )
{
SCH_SHEET_PATH subSheetPath = currentSheet;
subSheetPath.push_back( static_cast<SCH_SHEET*>( 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_TOOL>();
EE_SELECTION& selection = selTool->RequestSelection();
SCH_SHEET_LIST selectedSheets;
for( EDA_ITEM* item : selection.Items() )
{
if( item->Type() == SCH_SYMBOL_T )
clearSymbolAnnotation( item, screen, &currentSheet, false );
if( item->Type() == SCH_SHEET_T && aRecursive )
{
SCH_SHEET_PATH subSheetPath = currentSheet;
subSheetPath.push_back( static_cast<SCH_SHEET*>( 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<SCH_SHEET*>( 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<SCH_ITEM*> tempSubSheets;
currentSheet.LastScreen()->GetSheets( &tempSubSheets );
for( SCH_ITEM* item : tempSubSheets )
{
SCH_SHEET_PATH subSheetPath = currentSheet;
subSheetPath.push_back( static_cast<SCH_SHEET*>( 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<SCH_ITEM*> tempSubSheets;
currentSheet.LastScreen()->GetSheets( &tempSubSheets );
for( SCH_ITEM* item : tempSubSheets )
{
SCH_SHEET_PATH subSheetPath = currentSheet;
subSheetPath.push_back( static_cast<SCH_SHEET*>( 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_TOOL>();
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<SCH_SHEET*>( item ) );
sheets.GetSheetsWithinPath( selectedSheets, subSheetPath );
}
}
for( SCH_SHEET_PATH sheet : selectedSheets )
sheet.GetSymbols( referenceList, includePowerSymbols );
}
break;
}

View File

@ -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() )

View File

@ -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.

View File

@ -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 )

View File

@ -983,8 +983,8 @@ int SCH_EDIT_TOOL::RepeatDrawItem( const TOOL_EVENT& aEvent )
static_cast<SCH_SYMBOL*>( 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 );
}
}

View File

@ -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() )