Eeschema: fix symbol rescue bug.

Loading the schematic symbol preserves the invalid LIB_ID characters in
the symbol name.  Unfortunately, loading the library symbol automatically
fixes the invalid characters so this caused the symbol rescue to not find
library symbols with invalid characters.  Replacing the invalid characters
in the schematic symbol name during rescue fixed the issue.  This fix
isn't perfect because there is the off chance that replacing the invalid
characters could lead to a name clash in the library resulting in the
incorrect symbol to be rescued.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/2319

(cherry picked from commit d90d734166)
This commit is contained in:
Wayne Stambaugh 2020-10-28 09:30:39 -04:00
parent e5e174a20e
commit 83d6a77617
1 changed files with 20 additions and 19 deletions

View File

@ -147,11 +147,14 @@ void RESCUE_CASE_CANDIDATE::FindRescues( RESCUER& aRescuer,
LIB_ALIAS* case_sensitive_match = nullptr; LIB_ALIAS* case_sensitive_match = nullptr;
std::vector<LIB_ALIAS*> case_insensitive_matches; std::vector<LIB_ALIAS*> case_insensitive_matches;
wxString part_name;
wxString search_name;
wxString last_part_name; wxString last_part_name;
for( SCH_COMPONENT* each_component : *( aRescuer.GetComponents() ) ) for( SCH_COMPONENT* each_component : *( aRescuer.GetComponents() ) )
{ {
wxString part_name = each_component->GetLibId().GetLibItemName(); part_name = each_component->GetLibId().GetLibItemName();
search_name = LIB_ID::FixIllegalChars( part_name, LIB_ID::ID_SCH );
if( last_part_name != part_name ) if( last_part_name != part_name )
{ {
@ -160,14 +163,14 @@ void RESCUE_CASE_CANDIDATE::FindRescues( RESCUER& aRescuer,
last_part_name = part_name; last_part_name = part_name;
case_insensitive_matches.clear(); case_insensitive_matches.clear();
LIB_ID id( wxEmptyString, part_name ); LIB_ID id( wxEmptyString, search_name );
case_sensitive_match = aRescuer.GetPrj()->SchLibs()->FindLibraryAlias( id ); case_sensitive_match = aRescuer.GetPrj()->SchLibs()->FindLibraryAlias( id );
// If the case sensitive match failed, try a case insensitive match.
if( !case_sensitive_match ) if( !case_sensitive_match )
// the case sensitive match failed. Try a case insensitive match
aRescuer.GetPrj()->SchLibs()->FindLibraryNearEntries( case_insensitive_matches, aRescuer.GetPrj()->SchLibs()->FindLibraryNearEntries( case_insensitive_matches,
part_name ); search_name );
} }
if( case_sensitive_match || !( case_insensitive_matches.size() ) ) if( case_sensitive_match || !( case_insensitive_matches.size() ) )
@ -192,7 +195,7 @@ void RESCUE_CASE_CANDIDATE::FindRescues( RESCUER& aRescuer,
wxString RESCUE_CASE_CANDIDATE::GetActionDescription() const wxString RESCUE_CASE_CANDIDATE::GetActionDescription() const
{ {
wxString action; wxString action;
action.Printf( _( "Rename to %s" ), m_new_name ); action.Printf( _( "Rename %s to %s" ), m_requested_name, m_new_name );
return action; return action;
} }
@ -249,39 +252,37 @@ void RESCUE_CACHE_CANDIDATE::FindRescues( RESCUER& aRescuer,
// So a search in libraries is made only once by group // So a search in libraries is made only once by group
LIB_PART* cache_match = nullptr; LIB_PART* cache_match = nullptr;
LIB_PART* lib_match = nullptr; LIB_PART* lib_match = nullptr;
wxString part_name;
wxString search_name;
wxString old_part_name; wxString old_part_name;
for( SCH_COMPONENT* each_component : *( aRescuer.GetComponents() ) ) for( SCH_COMPONENT* each_component : *( aRescuer.GetComponents() ) )
{ {
wxString part_name = each_component->GetLibId().GetLibItemName(); part_name = each_component->GetLibId().GetLibItemName();
search_name = LIB_ID::FixIllegalChars( part_name, LIB_ID::ID_SCH );
if( old_part_name != part_name ) if( old_part_name != part_name )
{ {
// A new part name is found (a new group starts here). // A new part name is found (a new group starts here).
// Search the symbol names candidates only once for this group: // Search the symbol names candidates only once for this group:
old_part_name = part_name; old_part_name = part_name;
cache_match = find_component( part_name, aRescuer.GetPrj()->SchLibs(), true ); cache_match = find_component( search_name, aRescuer.GetPrj()->SchLibs(), true );
lib_match = find_component( part_name, aRescuer.GetPrj()->SchLibs(), false ); lib_match = find_component( search_name, aRescuer.GetPrj()->SchLibs(), false );
if( !cache_match && !lib_match ) if( !cache_match && !lib_match )
continue; continue;
// Test whether there is a conflict or if the symbol can only be found in the cache // Test whether there is a conflict or if the symbol can only be found in the cache
// and the symbol name does not have any illegal characters. // and the symbol name does not have any illegal characters.
if( LIB_ID::HasIllegalChars( part_name, LIB_ID::ID_SCH ) == -1 ) if( cache_match && lib_match &&
{ !cache_match->PinsConflictWith( *lib_match, true, true, true, true, false ) )
if( cache_match && lib_match && continue;
!cache_match->PinsConflictWith( *lib_match, true, true, true, true, false ) )
continue;
if( !cache_match && lib_match ) if( !cache_match && lib_match )
continue; continue;
}
// Check if the symbol has already been rescued. // Check if the symbol has already been rescued.
wxString new_name = LIB_ID::FixIllegalChars( part_name, LIB_ID::ID_SCH ); RESCUE_CACHE_CANDIDATE candidate( part_name, search_name, cache_match, lib_match,
RESCUE_CACHE_CANDIDATE candidate( part_name, new_name, cache_match, lib_match,
each_component->GetUnit(), each_component->GetUnit(),
each_component->GetConvert() ); each_component->GetConvert() );