Keep track of existing/excluded references when re-annotating the PCB

Fixes https://gitlab.com/kicad/code/kicad/-/issues/8211
This commit is contained in:
Roberto Fernandez Bautista 2021-08-13 19:08:45 +01:00
parent aa67abb681
commit 35d5223825
2 changed files with 78 additions and 26 deletions

View File

@ -23,6 +23,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include <algorithm>
#include <base_units.h> #include <base_units.h>
#include <bitmaps.h> #include <bitmaps.h>
#include <board_commit.h> #include <board_commit.h>
@ -34,6 +35,7 @@
#include <kiface_i.h> #include <kiface_i.h>
#include <mail_type.h> #include <mail_type.h>
#include <pcbnew_settings.h> #include <pcbnew_settings.h>
#include <refdes_utils.h>
#include <sstream> #include <sstream>
#include <tool/tool_manager.h> #include <tool/tool_manager.h>
#include <tool/grid_menu.h> #include <tool/grid_menu.h>
@ -236,6 +238,32 @@ void DIALOG_BOARD_REANNOTATE::FilterPrefix( wxTextCtrl* aPrefix )
} }
RefDesTypeStr* DIALOG_BOARD_REANNOTATE::GetOrBuildRefDesInfo( const wxString& aRefDesPrefix,
unsigned int aStartRefDes )
{
unsigned int requiredLastRef = ( aStartRefDes == 0 ? 1 : aStartRefDes ) - 1;
for( size_t i = 0; i < m_refDesTypes.size(); i++ ) // See if it is in the types array
{
if( m_refDesTypes[i].RefDesType == aRefDesPrefix ) // Found it!
{
m_refDesTypes[i].LastUsedRefDes = std::max( m_refDesTypes[i].LastUsedRefDes,
requiredLastRef );
return &m_refDesTypes[i];
}
}
// Wasn't in the types array so add it
RefDesTypeStr newtype;
newtype.RefDesType = aRefDesPrefix;
newtype.LastUsedRefDes = requiredLastRef;
m_refDesTypes.push_back( newtype );
return &m_refDesTypes.back();
}
void DIALOG_BOARD_REANNOTATE::FilterFrontPrefix( wxCommandEvent& event ) void DIALOG_BOARD_REANNOTATE::FilterFrontPrefix( wxCommandEvent& event )
{ {
FilterPrefix( m_FrontPrefix ); FilterPrefix( m_FrontPrefix );
@ -739,7 +767,8 @@ bool DIALOG_BOARD_REANNOTATE::BuildFootprintList( std::vector<RefDesInfo>& aBadR
m_refDesTypes.clear(); m_refDesTypes.clear();
m_changeArray.clear(); m_changeArray.clear();
backstartrefdes = wxAtoi( m_BackRefDesStart->GetValue() );
BuildUnavailableRefsList();
if( !m_frontFootprints.empty() ) if( !m_frontFootprints.empty() )
{ {
@ -749,8 +778,8 @@ bool DIALOG_BOARD_REANNOTATE::BuildFootprintList( std::vector<RefDesInfo>& aBadR
if( !m_backFootprints.empty() ) if( !m_backFootprints.empty() )
{ {
BuildChangeArray( m_backFootprints, backstartrefdes, m_BackPrefix->GetValue(), BuildChangeArray( m_backFootprints, wxAtoi( m_BackRefDesStart->GetValue() ),
m_RemoveBackPrefix->GetValue(), aBadRefDes ); m_BackPrefix->GetValue(), m_RemoveBackPrefix->GetValue(), aBadRefDes );
} }
if( !m_changeArray.empty() ) if( !m_changeArray.empty() )
@ -788,17 +817,38 @@ bool DIALOG_BOARD_REANNOTATE::BuildFootprintList( std::vector<RefDesInfo>& aBadR
return ( 0 == errorcount ); return ( 0 == errorcount );
} }
void DIALOG_BOARD_REANNOTATE::BuildUnavailableRefsList()
{
std::vector<RefDesInfo> excludedFootprints;
for( RefDesInfo fpData : m_frontFootprints )
{
if( fpData.Action == Exclude )
excludedFootprints.push_back( fpData );
}
for( RefDesInfo fpData : m_backFootprints )
{
if( fpData.Action == Exclude )
excludedFootprints.push_back( fpData );
}
for( RefDesInfo fpData : excludedFootprints )
{
if( fpData.Action == Exclude )
{
RefDesTypeStr* refDesInfo = GetOrBuildRefDesInfo( fpData.RefDesType );
refDesInfo->UnavailableRefs.insert( UTIL::GetRefDesNumber( fpData.RefDesString ) );
}
}
}
void DIALOG_BOARD_REANNOTATE::BuildChangeArray( std::vector<RefDesInfo>& aFootprints, void DIALOG_BOARD_REANNOTATE::BuildChangeArray( std::vector<RefDesInfo>& aFootprints,
unsigned int aStartRefDes, const wxString& aPrefix, unsigned int aStartRefDes, const wxString& aPrefix,
bool aRemovePrefix, bool aRemovePrefix,
std::vector<RefDesInfo>& aBadRefDes ) std::vector<RefDesInfo>& aBadRefDes )
{ {
size_t i;
RefDesChange change;
RefDesTypeStr newtype;
wxString refdestype;
size_t prefixsize = aPrefix.size(); size_t prefixsize = aPrefix.size();
bool haveprefix = ( 0 != prefixsize ); // Do I have a prefix? bool haveprefix = ( 0 != prefixsize ); // Do I have a prefix?
@ -813,12 +863,15 @@ void DIALOG_BOARD_REANNOTATE::BuildChangeArray( std::vector<RefDesInfo>& aFootpr
if( 0 != aStartRefDes ) // Initialize the change array if present if( 0 != aStartRefDes ) // Initialize the change array if present
{ {
for( i = 0; i < m_refDesTypes.size(); i++ ) for( size_t i = 0; i < m_refDesTypes.size(); i++ )
m_refDesTypes[i].RefDesCount = aStartRefDes; m_refDesTypes[i].LastUsedRefDes = aStartRefDes;
} }
for( RefDesInfo fpData : aFootprints ) for( RefDesInfo fpData : aFootprints )
{ {
RefDesChange change;
change.Uuid = fpData.Uuid; change.Uuid = fpData.Uuid;
change.Action = fpData.Action; change.Action = fpData.Action;
change.OldRefDesString = fpData.RefDesString; change.OldRefDesString = fpData.RefDesString;
@ -837,7 +890,6 @@ void DIALOG_BOARD_REANNOTATE::BuildChangeArray( std::vector<RefDesInfo>& aFootpr
if( change.Action == UpdateRefDes ) if( change.Action == UpdateRefDes )
{ {
refdestype = fpData.RefDesType;
prefixpresent = ( 0 == fpData.RefDesType.find( aPrefix ) ); prefixpresent = ( 0 == fpData.RefDesType.find( aPrefix ) );
if( addprefix && !prefixpresent ) if( addprefix && !prefixpresent )
@ -846,22 +898,14 @@ void DIALOG_BOARD_REANNOTATE::BuildChangeArray( std::vector<RefDesInfo>& aFootpr
if( aRemovePrefix && prefixpresent ) // If there is a prefix remove it if( aRemovePrefix && prefixpresent ) // If there is a prefix remove it
fpData.RefDesType.erase( 0, prefixsize ); fpData.RefDesType.erase( 0, prefixsize );
for( i = 0; i < m_refDesTypes.size(); i++ ) // See if it is in the types array RefDesTypeStr* refDesInfo = GetOrBuildRefDesInfo( fpData.RefDesType, aStartRefDes );
{ unsigned int newRefDesNumber = refDesInfo->LastUsedRefDes + 1;
if( m_refDesTypes[i].RefDesType == fpData.RefDesType ) // Found it!
break;
}
// Wasn't in the types array so add it while( refDesInfo->UnavailableRefs.count( newRefDesNumber ) )
if( i == m_refDesTypes.size() ) newRefDesNumber++;
{
newtype.RefDesType = fpData.RefDesType;
newtype.RefDesCount = ( aStartRefDes == 0 ? 1 : aStartRefDes );
m_refDesTypes.push_back( newtype );
}
change.NewRefDes = m_refDesTypes[i].RefDesType change.NewRefDes = refDesInfo->RefDesType + std::to_string( newRefDesNumber );
+ std::to_string( m_refDesTypes[i].RefDesCount++ ); refDesInfo->LastUsedRefDes = newRefDesNumber;
} }
m_changeArray.push_back( change ); m_changeArray.push_back( change );

View File

@ -92,7 +92,8 @@ struct RefDesInfo
struct RefDesTypeStr struct RefDesTypeStr
{ {
wxString RefDesType; wxString RefDesType;
unsigned int RefDesCount; unsigned int LastUsedRefDes;
std::set<unsigned int> UnavailableRefs;
}; };
@ -159,6 +160,9 @@ private:
/// @return true if success, false if errors /// @return true if success, false if errors
bool BuildFootprintList( std::vector<RefDesInfo>& aBadRefDes ); bool BuildFootprintList( std::vector<RefDesInfo>& aBadRefDes );
/// Build list of unavailable references. E.g. unselected footprints or locked footprints.
void BuildUnavailableRefsList();
/// Scan through the footprint arrays and create the from -> to array. /// Scan through the footprint arrays and create the from -> to array.
void BuildChangeArray( std::vector<RefDesInfo>& aFootprints, unsigned int aStartRefDes, void BuildChangeArray( std::vector<RefDesInfo>& aFootprints, unsigned int aStartRefDes,
const wxString& aPrefix, bool aRemovePrefix, const wxString& aPrefix, bool aRemovePrefix,
@ -180,6 +184,10 @@ private:
/// Check to make sure the prefix (if there is one) is properly constructed. /// Check to make sure the prefix (if there is one) is properly constructed.
void FilterPrefix( wxTextCtrl* aPrefix ); void FilterPrefix( wxTextCtrl* aPrefix );
/// Get the structure representing the information currently held for aRefDesPrefix or create one
/// if it doesn't exist
RefDesTypeStr* GetOrBuildRefDesInfo( const wxString& aRefDesPrefix, unsigned int aStartRefDes = 0 );
PCB_EDIT_FRAME* m_frame; PCB_EDIT_FRAME* m_frame;
FOOTPRINTS m_footprints; FOOTPRINTS m_footprints;
PCB_SELECTION m_selection; PCB_SELECTION m_selection;