Fix geographic annotation bug when back annotating to schematic.

For some reason, the footprint UUID was being prefixed to the sheet path
which caused the symbol look up by sheet path to fail.  An option was
added to not do this when the geographical back annotation to the schematic
is performed.
This commit is contained in:
Wayne Stambaugh 2021-03-24 09:25:32 -04:00
parent 2da2b00560
commit b37b7d53b4
7 changed files with 266 additions and 266 deletions

View File

@ -37,6 +37,7 @@
#include <wildcards_and_files_ext.h>
#include <connection_graph.h>
BACK_ANNOTATE::BACK_ANNOTATE( SCH_EDIT_FRAME* aFrame, REPORTER& aReporter, bool aRelinkFootprints,
bool aProcessFootprints, bool aProcessValues,
bool aProcessReferences, bool aProcessNetNames, bool aDryRun ) :
@ -159,8 +160,7 @@ void BACK_ANNOTATE::getPcbModulesFromString( const std::string& aPayload )
if( path == "" )
{
msg.Printf( _( "Footprint '%s' has no assigned symbol." ),
ref );
msg.Printf( _( "Footprint '%s' has no assigned symbol." ), ref );
m_reporter.ReportHead( msg, RPT_SEVERITY_WARNING );
continue;
}
@ -251,7 +251,7 @@ void BACK_ANNOTATE::getChangeList()
if( refIndex >= 0 )
{
m_refs[ refIndex ].GetSymbol()->ClearFlags(SKIP_STRUCT );
m_refs[ refIndex ].GetSymbol()->ClearFlags( SKIP_STRUCT );
m_changelist.emplace_back( CHANGELIST_ITEM( m_refs[refIndex], pcbData ) );
}
else
@ -553,27 +553,22 @@ void BACK_ANNOTATE::processNetNameChange( const wxString& aRef, SCH_PIN* aPin,
if( schPin->IsPowerConnection() )
{
msg.Printf( _( "Net %s cannot be changed to '%s' because it is driven by a power pin." ),
aOldName,
aNewName );
msg.Printf( _( "Net %s cannot be changed to '%s' because it is driven by a power "
"pin." ), aOldName, aNewName );
m_reporter.ReportHead( msg, RPT_SEVERITY_ERROR );
break;
}
++m_changesCount;
msg.Printf( _( "Add label '%s' to %s pin %s net." ),
aNewName,
aRef,
aPin->GetNumber() );
msg.Printf( _( "Add label '%s' to %s pin %s net." ), aNewName, aRef, aPin->GetNumber() );
if( !m_dryRun )
{
SCHEMATIC_SETTINGS& settings = m_frame->Schematic().Settings();
SCH_LABEL* label = new SCH_LABEL( driver->GetPosition(), aNewName );
label->SetParent( &m_frame->Schematic() );
label->SetTextSize( wxSize( settings.m_DefaultTextSize,
settings.m_DefaultTextSize ) );
label->SetTextSize( wxSize( settings.m_DefaultTextSize, settings.m_DefaultTextSize ) );
label->SetLabelSpinStyle( spin );
label->SetFlags( IS_NEW );

View File

@ -56,7 +56,7 @@ class BACK_ANNOTATE
{
public:
/**
* Struct to hold Pcbnew footprint data.
* Container for Pcbnew footprint data.
*/
struct PCB_FP_DATA
{
@ -87,8 +87,8 @@ public:
/**
* Get netlist from the Pcbnew.
*
* @param aNetlist reference to where netlist will be stored
* @return true if success
* @param aNetlist is the netlist for the board editor.
* @return true if success.
*/
bool FetchNetlistFromPCB( std::string& aNetlist );
@ -97,8 +97,8 @@ public:
/**
* Run back annotation algorithm. If any errors, back annotation doesn't run.
*
* @param aNetlist netlist to run back annotation from
* @return true if success
* @param aNetlist is the netlist to use for back annotation.
* @return true if back annotation completed success.
*/
bool BackAnnotateSymbols( const std::string& aNetlist );
@ -106,22 +106,23 @@ private:
/**
* Parse netlist sent over KiWay express mail interface and fill \ref m_pcbModules.
*
* @param aPayload - netlist from Pcbnew
* @return number of errors during parsing
* @param aPayload is the netlist from Pcbnew.
* @return number of errors during parsing.
*/
void getPcbModulesFromString( const std::string& aPayload );
///< Create changelist
///< Create changelist.
void getChangeList();
/**
* Check if some symbols are not represented in PCB footprints and vice versa.
* \ref m_refs must be sorted by path
*
* \ref m_refs must be sorted by path.
*/
void checkForUnusedSymbols();
/**
* Apply changelist to the schematic
* Apply changelist to the schematic.
*/
void applyChangelist();

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 Brian Piccioni brian@documenteddesigns.com
* Copyright (C) 2004-2020 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2004-2021 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -22,9 +22,9 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <sch_edit_frame.h>
#include <tools/backannotate.h>
#include <reannotate.h>
#include <sch_edit_frame.h>
#include <tools/backannotate.h>
#include <reannotate.h>
WX_STRING_REPORTER_FILTERED::WX_STRING_REPORTER_FILTERED( SEVERITY aSeverity ) :
@ -69,6 +69,10 @@ void ReannotateFromPCBNew( SCH_EDIT_FRAME* aFrame, std::string& aNetlist )
false, // aProcessNetNames
false ); // aDryRun
// TODO (WS): This is completely broken. BackAnnotate symbols never fails so the attempt
// to pass information back through the Kiway payload to Pcbnew never happens.
// Attempting to pass information back through the Kiway payload in and of
// itself is broken because Kiway payloads were never intended to be bidirectional.
if( !backAnno.BackAnnotateSymbols( aNetlist ) )
{
aNetlist = _( "Errors reported by Eeschema:\n" ) + reporter.m_string.ToStdString();

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 Brian Piccioni brian@documenteddesigns.com
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2020-2021 KiCad Developers, see AUTHORS.txt for contributors.
* @author Brian Piccioni <brian@documenteddesigns.com>
*
* This program is free software; you can redistribute it and/or
@ -30,6 +30,7 @@
#include <ctype.h>
#include <dialog_board_reannotate.h>
#include <fstream>
#include <kicad_string.h> // StrNumCmp
#include <kiface_i.h>
#include <mail_type.h>
#include <pcbnew_settings.h>
@ -37,6 +38,7 @@
#include <tool/tool_manager.h>
#include <tool/grid_menu.h>
bool SortYFirst;
bool DescendingFirst;
bool DescendingSecond;
@ -46,14 +48,14 @@ bool DescendingSecond;
// right swapped.
//
int FrontDirectionsArray[] = {
SORTYFIRST + ASCENDINGFIRST + ASCENDINGSECOND, //"Top to bottom, left to right", // 100
SORTYFIRST + ASCENDINGFIRST + DESCENDINGSECOND, //"Top to bottom, right to left", // 101
SORTYFIRST + DESCENDINGFIRST + ASCENDINGSECOND, //"Back to Front, left to right", // 110
SORTYFIRST + DESCENDINGFIRST + DESCENDINGSECOND, //"Back to Front, right to left", // 111
SORTXFIRST + ASCENDINGFIRST + ASCENDINGSECOND, //"Left to right, Front to Back", // 000
SORTXFIRST + ASCENDINGFIRST + DESCENDINGSECOND, //"Left to right, Back to Front", // 001
SORTXFIRST + DESCENDINGFIRST + ASCENDINGSECOND, //"Right to left, Front to Back", // 010
SORTXFIRST + DESCENDINGFIRST + DESCENDINGSECOND //"Right to left, Back to Front", // 011
SORTYFIRST + ASCENDINGFIRST + ASCENDINGSECOND, // "Top to bottom, left to right", // 100
SORTYFIRST + ASCENDINGFIRST + DESCENDINGSECOND, // "Top to bottom, right to left", // 101
SORTYFIRST + DESCENDINGFIRST + ASCENDINGSECOND, // "Back to Front, left to right", // 110
SORTYFIRST + DESCENDINGFIRST + DESCENDINGSECOND, // "Back to Front, right to left", // 111
SORTXFIRST + ASCENDINGFIRST + ASCENDINGSECOND, // "Left to right, Front to Back", // 000
SORTXFIRST + ASCENDINGFIRST + DESCENDINGSECOND, // "Left to right, Back to Front", // 001
SORTXFIRST + DESCENDINGFIRST + ASCENDINGSECOND, // "Right to left, Front to Back", // 010
SORTXFIRST + DESCENDINGFIRST + DESCENDINGSECOND // "Right to left, Back to Front", // 011
};
@ -61,14 +63,14 @@ int FrontDirectionsArray[] = {
// Back Left/Right is opposite because it is a mirror image (coordinates are from the top)
//
int BackDirectionsArray[] = {
SORTYFIRST + ASCENDINGFIRST + DESCENDINGSECOND, //"Top to bottom, left to right", // 101
SORTYFIRST + ASCENDINGFIRST + ASCENDINGSECOND, //"Top to bottom, right to left", // 100
SORTYFIRST + DESCENDINGFIRST + DESCENDINGSECOND, //"Bottom to top, left to right", // 111
SORTYFIRST + DESCENDINGFIRST + ASCENDINGSECOND, //"Bottom to top, right to left", // 110
SORTXFIRST + DESCENDINGFIRST + ASCENDINGSECOND, //"Left to right, top to bottom", // 010
SORTXFIRST + DESCENDINGFIRST + DESCENDINGSECOND, //"Left to right, bottom to top", // 011
SORTXFIRST + ASCENDINGFIRST + ASCENDINGSECOND, //"Right to left, top to bottom", // 000
SORTXFIRST + ASCENDINGFIRST + DESCENDINGSECOND //"Right to left, bottom to top", // 001
SORTYFIRST + ASCENDINGFIRST + DESCENDINGSECOND, // "Top to bottom, left to right", // 101
SORTYFIRST + ASCENDINGFIRST + ASCENDINGSECOND, // "Top to bottom, right to left", // 100
SORTYFIRST + DESCENDINGFIRST + DESCENDINGSECOND, // "Bottom to top, left to right", // 111
SORTYFIRST + DESCENDINGFIRST + ASCENDINGSECOND, // "Bottom to top, right to left", // 110
SORTXFIRST + DESCENDINGFIRST + ASCENDINGSECOND, // "Left to right, top to bottom", // 010
SORTXFIRST + DESCENDINGFIRST + DESCENDINGSECOND, // "Left to right, bottom to top", // 011
SORTXFIRST + ASCENDINGFIRST + ASCENDINGSECOND, // "Right to left, top to bottom", // 000
SORTXFIRST + ASCENDINGFIRST + DESCENDINGSECOND // "Right to left, bottom to top", // 001
};
#define SetSortCodes( DirArray, Code ) \
@ -80,18 +82,18 @@ int BackDirectionsArray[] = {
wxString AnnotateString[] = {
_( "All" ), //AnnotateAll
_( "Only front" ), //AnnotateFront
_( "Only back" ), //AnnotateBack
_( "Only selected" ) //AnnotateSelected
_( "All" ), // AnnotateAll
_( "Only front" ), // AnnotateFront
_( "Only back" ), // AnnotateBack
_( "Only selected" ) // AnnotateSelected
};
wxString ActionMessage[] = {
"", //UpdateRefDes
_( "Empty" ), //EmptyRefDes
_( "Invalid" ), //InvalidRefDes
_( "Excluded" ) //Exclude
"", // UpdateRefDes
_( "Empty" ), // EmptyRefDes
_( "Invalid" ), // InvalidRefDes
_( "Excluded" ) // Exclude
};
@ -104,10 +106,11 @@ DIALOG_BOARD_REANNOTATE::DIALOG_BOARD_REANNOTATE( PCB_EDIT_FRAME* aParentFrame )
m_frame = aParentFrame;
m_screen = m_frame->GetScreen();
m_standalone = !m_frame->TestStandalone(); //Do this here forces the menu on top
m_standalone = !m_frame->TestStandalone(); // Do this here forces the menu on top
// Only update the schematic if not in standalone mode.
if( m_standalone )
{ //Only update the schematic if not in standalone mode
{
m_UpdateSchematic->Enable( false );
m_UpdateSchematic->SetValue( false );
}
@ -123,13 +126,13 @@ DIALOG_BOARD_REANNOTATE::DIALOG_BOARD_REANNOTATE( PCB_EDIT_FRAME* aParentFrame )
wxArrayString gridslist;
GRID_MENU::BuildChoiceList( &gridslist, m_settings, aParentFrame );
if( -1 == m_gridIndex ) //If no default loaded
m_gridIndex = m_settings->m_Window.grid.last_size_idx; //Get the current grid size
if( -1 == m_gridIndex ) // If no default loaded
m_gridIndex = m_settings->m_Window.grid.last_size_idx; // Get the current grid size
m_sortGridx = m_frame->GetCanvas()->GetGAL()->GetGridSize().x;
m_sortGridy = m_frame->GetCanvas()->GetGAL()->GetGridSize().y;
m_GridChoice->Set( gridslist ); //Show the choice in the dialog
m_GridChoice->Set( gridslist );
m_GridChoice->SetSelection( m_gridIndex );
for( wxRadioButton* button : m_sortButtons )
@ -171,7 +174,7 @@ DIALOG_BOARD_REANNOTATE::DIALOG_BOARD_REANNOTATE( PCB_EDIT_FRAME* aParentFrame )
DIALOG_BOARD_REANNOTATE::~DIALOG_BOARD_REANNOTATE()
{
GetParameters(); //Get the current menu settings
GetParameters(); // Get the current menu settings
PCBNEW_SETTINGS* cfg = m_frame->GetPcbNewSettings();
cfg->m_Reannotate.sort_on_fp_location = m_locationChoice->GetSelection() == 0;
cfg->m_Reannotate.remove_front_prefix = m_RemoveFrontPrefix->GetValue();
@ -193,7 +196,6 @@ DIALOG_BOARD_REANNOTATE::~DIALOG_BOARD_REANNOTATE()
}
/// Copy saved app settings to the dialog
void DIALOG_BOARD_REANNOTATE::InitValues( void )
{
PCBNEW_SETTINGS* cfg = m_frame->GetPcbNewSettings();
@ -223,8 +225,6 @@ void DIALOG_BOARD_REANNOTATE::OnCloseClick( wxCommandEvent& event )
}
//
/// Check to make sure the prefix (if there is one) is properly constructed
void DIALOG_BOARD_REANNOTATE::FilterPrefix( wxTextCtrl* aPrefix )
{
std::string tmps = VALIDPREFIX;
@ -269,7 +269,7 @@ void DIALOG_BOARD_REANNOTATE::OnApplyClick( wxCommandEvent& event )
return;
}
GetParameters(); //Figure out how this is to be done
GetParameters(); // Figure out how this is to be done
MakeSampleText( warning );
if( !IsOK( m_frame, warning ) )
@ -280,19 +280,17 @@ void DIALOG_BOARD_REANNOTATE::OnApplyClick( wxCommandEvent& event )
m_MessageWindow->SetLazyUpdate( false );
m_MessageWindow->Flush( false );
m_frame->GetCanvas()->Refresh(); //Redraw
m_frame->OnModify(); //Need to save file on exit.
m_frame->GetCanvas()->Refresh(); // Redraw
m_frame->OnModify(); // Need to save file on exit.
}
//
/// Make the text to summarize what is about to happen
void DIALOG_BOARD_REANNOTATE::MakeSampleText( wxString& aMessage )
{
wxString tmp;
aMessage.Printf( _( "\n%s footprints will be reannotated." ),
_( AnnotateString[m_annotationChoice] ) );
_( AnnotateString[m_annotationChoice] ) );
if( !m_ExcludeList->GetValue().empty() )
{
@ -371,7 +369,7 @@ void DIALOG_BOARD_REANNOTATE::MakeSampleText( wxString& aMessage )
void DIALOG_BOARD_REANNOTATE::GetParameters()
{
m_sortCode = 0; //Convert radio button to sort direction code
m_sortCode = 0; // Convert radio button to sort direction code
for( wxRadioButton* sortbuttons : m_sortButtons )
{
@ -387,7 +385,7 @@ void DIALOG_BOARD_REANNOTATE::GetParameters()
m_frontPrefixString = m_FrontPrefix->GetValue();
m_backPrefixString = m_BackPrefix->GetValue();
//Get the chosen sort grid for rounding
// Get the chosen sort grid for rounding
m_gridIndex = m_GridChoice->GetSelection();
if( m_gridIndex >= ( int ) m_settings->m_Window.grid.sizes.size() )
@ -420,8 +418,6 @@ void DIALOG_BOARD_REANNOTATE::GetParameters()
}
//
/// Round an int coordinate to a suitable grid
int DIALOG_BOARD_REANNOTATE::RoundToGrid( int aCoord, int aGrid )
{
if( 0 == aGrid )
@ -438,16 +434,14 @@ int DIALOG_BOARD_REANNOTATE::RoundToGrid( int aCoord, int aGrid )
}
//
/// Compare function used to compare ChangeArray element for sort
/// @return true is A < B
/// Compare function used to compare ChangeArray element for sort
/// @return true is A < B
static bool ChangeArrayCompare( const RefDesChange& aA, const RefDesChange& aB )
{
return ( aA.OldRefDesString < aB.OldRefDesString );
return ( StrNumCmp( aA.OldRefDesString, aB.OldRefDesString ) < 0 );
}
//
/// Compare function to sort footprints.
/// @return true if the first coordinate should be before the second coordinate
static bool ModuleCompare( const RefDesInfo& aA, const RefDesInfo& aB )
@ -460,7 +454,7 @@ static bool ModuleCompare( const RefDesInfo& aA, const RefDesInfo& aB )
std::swap( X1, Y1 );
}
//If descending, same compare just swap directions
// If descending, same compare just swap directions
if( DescendingFirst )
std::swap( X0, X1 );
@ -468,21 +462,18 @@ static bool ModuleCompare( const RefDesInfo& aA, const RefDesInfo& aB )
std::swap( Y0, Y1 );
if( X0 < X1 )
return ( true ); //yes, its smaller
return ( true ); // yes, its smaller
if( X0 > X1 )
return ( false ); //No its not
return ( false ); // No its not
if( Y0 < Y1 )
return ( true ); //same but equal
return ( true ); // same but equal
return ( false );
}
//
/// Convert coordinates to wxString
/// @return the string
wxString DIALOG_BOARD_REANNOTATE::CoordTowxString( int aX, int aY )
{
return wxString::Format( "%s, %s",
@ -491,8 +482,6 @@ wxString DIALOG_BOARD_REANNOTATE::CoordTowxString( int aX, int aY )
}
//
/// Break report into strings separated by \n and sent to the reporter
void DIALOG_BOARD_REANNOTATE::ShowReport( wxString aMessage, SEVERITY aSeverity )
{
size_t pos = 0, prev = 0;
@ -507,8 +496,6 @@ void DIALOG_BOARD_REANNOTATE::ShowReport( wxString aMessage, SEVERITY aSeverity
}
//
/// Create an audit trail of the changes
void DIALOG_BOARD_REANNOTATE::LogChangePlan()
{
int i = 1;
@ -518,14 +505,14 @@ void DIALOG_BOARD_REANNOTATE::LogChangePlan()
"**********************************************************\n" ),
(int) m_refDesTypes.size() );
for( RefDesTypeStr Type : m_refDesTypes ) //Show all the types of refdes
for( RefDesTypeStr Type : m_refDesTypes ) // Show all the types of refdes
message += Type.RefDesType + ( 0 == ( i++ % 16 ) ? "\n" : " " );
if( !m_excludeArray.empty() )
{
wxString excludes;
for( wxString& exclude : m_excludeArray ) //Show the refdes we are excluding
for( wxString& exclude : m_excludeArray ) // Show the refdes we are excluding
excludes += exclude + " ";
message += wxString::Format( _( "\nExcluding: %s from reannotation\n\n" ), excludes );
@ -533,19 +520,18 @@ void DIALOG_BOARD_REANNOTATE::LogChangePlan()
message += _( "\n Change Array\n***********************\n" );
for( RefDesChange Change : m_changeArray )
for( const RefDesChange& change : m_changeArray )
{
message += wxString::Format( "%s -> %s %s %s\n", Change.OldRefDesString, Change.NewRefDes,
ActionMessage[Change.Action],
UpdateRefDes != Change.Action ? wxS( " " ) + _( "will be ignored" ) : wxString("") );
message += wxString::Format(
"%s -> %s %s %s\n", change.OldRefDesString, change.NewRefDes,
ActionMessage[change.Action],
UpdateRefDes != change.Action ? _( " will be ignored" ) : wxT( "" ) );
}
ShowReport( message, RPT_SEVERITY_INFO );
}
//
/// Create a list of the footprints and their coordinates
void DIALOG_BOARD_REANNOTATE::LogFootprints( const wxString& aMessage,
const std::vector<RefDesInfo>& aFootprints )
{
@ -579,9 +565,6 @@ void DIALOG_BOARD_REANNOTATE::LogFootprints( const wxString& aMessage,
}
//
/// Actually reannotate the board
/// @return false if fail, true if success
bool DIALOG_BOARD_REANNOTATE::ReannotateBoard()
{
std::string payload;
@ -621,45 +604,49 @@ bool DIALOG_BOARD_REANNOTATE::ReannotateBoard()
return ( false );
}
payload.clear(); //If not updating schematic no netlist error
payload.clear(); // If not updating schematic no netlist error.
// If updating schematic send a netlist.
if( m_UpdateSchematic->GetValue() )
{ //If updating schematic send a netlist
{
for( FOOTPRINT* footprint : m_footprints )
{ // Create a netlist
{
// Create a netlist
newref = GetNewRefDes( footprint );
if( nullptr == newref )
return false; //Not found in changelist
return false; // Not found in changelist
//add to the netlist
// Add to the netlist
netlist.AddComponent( new COMPONENT( footprint->GetFPID(), newref->NewRefDes,
footprint->GetValue(), footprint->GetPath(), { footprint->m_Uuid } ) );
footprint->GetValue(), footprint->GetPath(),
{ footprint->m_Uuid } ) );
}
netlist.Format( "pcb_netlist", &stringformatter, 0,
CTL_OMIT_FILTERS | CTL_OMIT_NETS | CTL_OMIT_FILTERS );
CTL_OMIT_NETS | CTL_OMIT_FILTERS | CTL_OMIT_FP_UUID );
payload = stringformatter.GetString(); //create netlist
payload = stringformatter.GetString(); // Create netlist
//Send netlist to eeSchema
// Send netlist to Eeschema.
bool attemptreannotate = m_frame->ReannotateSchematic( payload );
if( !attemptreannotate )
{ //Didn't get a valid reply
{
// Didn't get a valid reply.
ShowReport( _( "\nReannotate failed!\n" ), RPT_SEVERITY_WARNING );
return false;
}
} //If updating schematic
}
bool reannotateOk = payload.size( ) == 0;
bool reannotateOk = payload.size() == 0;
ShowReport( payload, reannotateOk ? RPT_SEVERITY_ACTION : RPT_SEVERITY_ERROR );
BOARD_COMMIT commit( m_frame );
if( reannotateOk )//Only update if no errors
if( reannotateOk )
{
for( FOOTPRINT* footprint : m_footprints )
@ -680,14 +667,11 @@ bool DIALOG_BOARD_REANNOTATE::ReannotateBoard()
}
//
/// Build the footprint lists, sort it, filter for excludes, then build the change list
/// @returns true if success, false if errors
bool DIALOG_BOARD_REANNOTATE::BuildFootprintList( std::vector<RefDesInfo>& aBadRefDes )
{
bool annotateSelected;
bool annotateFront = m_AnnotateFront->GetValue(); //Unless only doing back
bool annotateBack = m_AnnotateBack->GetValue(); //Unless only doing front
bool annotateFront = m_AnnotateFront->GetValue(); // Unless only doing back
bool annotateBack = m_AnnotateBack->GetValue(); // Unless only doing front
bool skipLocked = m_ExcludeLocked->GetValue();
int errorcount = 0;
@ -705,7 +689,7 @@ bool DIALOG_BOARD_REANNOTATE::BuildFootprintList( std::vector<RefDesInfo>& aBadR
{
for( EDA_ITEM* item : m_selection )
{
//Get the timestamps of selected footprints
// Get the timestamps of selected footprints
if( item->Type() == PCB_FOOTPRINT_T )
selected.push_back( item->m_Uuid );
}
@ -715,9 +699,9 @@ bool DIALOG_BOARD_REANNOTATE::BuildFootprintList( std::vector<RefDesInfo>& aBadR
wxString exclude;
// Break exclude list into words.
for( auto thischar : m_ExcludeList->GetValue() )
{ //Break exclude list into words
{
if( ( ' ' == thischar ) || ( ',' == thischar ) )
{
m_excludeArray.push_back( exclude );
@ -742,10 +726,10 @@ bool DIALOG_BOARD_REANNOTATE::BuildFootprintList( std::vector<RefDesInfo>& aBadR
: footprint->Reference().GetPosition().x;
fpData.y = useModuleLocation ? footprint->GetPosition().y
: footprint->Reference().GetPosition().y;
fpData.roundedx = RoundToGrid( fpData.x, m_sortGridx ); //Round to sort
fpData.roundedx = RoundToGrid( fpData.x, m_sortGridx ); // Round to sort
fpData.roundedy = RoundToGrid( fpData.y, m_sortGridy );
fpData.Front = footprint->GetLayer() == F_Cu;
fpData.Action = UpdateRefDes; //Usually good
fpData.Action = UpdateRefDes; // Usually good
if( fpData.RefDesString.IsEmpty() )
{
@ -756,17 +740,17 @@ bool DIALOG_BOARD_REANNOTATE::BuildFootprintList( std::vector<RefDesInfo>& aBadR
firstnum = fpData.RefDesString.find_first_of( "0123456789" );
if( std::string::npos == firstnum )
fpData.Action = InvalidRefDes; //do not change ref des such as 12 or +1, or L
fpData.Action = InvalidRefDes; // do not change ref des such as 12 or +1, or L
}
//Get the type (R, C, etc)
// Get the type (R, C, etc)
fpData.RefDesType = fpData.RefDesString.substr( 0, firstnum );
for( wxString excluded : m_excludeArray )
{
if( excluded == fpData.RefDesType ) //Am I supposed to exclude this type?
if( excluded == fpData.RefDesType ) // Am I supposed to exclude this type?
{
fpData.Action = Exclude; //Yes
fpData.Action = Exclude; // Yes
break;
}
}
@ -779,7 +763,7 @@ bool DIALOG_BOARD_REANNOTATE::BuildFootprintList( std::vector<RefDesInfo>& aBadR
}
if( annotateSelected )
{ // If onnly annotating selected c
{ // If only annotating selected c
fpData.Action = Exclude; // Assume it isn't selected
for( KIID sel : selected )
@ -798,11 +782,17 @@ bool DIALOG_BOARD_REANNOTATE::BuildFootprintList( std::vector<RefDesInfo>& aBadR
m_backFootprints.push_back( fpData );
}
SetSortCodes( FrontDirectionsArray, m_sortCode ); //Determine the sort order for the front
sort( m_frontFootprints.begin(), m_frontFootprints.end(), ModuleCompare ); //Sort the front footprints
// Determine the sort order for the front.
SetSortCodes( FrontDirectionsArray, m_sortCode );
SetSortCodes( BackDirectionsArray, m_sortCode ); //Determine the sort order for the back
sort( m_backFootprints.begin(), m_backFootprints.end(), ModuleCompare ); //Sort the back footprints
// Sort the front footprints.
sort( m_frontFootprints.begin(), m_frontFootprints.end(), ModuleCompare );
// Determine the sort order for the back.
SetSortCodes( BackDirectionsArray, m_sortCode );
// Sort the back footprints.
sort( m_backFootprints.begin(), m_backFootprints.end(), ModuleCompare );
m_refDesTypes.clear();
m_changeArray.clear();
@ -827,7 +817,7 @@ bool DIALOG_BOARD_REANNOTATE::BuildFootprintList( std::vector<RefDesInfo>& aBadR
size_t changearraysize = m_changeArray.size();
for( size_t i = 0; i < changearraysize; i++ ) //Scan through for duplicates if update or skip
for( size_t i = 0; i < changearraysize; i++ ) // Scan through for duplicates if update or skip
{
if( ( m_changeArray[i].Action != EmptyRefDes )
&& ( m_changeArray[i].Action != InvalidRefDes ) )
@ -856,8 +846,6 @@ bool DIALOG_BOARD_REANNOTATE::BuildFootprintList( std::vector<RefDesInfo>& aBadR
}
//
/// Scan through the footprint arrays and create the from -> to array
void DIALOG_BOARD_REANNOTATE::BuildChangeArray( std::vector<RefDesInfo>& aFootprints,
unsigned int aStartRefDes, wxString aPrefix,
bool aRemovePrefix,
@ -870,17 +858,17 @@ void DIALOG_BOARD_REANNOTATE::BuildChangeArray( std::vector<RefDesInfo>& aFootpr
wxString refdestype;
size_t prefixsize = aPrefix.size();
bool haveprefix = ( 0 != prefixsize ); //Do I have a prefix?
bool addprefix = haveprefix & !aRemovePrefix; //Yes- and I'm not removing it
aRemovePrefix &= haveprefix; //Only remove if I have a prefix
bool haveprefix = ( 0 != prefixsize ); // Do I have a prefix?
bool addprefix = haveprefix & !aRemovePrefix; // Yes- and I'm not removing it
aRemovePrefix &= haveprefix; // Only remove if I have a prefix
bool prefixpresent; //Prefix found
bool prefixpresent; // Prefix found
wxString logstring = ( aFootprints.front().Front ) ? _( "\n\nFront Footprints" )
: _( "\n\nBack Footprints" );
LogFootprints( logstring, aFootprints );
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++ )
m_refDesTypes[i].RefDesCount = aStartRefDes;
@ -910,19 +898,20 @@ void DIALOG_BOARD_REANNOTATE::BuildChangeArray( std::vector<RefDesInfo>& aFootpr
prefixpresent = ( 0 == fpData.RefDesType.find( aPrefix ) );
if( addprefix && !prefixpresent )
fpData.RefDesType.insert( 0, aPrefix ); //Add prefix once only
fpData.RefDesType.insert( 0, aPrefix ); // Add prefix once only
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 );
for( i = 0; i < m_refDesTypes.size(); i++ ) //See if it is in the types array
for( i = 0; i < m_refDesTypes.size(); i++ ) // See if it is in the types array
{
if( m_refDesTypes[i].RefDesType == fpData.RefDesType ) //Found it!
if( m_refDesTypes[i].RefDesType == fpData.RefDesType ) // Found it!
break;
}
// Wasn't in the types array so add it
if( i == m_refDesTypes.size() )
{ //Wasn't in the types array so add it
{
newtype.RefDesType = fpData.RefDesType;
newtype.RefDesCount = ( aStartRefDes == 0 ? 1 : aStartRefDes );
m_refDesTypes.push_back( newtype );
@ -931,13 +920,12 @@ void DIALOG_BOARD_REANNOTATE::BuildChangeArray( std::vector<RefDesInfo>& aFootpr
change.NewRefDes = m_refDesTypes[i].RefDesType
+ std::to_string( m_refDesTypes[i].RefDesCount++ );
}
m_changeArray.push_back( change ); //Add to the change array
m_changeArray.push_back( change );
}
}
//
/// @returns the new refdes for this footprint
RefDesChange* DIALOG_BOARD_REANNOTATE::GetNewRefDes( FOOTPRINT* aFootprint )
{
size_t i;
@ -951,5 +939,5 @@ RefDesChange* DIALOG_BOARD_REANNOTATE::GetNewRefDes( FOOTPRINT* aFootprint )
ShowReport( _( "Footprint not found in changelist" ) + wxS( " " ) + aFootprint->GetReference(),
RPT_SEVERITY_ERROR );
return nullptr; //Should never happen
return nullptr; // Should never happen
}

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 Brian Piccioni brian@documenteddesigns.com
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
* @author Brian Piccioni <brian@documenteddesigns.com>
*
* This program is free software; you can redistribute it and/or
@ -42,16 +42,16 @@
#include <tool/tool_manager.h>
#include <tools/pcb_selection_tool.h>
#define SORTXFIRST 0b000 //Sort on X
#define SORTYFIRST 0b100 //Sort on Y
#define ASCENDINGFIRST 0b000 //Sort low to high
#define DESCENDINGFIRST 0b010 //Sort high to low
#define ASCENDINGSECOND 0b000 //Sort low to high
#define DESCENDINGSECOND 0b001 //Sort high to low
#define SORTXFIRST 0b000 // Sort on X
#define SORTYFIRST 0b100 // Sort on Y
#define ASCENDINGFIRST 0b000 // Sort low to high
#define DESCENDINGFIRST 0b010 // Sort high to low
#define ASCENDINGSECOND 0b000 // Sort low to high
#define DESCENDINGSECOND 0b001 // Sort high to low
#define MINGRID 1000
#define MAXERROR 10
#define VALIDPREFIX "_-+=/\\" //Prefixs can be alpha or these symbols
#define VALIDPREFIX "_-+=/\\" // Prefixs can be alpha or these symbols
enum ActionCode
{
@ -72,21 +72,21 @@ enum AnnotationChoice
struct RefDesChange
{
KIID Uuid;
wxString NewRefDes; //The new reference designation (F_U21)
wxString OldRefDesString; //What the old refdes preamble + number was
bool Front; //True if on the front of the board
ActionCode Action; //Used to skip (if #, etc)
wxString NewRefDes; // The new reference designation (F_U21)
wxString OldRefDesString; // What the old refdes preamble + number was
bool Front; // True if on the front of the board
ActionCode Action; // Used to skip (if #, etc)
};
struct RefDesInfo
{
KIID Uuid;
bool Front; //True if on the front of the board
wxString RefDesString; //What its refdes is R1, C2
wxString RefDesType; //ie R, C, etc
int x, y; //The coordinates
int roundedx, roundedy; //The coordinates after rounding.
ActionCode Action; //Used to skip (if #, etc)
bool Front; // True if on the front of the board
wxString RefDesString; // What its refdes is R1, C2
wxString RefDesType; // ie R, C, etc
int x, y; // The coordinates
int roundedx, roundedy; // The coordinates after rounding.
ActionCode Action; // Used to skip (if #, etc)
LIB_ID FPID;
};
@ -104,33 +104,6 @@ public:
~DIALOG_BOARD_REANNOTATE();
private:
PCB_EDIT_FRAME* m_frame;
FOOTPRINTS m_footprints;
PCB_SCREEN* m_screen;
PCB_SELECTION m_selection;
std::vector<RefDesChange> m_changeArray;
std::vector<RefDesInfo> m_frontFootprints;
std::vector<RefDesInfo> m_backFootprints;
std::vector<RefDesTypeStr> m_refDesTypes;
std::vector<wxString> m_excludeArray;
bool m_standalone;
int m_sortCode;
int m_gridIndex;
int m_annotationChoice;
int m_severity;
double m_sortGridx;
double m_sortGridy;
wxString m_frontPrefixString;
wxString m_backPrefixString;
wxString m_validPrefixes;
APP_SETTINGS_BASE* m_settings;
std::vector<wxRadioButton*> m_sortButtons = {
m_Down_Right,
m_Right_Down,
@ -160,10 +133,9 @@ private:
reannotate_left_up_bitmap
};
APP_SETTINGS_BASE* m_Config;
void GetParameters( void );
/// Copy saved app settings to the dialog.
void InitValues( void );
void OnApplyClick( wxCommandEvent& event ) override;
@ -171,22 +143,72 @@ private:
void FilterFrontPrefix( wxCommandEvent& event ) override;
void FilterBackPrefix( wxCommandEvent& event ) override;
/// Break report into strings separated by \n and sent to the reporter.
void ShowReport( wxString aMessage, SEVERITY aSeverity );
/// Create a list of the footprints and their coordinates.
void LogFootprints( const wxString& aMessage, const std::vector<RefDesInfo>& aFootprints );
/// Create an audit trail of the changes.
void LogChangePlan( void );
/// Actually reannotate the board.
/// @return false if fail, true if success.
bool ReannotateBoard( void );
/// Build the footprint lists, sort it, filter for excludes, then build the change list.
/// @return true if success, false if errors
bool BuildFootprintList( std::vector<RefDesInfo>& aBadRefDes );
/// Scan through the footprint arrays and create the from -> to array.
void BuildChangeArray( std::vector<RefDesInfo>& aFootprints, unsigned int aStartRefDes,
wxString aPrefix, bool aRemovePrefix,
std::vector<RefDesInfo>& aBadRefDes );
/// @return the new reference for this footprint.
RefDesChange* GetNewRefDes( FOOTPRINT* aFootprint );
int RoundToGrid( int aCoord, int aGrid );
/// Round an int coordinate to a suitable grid
int RoundToGrid( int aCoord, int aGrid );
/// Convert coordinates to wxString.
/// @return the string
wxString CoordTowxString( int aX, int aY );
void MakeSampleText( wxString& aMessage );
void FilterPrefix( wxTextCtrl* aPrefix );
/// Make the text to summarize what is about to happen.
void MakeSampleText( wxString& aMessage );
/// Check to make sure the prefix (if there is one) is properly constructed.
void FilterPrefix( wxTextCtrl* aPrefix );
PCB_EDIT_FRAME* m_frame;
FOOTPRINTS m_footprints;
PCB_SCREEN* m_screen;
PCB_SELECTION m_selection;
std::vector<RefDesChange> m_changeArray;
std::vector<RefDesInfo> m_frontFootprints;
std::vector<RefDesInfo> m_backFootprints;
std::vector<RefDesTypeStr> m_refDesTypes;
std::vector<wxString> m_excludeArray;
bool m_standalone;
int m_sortCode;
int m_gridIndex;
int m_annotationChoice;
int m_severity;
double m_sortGridx;
double m_sortGridy;
wxString m_frontPrefixString;
wxString m_backPrefixString;
wxString m_validPrefixes;
APP_SETTINGS_BASE* m_settings;
APP_SETTINGS_BASE* m_Config;
};
#endif /* DIALOG_BOARD_REANNOTATECLASSES_H_ */

View File

@ -2,8 +2,8 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 1992-2011 Jean-Pierre Charras.
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>.
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@gmail.com>.
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -77,7 +77,7 @@ void COMPONENT::Format( OUTPUTFORMATTER* aOut, int aNestLevel, int aCtl )
aOut->Print( nl, "(ref %s ", aOut->Quotew( m_reference ).c_str() );
aOut->Print( 0, "(fpid %s)\n", aOut->Quotew( m_fpid.Format() ).c_str() );
if( ! ( aCtl & CTL_OMIT_EXTRA ) )
if( !( aCtl & CTL_OMIT_EXTRA ) )
{
aOut->Print( nl+1, "(value %s)\n", aOut->Quotew( m_value ).c_str() );
aOut->Print( nl+1, "(name %s)\n", aOut->Quotew( m_name ).c_str() );
@ -88,7 +88,7 @@ void COMPONENT::Format( OUTPUTFORMATTER* aOut, int aNestLevel, int aCtl )
for( const KIID& pathStep : m_path )
path += '/' + pathStep.AsString();
if( !m_kiids.empty() )
if( !( aCtl & CTL_OMIT_FP_UUID ) && !m_kiids.empty() )
path += '/' + m_kiids.front().AsString();
aOut->Print( nl+1, "(timestamp %s)\n", aOut->Quotew( path ).c_str() );
@ -191,8 +191,7 @@ COMPONENT* NETLIST::GetComponentByPath( const KIID_PATH& aUuidPath )
/**
* Function ByFPID
* is a helper function used to sort the component list used by loadNewModules.
* A helper function used to sort the component list used by loadNewModules.
*/
static bool ByFPID( const COMPONENT& ref, const COMPONENT& cmp )
{
@ -207,8 +206,7 @@ void NETLIST::SortByFPID()
/**
* Operator <
* compares two #COMPONENT objects by reference designator.
* Compare two #COMPONENT objects by reference designator.
*/
bool operator < ( const COMPONENT& item1, const COMPONENT& item2 )
{

View File

@ -2,8 +2,8 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2012 Jean-Pierre Charras.
* Copyright (C) 2013-2016 Wayne Stambaugh <stambaughw@verizon.net>.
* Copyright (C) 2012-2020 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2013-2016 Wayne Stambaugh <stambaughw@gmail.com>.
* Copyright (C) 2012-2021 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -37,8 +37,7 @@ class REPORTER;
/**
* COMPONENT_NET
* is used to store the component pin name to net name (and pin function)
* Used to store the component pin name to net name (and pin function)
* associations stored in a netlist.
*/
class COMPONENT_NET
@ -79,45 +78,10 @@ public:
typedef std::vector< COMPONENT_NET > COMPONENT_NETS;
/**
* COMPONENT
* is used to store components and all of their related information found in a netlist.
* Store all of the related footprint information found in a netlist.
*/
class COMPONENT
{
COMPONENT_NETS m_nets; ///< list of nets shared by the component pins
wxArrayString m_footprintFilters; ///< Footprint filters found in netlist.
int m_pinCount; ///< Number of pins found in netlist.
wxString m_reference; ///< The component reference designator found in netlist.
wxString m_value; ///< The component value found in netlist.
/// A fully specified path to the component (but not the component: [ sheetUUID, sheetUUID, .. ]
KIID_PATH m_path;
/// A vector of possible KIIDs corresponding to all units in a symbol
std::vector<KIID> m_kiids;
/// The name of the component in #m_library used when it was placed on the schematic..
wxString m_name;
/// The name of the component library where #m_name was found.
wxString m_library;
/// The #LIB_ID of the footprint assigned to the component.
LIB_ID m_fpid;
/// The alt LIB_ID of the footprint, when there are 2 different assigned footprints,
/// One from the netlist, the other from the .cmp file.
/// this one is a copy of the netlist footprint assignment
LIB_ID m_altFpid;
/// The #FOOTPRINT loaded for #m_FPID.
std::unique_ptr< FOOTPRINT > m_footprint;
/// Component-specific properties found in the netlist.
std::map<wxString, wxString> m_properties;
static COMPONENT_NET m_emptyNet;
public:
COMPONENT( const LIB_ID& aFPID,
const wxString& aReference,
@ -193,6 +157,41 @@ public:
}
void Format( OUTPUTFORMATTER* aOut, int aNestLevel, int aCtl );
private:
COMPONENT_NETS m_nets; ///< list of nets shared by the component pins
wxArrayString m_footprintFilters; ///< Footprint filters found in netlist.
int m_pinCount; ///< Number of pins found in netlist.
wxString m_reference; ///< The component reference designator found in netlist.
wxString m_value; ///< The component value found in netlist.
/// A fully specified path to the component (but not the component: [ sheetUUID, sheetUUID, .. ]
KIID_PATH m_path;
/// A vector of possible KIIDs corresponding to all units in a symbol
std::vector<KIID> m_kiids;
/// The name of the component in #m_library used when it was placed on the schematic..
wxString m_name;
/// The name of the component library where #m_name was found.
wxString m_library;
/// The #LIB_ID of the footprint assigned to the component.
LIB_ID m_fpid;
/// The alt LIB_ID of the footprint, when there are 2 different assigned footprints,
/// One from the netlist, the other from the .cmp file.
/// this one is a copy of the netlist footprint assignment
LIB_ID m_altFpid;
/// The #FOOTPRINT loaded for #m_FPID.
std::unique_ptr< FOOTPRINT > m_footprint;
/// Component-specific properties found in the netlist.
std::map<wxString, wxString> m_properties;
static COMPONENT_NET m_emptyNet;
};
@ -200,17 +199,11 @@ typedef boost::ptr_vector< COMPONENT > COMPONENTS;
/**
* NETLIST
* stores all of information read from a netlist along with the flags used to update
* the NETLIST in the #BOARD.
* Store information read from a netlist along with the flags used to update the NETLIST in the
* #BOARD.
*/
class NETLIST
{
COMPONENTS m_components; // Components found in the netlist.
bool m_findByTimeStamp; // Associate components by KIID (or refdes if false)
bool m_replaceFootprints; // Update footprints to match footprints defined in netlist
public:
NETLIST() :
m_findByTimeStamp( false ),
@ -219,26 +212,22 @@ public:
}
/**
* Function IsEmpty()
* @return true if there are no components in the netlist.
*/
bool IsEmpty() const { return m_components.empty(); }
/**
* Function Clear
* removes all components from the netlist.
* Remove all components from the netlist.
*/
void Clear() { m_components.clear(); }
/**
* Function GetCount
* @return the number of components in the netlist.
*/
unsigned GetCount() const { return m_components.size(); }
/**
* Function GetComponent
* returns the #COMPONENT at \a aIndex.
* Returns the #COMPONENT at \a aIndex.
*
* @param aIndex the index in #m_components to fetch.
* @return a pointer to the #COMPONENT at \a Index.
@ -246,8 +235,7 @@ public:
COMPONENT* GetComponent( unsigned aIndex ) { return &m_components[ aIndex ]; }
/**
* Function AddComponent
* adds \a aComponent to the NETLIST.
* Add \a aComponent to the NETLIST.
*
* @note If \a aComponent already exists in the NETLIST, \a aComponent is deleted
* to prevent memory leaks. An assertion is raised in debug builds.
@ -257,8 +245,7 @@ public:
void AddComponent( COMPONENT* aComponent );
/**
* Function GetComponentByReference
* returns a #COMPONENT by \a aReference.
* Return a #COMPONENT by \a aReference.
*
* @param aReference is the reference designator the #COMPONENT.
* @return a pointer to the #COMPONENT that matches \a aReference if found. Otherwise NULL.
@ -266,8 +253,7 @@ public:
COMPONENT* GetComponentByReference( const wxString& aReference );
/**
* Function GetComponentByPath
* returns a #COMPONENT by \a aPath.
* Return a #COMPONENT by \a aPath.
*
* @param aPath is the KIID_PATH [ sheetUUID, .., compUUID ] of the #COMPONENT.
* @return a pointer to the #COMPONENT that matches \a aPath if found. Otherwise NULL.
@ -284,7 +270,6 @@ public:
bool GetReplaceFootprints() const { return m_replaceFootprints; }
/**
* Function AnyFootprintsLinked
* @return true if any component with a footprint link is found.
*/
bool AnyFootprintsLinked() const;
@ -294,6 +279,7 @@ public:
#define CTL_OMIT_EXTRA (1<<0)
#define CTL_OMIT_NETS (1<<1)
#define CTL_OMIT_FILTERS (1<<2)
#define CTL_OMIT_FP_UUID (1<<3) ///< Don't prefix the footprint UUID to the sheet path.
#define CTL_FOR_CVPCB (CTL_OMIT_NETS | CTL_OMIT_FILTERS | CTL_OMIT_EXTRA)
@ -301,6 +287,12 @@ public:
{
Format( "cvpcb_netlist", aOut, 0, CTL_FOR_CVPCB );
}
private:
COMPONENTS m_components; // Components found in the netlist.
bool m_findByTimeStamp; // Associate components by KIID (or refdes if false)
bool m_replaceFootprints; // Update footprints to match footprints defined in netlist
};