Process all symbol instances as the ref, value, etc. may be different.

Also makes sure that the instance fields get set for reference, value
and footprint, and not just the base SCH_FIELD.

Also makes the translations easier.

Fixes https://gitlab.com/kicad/code/kicad/issues/6459
This commit is contained in:
Jeff Young 2020-11-23 21:23:40 +00:00
parent 34dbce6bce
commit bf04fc3b72
3 changed files with 65 additions and 45 deletions

View File

@ -389,10 +389,6 @@ bool DIALOG_CHANGE_SYMBOLS::processMatchingSymbols()
return false;
}
// Use map as a cheap and dirty way to ensure library symbols are not updated multiple
// times in complex hierachies.
std::map<SCH_COMPONENT*, SCH_SCREEN*> symbolsToProcess;
for( SCH_SHEET_PATH& instance : hierarchy )
{
SCH_SCREEN* screen = instance.LastScreen();
@ -408,42 +404,36 @@ bool DIALOG_CHANGE_SYMBOLS::processMatchingSymbols()
if( !isMatch( symbol, &instance ) )
continue;
// Shared symbols always have identical library symbols so don't add duplicates.
symbolsToProcess[symbol] = screen;
if( m_mode == MODE::UPDATE )
{
if( processSymbol( symbol, &instance, symbol->GetLibId(), appendToUndo ) )
changed = true;
}
else
{
if( processSymbol( symbol, &instance, newId, appendToUndo ) )
changed = true;
}
if( changed )
appendToUndo = true;
}
}
for( auto i : symbolsToProcess )
{
SCH_COMPONENT* symbol = i.first;
if( m_mode == MODE::UPDATE )
{
if( processSymbol( symbol, i.second, symbol->GetLibId(), appendToUndo ) )
changed = true;
}
else
{
if( processSymbol( symbol, i.second, newId, appendToUndo ) )
changed = true;
}
if( changed )
appendToUndo = true;
}
frame->GetCurrentSheet().UpdateAllScreenReferences();
return changed;
}
bool DIALOG_CHANGE_SYMBOLS::processSymbol( SCH_COMPONENT* aSymbol, SCH_SCREEN* aScreen,
const LIB_ID& aNewId, bool aAppendToUndo )
bool DIALOG_CHANGE_SYMBOLS::processSymbol( SCH_COMPONENT* aSymbol, const SCH_SHEET_PATH* aInstance,
const LIB_ID& aNewId, bool aAppendToUndo )
{
wxCHECK( aSymbol, false );
wxCHECK( aScreen, false );
wxCHECK( aNewId.IsValid(), false );
SCH_EDIT_FRAME* frame = dynamic_cast<SCH_EDIT_FRAME*>( GetParent() );
SCH_SCREEN* screen = aInstance->LastScreen();
wxCHECK( frame, false );
@ -459,12 +449,40 @@ bool DIALOG_CHANGE_SYMBOLS::processSymbol( SCH_COMPONENT* aSymbol, SCH_SCREEN* a
references += " " + instance.m_Reference;
}
msg.Printf( _( "%s %s \"%s\" from \"%s\" to \"%s\"" ),
( m_mode == MODE::UPDATE ) ? _( "Update" ) : _( "Change" ),
( aSymbol->GetInstanceReferences().size() == 1 ) ? _( "symbol" ) : _( "symbols" ),
references,
oldId.Format().c_str(),
aNewId.Format().c_str() );
if( m_mode == MODE::UPDATE )
{
if( aSymbol->GetInstanceReferences().size() == 1 )
{
msg.Printf( _( "Update symbol %s from '%s' to '%s'" ),
references,
oldId.Format().c_str(),
aNewId.Format().c_str() );
}
else
{
msg.Printf( _( "Update symbols %s from '%s' to '%s'" ),
references,
oldId.Format().c_str(),
aNewId.Format().c_str() );
}
}
else
{
if( aSymbol->GetInstanceReferences().size() == 1 )
{
msg.Printf( _( "Change symbol %s from '%s' to '%s'" ),
references,
oldId.Format().c_str(),
aNewId.Format().c_str() );
}
else
{
msg.Printf( _( "Change symbols %s from '%s' to '%s'" ),
references,
oldId.Format().c_str(),
aNewId.Format().c_str() );
}
}
LIB_PART* libSymbol = frame->GetLibPart( aNewId );
@ -486,8 +504,8 @@ bool DIALOG_CHANGE_SYMBOLS::processSymbol( SCH_COMPONENT* aSymbol, SCH_SCREEN* a
// Removing the symbol needs to be done before the LIB_PART is changed to prevent stale
// library symbols in the schematic file.
aScreen->Remove( aSymbol );
frame->SaveCopyInUndoList( aScreen, aSymbol, UNDO_REDO::CHANGED, aAppendToUndo );
screen->Remove( aSymbol );
frame->SaveCopyInUndoList( screen, aSymbol, UNDO_REDO::CHANGED, aAppendToUndo );
if( aNewId != aSymbol->GetLibId() )
aSymbol->SetLibId( aNewId );
@ -515,15 +533,17 @@ bool DIALOG_CHANGE_SYMBOLS::processSymbol( SCH_COMPONENT* aSymbol, SCH_SCREEN* a
if( libField )
{
if( libField->GetText().IsEmpty() )
if( !libField->GetText().IsEmpty() || resetEmpty )
{
if( resetEmpty )
if( i == REFERENCE_FIELD )
aSymbol->SetRef( aInstance, libField->GetText() );
else if( i == VALUE_FIELD )
aSymbol->SetValue( aInstance, libField->GetText() );
else if( i == FOOTPRINT_FIELD )
aSymbol->SetFootprint( aInstance, libField->GetText() );
else
field->SetText( wxEmptyString );
}
else
{
field->SetText( libField->GetText() );
}
if( resetVis )
field->SetVisible( libField->IsVisible() );
@ -570,7 +590,7 @@ bool DIALOG_CHANGE_SYMBOLS::processSymbol( SCH_COMPONENT* aSymbol, SCH_SCREEN* a
}
}
aScreen->Append( aSymbol );
screen->Append( aSymbol );
frame->GetCanvas()->GetView()->Update( aSymbol );
msg += ": OK";

View File

@ -71,8 +71,8 @@ private:
bool isMatch( SCH_COMPONENT* aSymbol, SCH_SHEET_PATH* aInstance );
bool processMatchingSymbols();
bool processSymbol( SCH_COMPONENT* aSymbol, SCH_SCREEN* aScreen, const LIB_ID& aNewId,
bool aAppendToUndo );
bool processSymbol( SCH_COMPONENT* aSymbol, const SCH_SHEET_PATH* aInstance,
const LIB_ID& aNewId, bool aAppendToUndo );
SCH_COMPONENT* m_symbol;
MODE m_mode;

View File

@ -94,7 +94,7 @@ void SCH_VIEW::ResizeSheetWorkingArea( SCH_SCREEN* aScreen )
void SCH_VIEW::DisplaySheet( SCH_SCREEN *aScreen )
{
for( auto item : aScreen->Items() )
for( SCH_ITEM* item : aScreen->Items() )
Add( item );
m_worksheet.reset( new KIGFX::WS_PROXY_VIEW_ITEM( static_cast< int >( IU_PER_MILS ),