Fix broken update symbol from library.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/13782
This commit is contained in:
Wayne Stambaugh 2023-02-05 10:36:18 -05:00
parent 23d0e6b4c0
commit baeeeec492
2 changed files with 43 additions and 31 deletions

View File

@ -25,14 +25,12 @@
#include <bitmaps.h> #include <bitmaps.h>
#include <string_utils.h> // WildCompareString #include <string_utils.h> // WildCompareString
#include <kiway.h> #include <kiway.h>
#include <lib_id.h>
#include <refdes_utils.h> #include <refdes_utils.h>
#include <core/kicad_algo.h> #include <core/kicad_algo.h>
#include <dialog_change_symbols.h> #include <dialog_change_symbols.h>
#include <sch_symbol.h> #include <sch_symbol.h>
#include <sch_edit_frame.h> #include <sch_edit_frame.h>
#include <sch_screen.h> #include <sch_screen.h>
#include <sch_sheet_path.h>
#include <schematic.h> #include <schematic.h>
#include <template_fieldnames.h> #include <template_fieldnames.h>
#include <widgets/wx_html_report_panel.h> #include <widgets/wx_html_report_panel.h>
@ -467,7 +465,7 @@ int DIALOG_CHANGE_SYMBOLS::processMatchingSymbols()
return false; return false;
} }
std::map<SCH_SYMBOL*, std::vector<SCH_SHEET_PATH>> symbols; std::map<SCH_SYMBOL*, SYMBOL_CHANGE_INFO> symbols;
for( SCH_SHEET_PATH& instance : hierarchy ) for( SCH_SHEET_PATH& instance : hierarchy )
{ {
@ -485,19 +483,27 @@ int DIALOG_CHANGE_SYMBOLS::processMatchingSymbols()
if( !isMatch( symbol, &instance ) ) if( !isMatch( symbol, &instance ) )
continue; continue;
if( ( m_mode == MODE::UPDATE ) && !newId.IsValid() ) if( m_mode == MODE::UPDATE )
newId = symbol->GetLibId(); newId = symbol->GetLibId();
auto it = symbols.find( symbol ); auto it = symbols.find( symbol );
if( it == symbols.end() ) if( it == symbols.end() )
symbols.insert( { symbol, { instance } } ); {
SYMBOL_CHANGE_INFO info;
info.m_Instances.emplace_back( instance );
info.m_LibId = newId;
symbols.insert( { symbol, info } );
}
else else
it->second.emplace_back( instance ); {
it->second.m_Instances.emplace_back( instance );
}
} }
} }
matchesProcessed += processSymbols( symbols, newId ); matchesProcessed += processSymbols( symbols );
frame->GetCurrentSheet().UpdateAllScreenReferences(); frame->GetCurrentSheet().UpdateAllScreenReferences();
@ -506,16 +512,15 @@ int DIALOG_CHANGE_SYMBOLS::processMatchingSymbols()
int DIALOG_CHANGE_SYMBOLS::processSymbols( const std::map<SCH_SYMBOL*, int DIALOG_CHANGE_SYMBOLS::processSymbols( const std::map<SCH_SYMBOL*,
std::vector<SCH_SHEET_PATH>>& aSymbols, SYMBOL_CHANGE_INFO>& aSymbols )
const LIB_ID& aNewId )
{ {
wxCHECK( !aSymbols.empty() && aNewId.IsValid(), 0 ); wxCHECK( !aSymbols.empty(), 0 );
int matchesProcessed = 0; int matchesProcessed = 0;
SCH_EDIT_FRAME* frame = dynamic_cast<SCH_EDIT_FRAME*>( GetParent() ); SCH_EDIT_FRAME* frame = dynamic_cast<SCH_EDIT_FRAME*>( GetParent() );
SCH_SCREEN* screen = nullptr; SCH_SCREEN* screen = nullptr;
LIB_SYMBOL* libSymbol = nullptr; LIB_SYMBOL* libSymbol = nullptr;
std::map<SCH_SYMBOL*, std::vector<SCH_SHEET_PATH>> symbols = aSymbols; std::map<SCH_SYMBOL*, SYMBOL_CHANGE_INFO> symbols = aSymbols;
wxCHECK( frame, 0 ); wxCHECK( frame, 0 );
@ -529,13 +534,13 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( const std::map<SCH_SYMBOL*,
{ {
SCH_SYMBOL* symbol = it->first; SCH_SYMBOL* symbol = it->first;
wxCHECK2( symbol, continue ); wxCHECK2( symbol && it->second.m_LibId.IsValid(), continue );
libSymbol = frame->GetLibSymbol( aNewId ); libSymbol = frame->GetLibSymbol( it->second.m_LibId );
if( !libSymbol ) if( !libSymbol )
{ {
msg = getSymbolReferences( *symbol, aNewId ); msg = getSymbolReferences( *symbol, it->second.m_LibId );
msg << wxT( ": " ) << _( "*** symbol not found ***" ); msg << wxT( ": " ) << _( "*** symbol not found ***" );
m_messagePanel->Report( msg, RPT_SEVERITY_ERROR ); m_messagePanel->Report( msg, RPT_SEVERITY_ERROR );
it = symbols.erase( it ); it = symbols.erase( it );
@ -546,7 +551,7 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( const std::map<SCH_SYMBOL*,
if( flattenedSymbol->GetUnitCount() < symbol->GetUnit() ) if( flattenedSymbol->GetUnitCount() < symbol->GetUnit() )
{ {
msg = getSymbolReferences( *symbol, aNewId ); msg = getSymbolReferences( *symbol, it->second.m_LibId );
msg << wxT( ": " ) << _( "*** new symbol has too few units ***" ); msg << wxT( ": " ) << _( "*** new symbol has too few units ***" );
m_messagePanel->Report( msg, RPT_SEVERITY_ERROR ); m_messagePanel->Report( msg, RPT_SEVERITY_ERROR );
it = symbols.erase( it ); it = symbols.erase( it );
@ -559,11 +564,11 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( const std::map<SCH_SYMBOL*,
// Removing the symbol needs to be done before the LIB_SYMBOL is changed to prevent stale // Removing the symbol needs to be done before the LIB_SYMBOL is changed to prevent stale
// library symbols in the schematic file. // library symbols in the schematic file.
for( const auto& [ symbol, instances ] : symbols ) for( const auto& [ symbol, symbol_change_info ] : symbols )
{ {
wxCHECK( symbol && !instances.empty(), 0 ); wxCHECK( symbol && !symbol_change_info.m_Instances.empty(), 0 );
screen = instances[0].LastScreen(); screen = symbol_change_info.m_Instances[0].LastScreen();
wxCHECK( screen, 0 ); wxCHECK( screen, 0 );
@ -571,12 +576,12 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( const std::map<SCH_SYMBOL*,
frame->SaveCopyInUndoList( screen, symbol, UNDO_REDO::CHANGED, true ); frame->SaveCopyInUndoList( screen, symbol, UNDO_REDO::CHANGED, true );
} }
for( const auto& [ symbol, instances ] : symbols ) for( const auto& [ symbol, symbol_change_info ] : symbols )
{ {
if( aNewId != symbol->GetLibId() ) if( symbol_change_info.m_LibId != symbol->GetLibId() )
symbol->SetLibId( aNewId ); symbol->SetLibId( symbol_change_info.m_LibId );
libSymbol = frame->GetLibSymbol( aNewId ); libSymbol = frame->GetLibSymbol( symbol_change_info.m_LibId );
std::unique_ptr<LIB_SYMBOL> flattenedSymbol = libSymbol->Flatten(); std::unique_ptr<LIB_SYMBOL> flattenedSymbol = libSymbol->Flatten();
symbol->SetLibSymbol( flattenedSymbol.release() ); symbol->SetLibSymbol( flattenedSymbol.release() );
@ -616,7 +621,7 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( const std::map<SCH_SYMBOL*,
{ {
if( i == REFERENCE_FIELD ) if( i == REFERENCE_FIELD )
{ {
for( const SCH_SHEET_PATH& instance : instances ) for( const SCH_SHEET_PATH& instance : symbol_change_info.m_Instances )
{ {
symbol->SetRef( &instance, symbol->SetRef( &instance,
UTIL::GetRefDesUnannotated( libField->GetText() ) ); UTIL::GetRefDesUnannotated( libField->GetText() ) );
@ -691,11 +696,11 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( const std::map<SCH_SYMBOL*,
} }
symbol->SetSchSymbolLibraryName( wxEmptyString ); symbol->SetSchSymbolLibraryName( wxEmptyString );
screen = instances[0].LastScreen(); screen = symbol_change_info.m_Instances[0].LastScreen();
screen->Append( symbol ); screen->Append( symbol );
frame->GetCanvas()->GetView()->Update( symbol ); frame->GetCanvas()->GetView()->Update( symbol );
msg = getSymbolReferences( *symbol, aNewId ); msg = getSymbolReferences( *symbol, symbol_change_info.m_LibId );
msg += wxS( ": OK" ); msg += wxS( ": OK" );
m_messagePanel->Report( msg, RPT_SEVERITY_ACTION ); m_messagePanel->Report( msg, RPT_SEVERITY_ACTION );
matchesProcessed +=1; matchesProcessed +=1;
@ -705,8 +710,6 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( const std::map<SCH_SYMBOL*,
} }
wxString DIALOG_CHANGE_SYMBOLS::getSymbolReferences( SCH_SYMBOL& aSymbol, const LIB_ID& aNewId ) wxString DIALOG_CHANGE_SYMBOLS::getSymbolReferences( SCH_SYMBOL& aSymbol, const LIB_ID& aNewId )
{ {
wxString msg; wxString msg;

View File

@ -25,11 +25,21 @@
#include <dialog_change_symbols_base.h> #include <dialog_change_symbols_base.h>
class LIB_ID; #include <lib_id.h>
#include <sch_sheet_path.h>
class SCH_SYMBOL; class SCH_SYMBOL;
class SCH_EDIT_FRAME; class SCH_EDIT_FRAME;
class SCH_SCREEN; class SCH_SCREEN;
class SCH_SHEET_PATH;
struct SYMBOL_CHANGE_INFO
{
std::vector<SCH_SHEET_PATH> m_Instances;
LIB_ID m_LibId;
};
/** /**
* Dialog to update or change schematic library symbols. * Dialog to update or change schematic library symbols.
@ -74,8 +84,7 @@ private:
bool isMatch( SCH_SYMBOL* aSymbol, SCH_SHEET_PATH* aInstance ); bool isMatch( SCH_SYMBOL* aSymbol, SCH_SHEET_PATH* aInstance );
int processMatchingSymbols(); int processMatchingSymbols();
int processSymbols( const std::map<SCH_SYMBOL*, std::vector<SCH_SHEET_PATH>>& aSymbols, int processSymbols( const std::map<SCH_SYMBOL*, SYMBOL_CHANGE_INFO>& aSymbols );
const LIB_ID& aNewId );
wxString getSymbolReferences( SCH_SYMBOL& aSymbol, const LIB_ID& aNewId ); wxString getSymbolReferences( SCH_SYMBOL& aSymbol, const LIB_ID& aNewId );
SCH_SYMBOL* m_symbol; SCH_SYMBOL* m_symbol;