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 <string_utils.h> // WildCompareString
#include <kiway.h>
#include <lib_id.h>
#include <refdes_utils.h>
#include <core/kicad_algo.h>
#include <dialog_change_symbols.h>
#include <sch_symbol.h>
#include <sch_edit_frame.h>
#include <sch_screen.h>
#include <sch_sheet_path.h>
#include <schematic.h>
#include <template_fieldnames.h>
#include <widgets/wx_html_report_panel.h>
@ -467,7 +465,7 @@ int DIALOG_CHANGE_SYMBOLS::processMatchingSymbols()
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 )
{
@ -485,19 +483,27 @@ int DIALOG_CHANGE_SYMBOLS::processMatchingSymbols()
if( !isMatch( symbol, &instance ) )
continue;
if( ( m_mode == MODE::UPDATE ) && !newId.IsValid() )
if( m_mode == MODE::UPDATE )
newId = symbol->GetLibId();
auto it = symbols.find( symbol );
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
it->second.emplace_back( instance );
{
it->second.m_Instances.emplace_back( instance );
}
}
}
matchesProcessed += processSymbols( symbols, newId );
matchesProcessed += processSymbols( symbols );
frame->GetCurrentSheet().UpdateAllScreenReferences();
@ -506,16 +512,15 @@ int DIALOG_CHANGE_SYMBOLS::processMatchingSymbols()
int DIALOG_CHANGE_SYMBOLS::processSymbols( const std::map<SCH_SYMBOL*,
std::vector<SCH_SHEET_PATH>>& aSymbols,
const LIB_ID& aNewId )
SYMBOL_CHANGE_INFO>& aSymbols )
{
wxCHECK( !aSymbols.empty() && aNewId.IsValid(), 0 );
wxCHECK( !aSymbols.empty(), 0 );
int matchesProcessed = 0;
SCH_EDIT_FRAME* frame = dynamic_cast<SCH_EDIT_FRAME*>( GetParent() );
SCH_SCREEN* screen = 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 );
@ -529,13 +534,13 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( const std::map<SCH_SYMBOL*,
{
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 )
{
msg = getSymbolReferences( *symbol, aNewId );
msg = getSymbolReferences( *symbol, it->second.m_LibId );
msg << wxT( ": " ) << _( "*** symbol not found ***" );
m_messagePanel->Report( msg, RPT_SEVERITY_ERROR );
it = symbols.erase( it );
@ -546,7 +551,7 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( const std::map<SCH_SYMBOL*,
if( flattenedSymbol->GetUnitCount() < symbol->GetUnit() )
{
msg = getSymbolReferences( *symbol, aNewId );
msg = getSymbolReferences( *symbol, it->second.m_LibId );
msg << wxT( ": " ) << _( "*** new symbol has too few units ***" );
m_messagePanel->Report( msg, RPT_SEVERITY_ERROR );
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
// 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 );
@ -571,12 +576,12 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( const std::map<SCH_SYMBOL*,
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() )
symbol->SetLibId( aNewId );
if( symbol_change_info.m_LibId != symbol->GetLibId() )
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();
symbol->SetLibSymbol( flattenedSymbol.release() );
@ -616,7 +621,7 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( const std::map<SCH_SYMBOL*,
{
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,
UTIL::GetRefDesUnannotated( libField->GetText() ) );
@ -691,11 +696,11 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( const std::map<SCH_SYMBOL*,
}
symbol->SetSchSymbolLibraryName( wxEmptyString );
screen = instances[0].LastScreen();
screen = symbol_change_info.m_Instances[0].LastScreen();
screen->Append( symbol );
frame->GetCanvas()->GetView()->Update( symbol );
msg = getSymbolReferences( *symbol, aNewId );
msg = getSymbolReferences( *symbol, symbol_change_info.m_LibId );
msg += wxS( ": OK" );
m_messagePanel->Report( msg, RPT_SEVERITY_ACTION );
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 msg;

View File

@ -25,11 +25,21 @@
#include <dialog_change_symbols_base.h>
class LIB_ID;
#include <lib_id.h>
#include <sch_sheet_path.h>
class SCH_SYMBOL;
class SCH_EDIT_FRAME;
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.
@ -74,8 +84,7 @@ private:
bool isMatch( SCH_SYMBOL* aSymbol, SCH_SHEET_PATH* aInstance );
int processMatchingSymbols();
int processSymbols( const std::map<SCH_SYMBOL*, std::vector<SCH_SHEET_PATH>>& aSymbols,
const LIB_ID& aNewId );
int processSymbols( const std::map<SCH_SYMBOL*, SYMBOL_CHANGE_INFO>& aSymbols );
wxString getSymbolReferences( SCH_SYMBOL& aSymbol, const LIB_ID& aNewId );
SCH_SYMBOL* m_symbol;