Attempt to unify symbol annotation behavior between place and paste.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/13330
This commit is contained in:
Wayne Stambaugh 2023-01-03 16:08:36 -05:00
parent 575a84f76c
commit 73b7dcbc35
4 changed files with 68 additions and 51 deletions

View File

@ -3,7 +3,7 @@
* *
* Copyright (C) 1992-2018 jean-pierre Charras <jp.charras at wanadoo.fr> * Copyright (C) 1992-2018 jean-pierre Charras <jp.charras at wanadoo.fr>
* Copyright (C) 1992-2011 Wayne Stambaugh <stambaughw@gmail.com> * Copyright (C) 1992-2011 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -603,6 +603,7 @@ void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId, int
{ {
// This is the symbol we're currently annotating. Hold the unit! // This is the symbol we're currently annotating. Hold the unit!
ref_unit.m_unit = lockedRef.m_unit; ref_unit.m_unit = lockedRef.m_unit;
// lock this new full reference // lock this new full reference
inUseRefs.insert( buildFullReference( ref_unit ) ); inUseRefs.insert( buildFullReference( ref_unit ) );
} }
@ -629,6 +630,7 @@ void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId, int
m_flatList[jj].m_numRef = ref_unit.m_numRef; m_flatList[jj].m_numRef = ref_unit.m_numRef;
m_flatList[jj].m_isNew = false; m_flatList[jj].m_isNew = false;
m_flatList[jj].m_flag = 1; m_flatList[jj].m_flag = 1;
// lock this new full reference // lock this new full reference
inUseRefs.insert( ref_candidate ); inUseRefs.insert( ref_candidate );
break; break;
@ -854,6 +856,16 @@ void SCH_REFERENCE::Annotate()
} }
bool SCH_REFERENCE::AlwaysAnnotate() const
{
wxCHECK( m_rootSymbol && m_rootSymbol->GetLibSymbolRef()
&& !m_rootSymbol->GetRef( &m_sheetPath ).IsEmpty(), false );
return m_rootSymbol->GetLibSymbolRef()->IsPower()
|| m_rootSymbol->GetRef( &m_sheetPath )[0] == wxUniChar( '#' );
}
void SCH_REFERENCE::Split() void SCH_REFERENCE::Split()
{ {
std::string refText = GetRefStr(); std::string refText = GetRefStr();

View File

@ -3,7 +3,7 @@
* *
* Copyright (C) 1992-2011 jean-pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr> * Copyright (C) 1992-2011 jean-pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@gmail.com> * Copyright (C) 2011 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -130,6 +130,14 @@ public:
*/ */
void Annotate(); void Annotate();
/**
* Verify the reference should always be automatically annotated.
*
* @return true if the symbol reference should always be automatically annotated otherwise
* false.
*/
bool AlwaysAnnotate() const;
/** /**
* Attempt to split the reference designator into a name (U) and number (1). * Attempt to split the reference designator into a name (U) and number (1).
* *
@ -251,10 +259,6 @@ typedef std::function<void( ERCE_T aType, const wxString& aMsg, SCH_REFERENCE* a
*/ */
class SCH_REFERENCE_LIST class SCH_REFERENCE_LIST
{ {
private:
std::vector<SCH_REFERENCE> m_flatList;
public: public:
SCH_REFERENCE_LIST() SCH_REFERENCE_LIST()
{ {
@ -616,6 +620,8 @@ private:
// Used for sorting static sortByTimeStamp function // Used for sorting static sortByTimeStamp function
friend class BACK_ANNOTATE; friend class BACK_ANNOTATE;
std::vector<SCH_REFERENCE> m_flatList;
}; };
#endif // _SCH_REFERENCE_LIST_H_ #endif // _SCH_REFERENCE_LIST_H_

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2019 CERN * Copyright (C) 2019 CERN
* Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2019-2023 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -192,12 +192,7 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
SCH_REFERENCE_LIST refs; SCH_REFERENCE_LIST refs;
refs.AddItem( newReference ); refs.AddItem( newReference );
if( symbol->GetLibSymbolRef()->IsPower() ) if( cfg->m_AnnotatePanel.automatic || newReference.AlwaysAnnotate() )
{
refs.ReannotateByOptions( UNSORTED, INCREMENTAL_BY_REF, 1, existingRefs,
true, nullptr );
}
else if( cfg->m_AnnotatePanel.automatic )
{ {
refs.ReannotateByOptions( refs.ReannotateByOptions(
(ANNOTATE_ORDER_T) cfg->m_AnnotatePanel.sort_order, (ANNOTATE_ORDER_T) cfg->m_AnnotatePanel.sort_order,
@ -331,6 +326,12 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
addSymbol( symbol ); addSymbol( symbol );
annotate(); annotate();
// Update the list of references for the next symbol placement.
SCH_REFERENCE placedSymbolReference( symbol, symbol->GetLibSymbolRef().get(),
m_frame->GetCurrentSheet() );
existingRefs.AddItem( placedSymbolReference );
existingRefs.SortByReferenceOnly();
if( m_frame->eeconfig()->m_AutoplaceFields.enable ) if( m_frame->eeconfig()->m_AutoplaceFields.enable )
symbol->AutoplaceFields( /* aScreen */ nullptr, /* aManual */ false ); symbol->AutoplaceFields( /* aScreen */ nullptr, /* aManual */ false );
@ -384,6 +385,13 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
addSymbol( nextSymbol ); addSymbol( nextSymbol );
symbol = nextSymbol; // annotate() looks at symbol, update it symbol = nextSymbol; // annotate() looks at symbol, update it
annotate(); annotate();
// Update the list of references for the next symbol placement.
SCH_REFERENCE placedSymbolReference( symbol,
symbol->GetLibSymbolRef().get(),
m_frame->GetCurrentSheet() );
existingRefs.AddItem( placedSymbolReference );
existingRefs.SortByReferenceOnly();
} }
} }

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2019 CERN * Copyright (C) 2019 CERN
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -1675,8 +1675,9 @@ void SCH_EDITOR_CONTROL::updatePastedSymbol( SCH_SYMBOL* aSymbol, SCH_SCREEN* aP
const KIID_PATH& aClipPath, const KIID_PATH& aClipPath,
bool aForceKeepAnnotations ) bool aForceKeepAnnotations )
{ {
wxCHECK( aSymbol && aPasteScreen, /* void */ );
KIID_PATH clipItemPath = aClipPath; KIID_PATH clipItemPath = aClipPath;
clipItemPath.push_back( aSymbol->m_Uuid );
wxString reference, value, footprint; wxString reference, value, footprint;
int unit; int unit;
@ -1720,17 +1721,11 @@ SCH_SHEET_PATH SCH_EDITOR_CONTROL::updatePastedSheet( const SCH_SHEET_PATH& aPas
SCH_SHEET_LIST* aPastedSheetsSoFar, SCH_SHEET_LIST* aPastedSheetsSoFar,
SCH_REFERENCE_LIST* aPastedSymbolsSoFar ) SCH_REFERENCE_LIST* aPastedSymbolsSoFar )
{ {
wxCHECK( aSheet && aPastedSheetsSoFar && aPastedSymbolsSoFar, aPastePath );
SCH_SHEET_PATH sheetPath = aPastePath; SCH_SHEET_PATH sheetPath = aPastePath;
sheetPath.push_back( aSheet ); sheetPath.push_back( aSheet );
wxString pageNum;
if( m_clipboardSheetInstances.count( aClipPath ) > 0 )
pageNum = m_clipboardSheetInstances.at( aClipPath ).m_PageNumber;
else
pageNum = wxString::Format( "%d", static_cast<int>( aPastedSheetsSoFar->size() ) );
sheetPath.SetPageNumber( pageNum );
aPastedSheetsSoFar->push_back( sheetPath ); aPastedSheetsSoFar->push_back( sheetPath );
if( aSheet->GetScreen() == nullptr ) if( aSheet->GetScreen() == nullptr )
@ -1756,8 +1751,8 @@ SCH_SHEET_PATH SCH_EDITOR_CONTROL::updatePastedSheet( const SCH_SHEET_PATH& aPas
aPastedSheetsSoFar, aPastedSymbolsSoFar ); aPastedSheetsSoFar, aPastedSymbolsSoFar );
SCH_SHEET_PATH subSheetPath = sheetPath; SCH_SHEET_PATH subSheetPath = sheetPath;
subSheetPath.push_back( subsheet );
subSheetPath.push_back( subsheet );
subSheetPath.GetSymbols( *aPastedSymbolsSoFar ); subSheetPath.GetSymbols( *aPastedSymbolsSoFar );
} }
} }
@ -1917,7 +1912,7 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
for( unsigned i = 0; i < loadedItems.size(); ++i ) for( unsigned i = 0; i < loadedItems.size(); ++i )
{ {
EDA_ITEM* item = loadedItems[i]; EDA_ITEM* item = loadedItems[i];
KIID_PATH clipPath( wxT("/") ); // clipboard is at root KIID_PATH clipPath( wxT( "/" ) ); // clipboard is at root
if( item->Type() == SCH_SYMBOL_T ) if( item->Type() == SCH_SYMBOL_T )
{ {
@ -2115,46 +2110,42 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
hierarchy = m_frame->Schematic().GetSheets(); hierarchy = m_frame->Schematic().GetSheets();
} }
if( pasteMode == PASTE_MODE::UNIQUE_ANNOTATIONS || pasteMode == PASTE_MODE::RESPECT_OPTIONS ) std::map<SCH_SHEET_PATH, SCH_REFERENCE_LIST> annotatedSymbols;
{
pastedSymbols.clear();
// The symbol references may be changed by adding them to the schematic // Update the list of symbol instances that satisfy the annotation criteria.
// if they only exist on the schematic (e.g. from non-standard libraries), so for( const SCH_SHEET_PATH& sheetPath : pasteInstances )
// recreate the pastedSymbols reference list here with the current data {
for( unsigned i = 0; i < loadedItems.size(); ++i ) for( size_t i = 0; i < pastedSymbols[sheetPath].GetCount(); i++ )
{ {
if( SCH_SYMBOL* symbol = dyn_cast<SCH_SYMBOL*>( loadedItems[i] ) ) if( pasteMode == PASTE_MODE::UNIQUE_ANNOTATIONS
|| pasteMode == PASTE_MODE::RESPECT_OPTIONS
|| pastedSymbols[sheetPath][i].AlwaysAnnotate() )
{ {
for( SCH_SHEET_PATH& instance : pasteInstances ) annotatedSymbols[sheetPath].AddItem( pastedSymbols[sheetPath][i] );
{
// Ignore pseudo-symbols (e.g. power symbols)
if( symbol->GetRef( &instance )[0] != wxT( '#' ) )
{
SCH_REFERENCE schReference( symbol, symbol->GetLibSymbolRef().get(), instance );
pastedSymbols[instance].AddItem( schReference );
}
}
} }
} }
}
if( !annotatedSymbols.empty() )
{
for( SCH_SHEET_PATH& instance : pasteInstances ) for( SCH_SHEET_PATH& instance : pasteInstances )
{ {
pastedSymbols[instance].SortByReferenceOnly(); annotatedSymbols[instance].SortByReferenceOnly();
if( pasteMode == PASTE_MODE::UNIQUE_ANNOTATIONS ) if( pasteMode == PASTE_MODE::UNIQUE_ANNOTATIONS )
pastedSymbols[instance].ReannotateDuplicates( existingRefs ); annotatedSymbols[instance].ReannotateDuplicates( existingRefs );
else else
pastedSymbols[instance].ReannotateByOptions( (ANNOTATE_ORDER_T) annotate.sort_order, annotatedSymbols[instance].ReannotateByOptions( (ANNOTATE_ORDER_T) annotate.sort_order,
(ANNOTATE_ALGO_T) annotate.method, (ANNOTATE_ALGO_T) annotate.method,
annotateStartNum, existingRefs, true, annotateStartNum, existingRefs,
&hierarchy ); true,
&hierarchy );
pastedSymbols[instance].UpdateAnnotation(); annotatedSymbols[instance].UpdateAnnotation();
// Update existing refs for next iteration // Update existing refs for next iteration
for( size_t i = 0; i < pastedSymbols[instance].GetCount(); i++ ) for( size_t i = 0; i < annotatedSymbols[instance].GetCount(); i++ )
existingRefs.AddItem( pastedSymbols[instance][i] ); existingRefs.AddItem( annotatedSymbols[instance][i] );
} }
} }