Compare commits

..

7 Commits

Author SHA1 Message Date
Seth Hillbrand 2bc8c0ace5 Fix Eeschema Find/Replace
Find/Replace skipped elements that were inside the same symbol,
preventing a full search of the schematic.
2023-03-09 11:51:29 -08:00
jean-pierre charras f439dfb6ea Pcb editor: fix crash when trying to activate the "place anchor" tool.
"place anchor" tool exists only in the Fp editor. However, the hotkey
to activate this tool was also active in the board editor. Now disabled.
From master branch.
2023-02-09 16:58:54 +01:00
Wayne Stambaugh 9fdc1257a1 Fix broken update symbol from library.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/13782

(cherry picked from commit baeeeec492)
2023-02-05 11:01:29 -05:00
Wayne Stambaugh 95828ff2e2 Use references instead of copies in map pair for loops. 2023-02-03 10:04:08 -05:00
jean-pierre charras 98e55c0a04 Fix compatibility with older wxWidgets versions. 2023-02-02 20:38:51 +01:00
Wayne Stambaugh 2757d81231 Fix schematic update library symbols issues.
Rather than update library symbols one at a time, queue them up by
schematic symbol to prevent multiple updates to the same symbol in
complex hierarchies.  This also removes all of the library symbols
first which will clear out all of the library symbol variants that
were created by modifying library symbols in place and/or changes to
the symbol in the library.

Don't add new variant library symbol if an equivalent variant already
exists in the schematic local cache.  This prevents duplicate library
symbols from being added to the local cache when the first variant in
the cache does not match that of the symbol being added.
2023-02-02 12:54:08 -05:00
Wayne Stambaugh 985ceb365b Begin 6.0.12 development.
Note: There should not be a 6.0.12 but we said that about 6.0.11.  We
      want to keep the 6.0 branch alive for testing builds for any
      lingering critical bugs until 7.0.0 is released.
2023-02-02 12:45:36 -05:00
8 changed files with 367 additions and 237 deletions
+1 -1
View File
@@ -37,7 +37,7 @@
# KiCad.
#
# Note: This version string should follow the semantic versioning system
set( KICAD_SEMANTIC_VERSION "6.0.11" )
set( KICAD_SEMANTIC_VERSION "6.0.11-unknown" )
# Default the version to the semantic version.
# This is overridden by the git repository tag though (if using git)
+222 -160
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020-2021 CERN
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2021-2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* @author Wayne Stambaugh <stambaughw@gmail.com>
*
@@ -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 <wx_html_report_panel.h>
@@ -399,7 +397,9 @@ void DIALOG_CHANGE_SYMBOLS::onOkButtonClicked( wxCommandEvent& aEvent )
m_updateFields.insert( dummy_field.GetCanonicalName() );
}
else
{
m_updateFields.insert( m_fieldsBox->GetString( i ) );
}
}
}
@@ -451,15 +451,16 @@ bool DIALOG_CHANGE_SYMBOLS::isMatch( SCH_SYMBOL* aSymbol, SCH_SHEET_PATH* aInsta
}
bool DIALOG_CHANGE_SYMBOLS::processMatchingSymbols()
int DIALOG_CHANGE_SYMBOLS::processMatchingSymbols()
{
SCH_EDIT_FRAME* frame = dynamic_cast<SCH_EDIT_FRAME*>( GetParent() );
wxCHECK( frame, false );
LIB_ID newId;
bool appendToUndo = false;
bool changed = false;
wxString msg;
int matchesProcessed = 0;
SCH_SYMBOL* symbol = nullptr;
SCH_SHEET_LIST hierarchy = frame->Schematic().GetSheets();
if( m_mode == MODE::CHANGE )
@@ -470,70 +471,258 @@ bool DIALOG_CHANGE_SYMBOLS::processMatchingSymbols()
return false;
}
std::map<SCH_SYMBOL*, SYMBOL_CHANGE_INFO> symbols;
for( SCH_SHEET_PATH& instance : hierarchy )
{
SCH_SCREEN* screen = instance.LastScreen();
wxCHECK2( screen, continue );
std::vector<SCH_SYMBOL*> symbols;
// Fetch all the symbols that meet the change criteria.
for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
symbols.push_back( static_cast<SCH_SYMBOL*>( item ) );
for( SCH_SYMBOL* symbol : symbols )
{
symbol = static_cast<SCH_SYMBOL*>( item );
wxCHECK2( symbol, continue );
if( !isMatch( symbol, &instance ) )
continue;
if( m_mode == MODE::UPDATE )
newId = symbol->GetLibId();
auto it = symbols.find( symbol );
if( it == symbols.end() )
{
if( processSymbol( symbol, &instance, symbol->GetLibId(), appendToUndo ) )
changed = true;
SYMBOL_CHANGE_INFO info;
info.m_Instances.emplace_back( instance );
info.m_LibId = newId;
symbols.insert( { symbol, info } );
}
else
{
if( processSymbol( symbol, &instance, newId, appendToUndo ) )
changed = true;
it->second.m_Instances.emplace_back( instance );
}
if( changed )
appendToUndo = true;
}
}
matchesProcessed += processSymbols( symbols );
frame->GetCurrentSheet().UpdateAllScreenReferences();
return changed;
return matchesProcessed;
}
bool DIALOG_CHANGE_SYMBOLS::processSymbol( SCH_SYMBOL* aSymbol, const SCH_SHEET_PATH* aInstance,
const LIB_ID& aNewId, bool aAppendToUndo )
int DIALOG_CHANGE_SYMBOLS::processSymbols( const std::map<SCH_SYMBOL*,
SYMBOL_CHANGE_INFO>& aSymbols )
{
wxCHECK( aSymbol, false );
wxCHECK( aNewId.IsValid(), false );
wxCHECK( !aSymbols.empty(), 0 );
SCH_EDIT_FRAME* frame = dynamic_cast<SCH_EDIT_FRAME*>( GetParent() );
SCH_SCREEN* screen = aInstance->LastScreen();
int matchesProcessed = 0;
SCH_EDIT_FRAME* frame = dynamic_cast<SCH_EDIT_FRAME*>( GetParent() );
SCH_SCREEN* screen = nullptr;
SCH_SYMBOL* symbol = nullptr;
LIB_SYMBOL* libSymbol = nullptr;
std::map<SCH_SYMBOL*, SYMBOL_CHANGE_INFO> symbols = aSymbols;
wxCHECK( frame, false );
wxCHECK( frame, 0 );
LIB_ID oldId = aSymbol->GetLibId();
wxString msg;
wxString references;
for( SYMBOL_INSTANCE_REFERENCE instance : aSymbol->GetInstanceReferences() )
auto it = symbols.begin();
// Remove all symbols that don't have a valid library symbol link or enough units to
// satify the library symbol update.
while( it != symbols.end() )
{
symbol = it->first;
wxCHECK2( symbol && it->second.m_LibId.IsValid(), continue );
libSymbol = frame->GetLibSymbol( it->second.m_LibId );
if( !libSymbol )
{
msg = getSymbolReferences( *symbol, it->second.m_LibId );
msg << wxT( ": " ) << _( "*** symbol not found ***" );
m_messagePanel->Report( msg, RPT_SEVERITY_ERROR );
it = symbols.erase( it );
continue;
}
std::unique_ptr<LIB_SYMBOL> flattenedSymbol = libSymbol->Flatten();
if( flattenedSymbol->GetUnitCount() < symbol->GetUnit() )
{
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 );
}
else
{
++it;
}
}
// Removing the symbol needs to be done before the LIB_SYMBOL is changed to prevent stale
// library symbols in the schematic file.
for( auto& pair : symbols )
{
symbol = pair.first;
wxCHECK( symbol && !pair.second.m_Instances.empty(), 0 );
screen = pair.second.m_Instances[0].LastScreen();
wxCHECK( screen, 0 );
screen->Remove( symbol );
frame->SaveCopyInUndoList( screen, symbol, UNDO_REDO::CHANGED, true );
}
for( auto& pair : symbols )
{
symbol = pair.first;
if( pair.second.m_LibId != symbol->GetLibId() )
symbol->SetLibId( pair.second.m_LibId );
libSymbol = frame->GetLibSymbol( pair.second.m_LibId );
std::unique_ptr<LIB_SYMBOL> flattenedSymbol = libSymbol->Flatten();
symbol->SetLibSymbol( flattenedSymbol.release() );
if( m_resetAttributes->GetValue() )
{
symbol->SetIncludeInBom( libSymbol->GetIncludeInBom() );
symbol->SetIncludeOnBoard( libSymbol->GetIncludeOnBoard() );
}
bool removeExtras = m_removeExtraBox->GetValue();
bool resetVis = m_resetFieldVisibilities->GetValue();
bool resetEffects = m_resetFieldEffects->GetValue();
bool resetPositions = m_resetFieldPositions->GetValue();
for( unsigned i = 0; i < symbol->GetFields().size(); ++i )
{
SCH_FIELD& field = symbol->GetFields()[i];
LIB_FIELD* libField = nullptr;
// Mandatory fields always exist in m_updateFields, but these names can be translated.
// so use GetCanonicalName().
if( !alg::contains( m_updateFields, field.GetCanonicalName() ) )
continue;
if( i < MANDATORY_FIELDS )
libField = libSymbol->GetFieldById( (int) i );
else
libField = libSymbol->FindField( field.GetName() );
if( libField )
{
bool resetText = libField->GetText().IsEmpty() ? m_resetEmptyFields->GetValue()
: m_resetFieldText->GetValue();
if( resetText )
{
for( const SCH_SHEET_PATH& instance : pair.second.m_Instances )
{
if( i == REFERENCE_FIELD )
symbol->SetRef( &instance,
UTIL::GetRefDesUnannotated( libField->GetText() ) );
else if( i == VALUE_FIELD )
symbol->SetValue( &instance, UnescapeString( libField->GetText() ) );
else if( i == FOOTPRINT_FIELD )
symbol->SetFootprint( &instance, libField->GetText() );
else
field.SetText( libField->GetText() );
}
}
if( resetVis )
field.SetVisible( libField->IsVisible() );
if( resetEffects )
{
// Careful: the visible bit and position are also in Effects
bool visible = field.IsVisible();
wxPoint pos = field.GetPosition();
field.SetEffects( *libField );
field.SetVisible( visible );
field.SetPosition( pos );
}
if( resetPositions )
field.SetTextPos( symbol->GetPosition() + libField->GetTextPos() );
}
else if( i >= MANDATORY_FIELDS && removeExtras )
{
symbol->RemoveField( field.GetName() );
i--;
}
}
std::vector<LIB_FIELD*> libFields;
libSymbol->GetFields( libFields );
for( unsigned i = MANDATORY_FIELDS; i < libFields.size(); ++i )
{
const LIB_FIELD& libField = *libFields[i];
if( !alg::contains( m_updateFields, libField.GetCanonicalName() ) )
continue;
if( !symbol->FindField( libField.GetName(), false ) )
{
wxString fieldName = libField.GetCanonicalName();
SCH_FIELD newField( wxPoint( 0, 0 ), symbol->GetFieldCount(), symbol,
fieldName );
SCH_FIELD* schField = symbol->AddField( newField );
schField->SetEffects( libField );
schField->SetText( libField.GetText() );
schField->SetTextPos( symbol->GetPosition() + libField.GetTextPos() );
}
}
symbol->SetSchSymbolLibraryName( wxEmptyString );
screen = pair.second.m_Instances[0].LastScreen();
screen->Append( symbol );
frame->GetCanvas()->GetView()->Update( symbol );
msg = getSymbolReferences( *symbol, pair.second.m_LibId );
msg += wxS( ": OK" );
m_messagePanel->Report( msg, RPT_SEVERITY_ACTION );
matchesProcessed +=1;
}
return matchesProcessed;
}
wxString DIALOG_CHANGE_SYMBOLS::getSymbolReferences( SCH_SYMBOL& aSymbol, const LIB_ID& aNewId )
{
wxString msg;
wxString references;
LIB_ID oldId = aSymbol.GetLibId();
for( const SYMBOL_INSTANCE_REFERENCE& instance : aSymbol.GetInstanceReferences() )
{
if( references.IsEmpty() )
references = instance.m_Reference;
else
references += wxT( " " ) + instance.m_Reference;
}
if( m_mode == MODE::UPDATE )
{
if( aSymbol->GetInstanceReferences().size() == 1 )
if( aSymbol.GetInstanceReferences().size() == 1 )
{
msg.Printf( _( "Update symbol %s from '%s' to '%s'" ),
references,
@@ -550,7 +739,7 @@ bool DIALOG_CHANGE_SYMBOLS::processSymbol( SCH_SYMBOL* aSymbol, const SCH_SHEET_
}
else
{
if( aSymbol->GetInstanceReferences().size() == 1 )
if( aSymbol.GetInstanceReferences().size() == 1 )
{
msg.Printf( _( "Change symbol %s from '%s' to '%s'" ),
references,
@@ -566,132 +755,5 @@ bool DIALOG_CHANGE_SYMBOLS::processSymbol( SCH_SYMBOL* aSymbol, const SCH_SHEET_
}
}
LIB_SYMBOL* libSymbol = frame->GetLibSymbol( aNewId );
if( !libSymbol )
{
msg << wxT( ": " ) << _( "*** symbol not found ***" );
m_messagePanel->Report( msg, RPT_SEVERITY_ERROR );
return false;
}
std::unique_ptr<LIB_SYMBOL> flattenedSymbol = libSymbol->Flatten();
if( flattenedSymbol->GetUnitCount() < aSymbol->GetUnit() )
{
msg << wxT( ": " ) << _( "*** new symbol has too few units ***" );
m_messagePanel->Report( msg, RPT_SEVERITY_ERROR );
return false;
}
// Removing the symbol needs to be done before the LIB_SYMBOL is changed to prevent stale
// library symbols in the schematic file.
screen->Remove( aSymbol );
frame->SaveCopyInUndoList( screen, aSymbol, UNDO_REDO::CHANGED, aAppendToUndo );
if( aNewId != aSymbol->GetLibId() )
aSymbol->SetLibId( aNewId );
aSymbol->SetLibSymbol( flattenedSymbol.release() );
if( m_resetAttributes->GetValue() )
{
aSymbol->SetIncludeInBom( libSymbol->GetIncludeInBom() );
aSymbol->SetIncludeOnBoard( libSymbol->GetIncludeOnBoard() );
}
bool removeExtras = m_removeExtraBox->GetValue();
bool resetVis = m_resetFieldVisibilities->GetValue();
bool resetEffects = m_resetFieldEffects->GetValue();
bool resetPositions = m_resetFieldPositions->GetValue();
for( unsigned i = 0; i < aSymbol->GetFields().size(); ++i )
{
SCH_FIELD& field = aSymbol->GetFields()[i];
LIB_FIELD* libField = nullptr;
// Mandatory fields always exist in m_updateFields, but these names can be translated.
// so use GetCanonicalName().
if( !alg::contains( m_updateFields, field.GetCanonicalName() ) )
continue;
if( i < MANDATORY_FIELDS )
libField = libSymbol->GetFieldById( (int) i );
else
libField = libSymbol->FindField( field.GetName() );
if( libField )
{
bool resetText = libField->GetText().IsEmpty() ? m_resetEmptyFields->GetValue()
: m_resetFieldText->GetValue();
if( resetText )
{
if( i == REFERENCE_FIELD )
aSymbol->SetRef( aInstance, UTIL::GetRefDesUnannotated( libField->GetText() ) );
else if( i == VALUE_FIELD )
aSymbol->SetValue( aInstance, UnescapeString( libField->GetText() ) );
else if( i == FOOTPRINT_FIELD )
aSymbol->SetFootprint( aInstance, libField->GetText() );
else
field.SetText( libField->GetText() );
}
if( resetVis )
field.SetVisible( libField->IsVisible() );
if( resetEffects )
{
// Careful: the visible bit and position are also in Effects
bool visible = field.IsVisible();
wxPoint pos = field.GetPosition();
field.SetEffects( *libField );
field.SetVisible( visible );
field.SetPosition( pos );
}
if( resetPositions )
field.SetTextPos( aSymbol->GetPosition() + libField->GetTextPos() );
}
else if( i >= MANDATORY_FIELDS && removeExtras )
{
aSymbol->RemoveField( field.GetName() );
i--;
}
}
std::vector<LIB_FIELD*> libFields;
libSymbol->GetFields( libFields );
for( unsigned i = MANDATORY_FIELDS; i < libFields.size(); ++i )
{
const LIB_FIELD& libField = *libFields[i];
if( !alg::contains( m_updateFields, libField.GetCanonicalName() ) )
continue;
if( !aSymbol->FindField( libField.GetName(), false ) )
{
wxString fieldName = libField.GetCanonicalName();
SCH_FIELD newField( wxPoint( 0, 0), aSymbol->GetFieldCount(), aSymbol, fieldName );
SCH_FIELD* schField = aSymbol->AddField( newField );
schField->SetEffects( libField );
schField->SetText( libField.GetText() );
schField->SetTextPos( aSymbol->GetPosition() + libField.GetTextPos() );
}
}
aSymbol->SetSchSymbolLibraryName( wxEmptyString );
screen->Append( aSymbol );
frame->GetCanvas()->GetView()->Update( aSymbol );
msg += wxT( ": OK" );
m_messagePanel->Report( msg, RPT_SEVERITY_ACTION );
return true;
return msg;
}
+16 -6
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 CERN
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2021-2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* @author Wayne Stambaugh <stambaughw@gmail.com>
*
@@ -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.
@@ -73,9 +83,9 @@ private:
void updateFieldsList();
bool isMatch( SCH_SYMBOL* aSymbol, SCH_SHEET_PATH* aInstance );
bool processMatchingSymbols();
bool processSymbol( SCH_SYMBOL* aSymbol, const SCH_SHEET_PATH* aInstance,
const LIB_ID& aNewId, bool aAppendToUndo );
int processMatchingSymbols();
int processSymbols( const std::map<SCH_SYMBOL*, SYMBOL_CHANGE_INFO>& aSymbols );
wxString getSymbolReferences( SCH_SYMBOL& aSymbol, const LIB_ID& aNewId );
SCH_SYMBOL* m_symbol;
MODE m_mode;
+79 -23
View File
@@ -4,7 +4,7 @@
* Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2023 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
@@ -145,14 +145,14 @@ bool SCH_SCREEN::ClassOf( const EDA_ITEM* aItem )
}
void SCH_SCREEN::Append( SCH_ITEM* aItem )
void SCH_SCREEN::Append( SCH_ITEM* aItem, bool aUpdateLibSymbol )
{
if( aItem->Type() != SCH_SHEET_PIN_T && aItem->Type() != SCH_FIELD_T )
{
// Ensure the item can reach the SCHEMATIC through this screen
aItem->SetParent( this );
if( aItem->Type() == SCH_SYMBOL_T )
if( aItem->Type() == SCH_SYMBOL_T && aUpdateLibSymbol )
{
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( aItem );
@@ -179,30 +179,63 @@ void SCH_SCREEN::Append( SCH_ITEM* aItem )
if( *foundSymbol != *symbol->GetLibSymbolRef() )
{
int cnt = 1;
wxString newName;
std::vector<wxString> matches;
newName.Printf( wxT( "%s_%d" ), symbol->GetLibId().GetUniStringLibItemName(),
cnt );
getLibSymbolNameMatches( *symbol, matches );
foundSymbol = nullptr;
while( m_libSymbols.find( newName ) != m_libSymbols.end() )
for( const wxString& libSymbolName : matches )
{
cnt += 1;
newName.Printf( wxT( "%s_%d" ), symbol->GetLibId().GetUniStringLibItemName(),
cnt );
it = m_libSymbols.find( libSymbolName );
if( it == m_libSymbols.end() )
continue;
foundSymbol = it->second;
wxCHECK2( foundSymbol, continue );
if( *foundSymbol == *symbol->GetLibSymbolRef() )
{
newName = libSymbolName;
break;
}
foundSymbol = nullptr;
}
if( !foundSymbol )
{
int cnt = 1;
newName.Printf( wxT( "%s_%d" ),
symbol->GetLibId().GetUniStringLibItemName(),
cnt );
while( m_libSymbols.find( newName ) != m_libSymbols.end() )
{
cnt += 1;
newName.Printf( wxT( "%s_%d" ),
symbol->GetLibId().GetUniStringLibItemName(),
cnt );
}
}
// Update the schematic symbol library link as this symbol only exists
// in the schematic.
symbol->SetSchSymbolLibraryName( newName );
LIB_SYMBOL* newLibSymbol = new LIB_SYMBOL( *symbol->GetLibSymbolRef() );
LIB_ID newLibId( wxEmptyString, newName );
if( !foundSymbol )
{
// Update the schematic symbol library link as this symbol does not
// exist in any symbol library.
LIB_ID newLibId( wxEmptyString, newName );
LIB_SYMBOL* newLibSymbol = new LIB_SYMBOL( *symbol->GetLibSymbolRef() );
newLibSymbol->SetLibId( newLibId );
newLibSymbol->SetName( newName );
symbol->SetLibSymbol( newLibSymbol->Flatten().release() );
m_libSymbols[newName] = newLibSymbol;
newLibSymbol->SetLibId( newLibId );
newLibSymbol->SetName( newName );
symbol->SetLibSymbol( newLibSymbol->Flatten().release() );
m_libSymbols[newName] = newLibSymbol;
}
}
}
}
@@ -265,19 +298,19 @@ void SCH_SCREEN::FreeDrawList()
}
void SCH_SCREEN::Update( SCH_ITEM* aItem )
void SCH_SCREEN::Update( SCH_ITEM* aItem, bool aUpdateLibSymbol )
{
if( Remove( aItem ) )
Append( aItem );
if( Remove( aItem, aUpdateLibSymbol ) )
Append( aItem, aUpdateLibSymbol );
}
bool SCH_SCREEN::Remove( SCH_ITEM* aItem )
bool SCH_SCREEN::Remove( SCH_ITEM* aItem, bool aUpdateLibSymbol )
{
bool retv = m_rtree.remove( aItem );
// Check if the library symbol for the removed schematic symbol is still required.
if( retv && aItem->Type() == SCH_SYMBOL_T )
if( retv && aItem->Type() == SCH_SYMBOL_T && aUpdateLibSymbol )
{
SCH_SYMBOL* removedSymbol = static_cast<SCH_SYMBOL*>( aItem );
@@ -1198,6 +1231,29 @@ void SCH_SCREEN::SetLegacySymbolInstanceData()
}
size_t SCH_SCREEN::getLibSymbolNameMatches( const SCH_SYMBOL& aSymbol,
std::vector<wxString>& aMatches )
{
wxString searchName = aSymbol.GetLibId().GetUniStringLibId();
if( m_libSymbols.find( searchName ) != m_libSymbols.end() )
aMatches.emplace_back( searchName );
searchName = aSymbol.GetLibId().GetUniStringLibItemName() + wxS( "_" );
long tmp;
wxString suffix;
for( auto pair : m_libSymbols )
{
if( pair.first.StartsWith( searchName, &suffix ) && suffix.ToLong( &tmp ) )
aMatches.emplace_back( pair.first );
}
return aMatches.size();
}
#if defined(DEBUG)
void SCH_SCREEN::Show( int nestLevel, std::ostream& os ) const
{
+23 -6
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2023 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
@@ -181,7 +181,7 @@ public:
return m_clientSheetPathList;
}
void Append( SCH_ITEM* aItem );
void Append( SCH_ITEM* aItem, bool aUpdateLibSymbol = true );
/**
* Copy the contents of \a aScreen into this #SCH_SCREEN object.
@@ -264,16 +264,18 @@ public:
*
* @note The removed item is not deleted. It is only unlinked from the item list.
* @param[in] aItem Item to be removed from schematic.
* @param aUpdateLibSymbol removes the library symbol as required when true.
* @return True if we successfully removed the item
*/
bool Remove( SCH_ITEM* aItem );
bool Remove( SCH_ITEM* aItem, bool aUpdateLibSymbol = true );
/**
* Update \a aItem's bounding box in the tree
*
* @param[in] aItem Item that needs to be updated.
* @param aUpdateLibSymbol removes the library symbol as required when true.
*/
void Update( SCH_ITEM* aItem );
void Update( SCH_ITEM* aItem, bool aUpdateLibSymbol = true );
/**
* Removes \a aItem from the linked list and deletes the object.
@@ -516,13 +518,28 @@ private:
bool doIsJunction( const wxPoint& aPosition, bool aBreakCrossings,
bool* aHasExplicitJunctionDot, bool* aHasBusEntry ) const;
void clearLibSymbols();
/**
* Return a list of potential library symbol matches for \a aSymbol.
*
* When and existing library symbol named with the full #LIB_ID object is found, there may
* be more potential matches if the #SCH_SCREEN::Append() method need to create an alternate
* symbol due to differences from the original symbol. This process creates a new library
* symbol name by adding a "_#" suffix to the existing #LIB_ID item name.
*
* @param[in] aSymbol is the schematic symbol to search for potential library symbol matches.
* @param[out] aMatches contains library cache names of all of the potential matches.
*
* @return the number of potential matches found for \a aSymbol.
*/
size_t getLibSymbolNameMatches( const SCH_SYMBOL& aSymbol, std::vector<wxString>& aMatches );
private:
friend SCH_EDIT_FRAME; // Only to populate m_symbolInstances.
friend SCH_SEXPR_PARSER; // Only to load instance information from schematic file.
friend SCH_SEXPR_PLUGIN; // Only to save the loaded instance information to schematic file.
void clearLibSymbols();
wxString m_fileName; // File used to load the screen.
int m_fileFormatVersionAtLoad;
int m_refCount; // Number of sheets referencing this screen.
+2 -2
View File
@@ -3,7 +3,7 @@
*
* Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2023 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
@@ -310,7 +310,7 @@ void SCH_SHEET_PATH::UpdateAllScreenReferences()
symbol->GetField( VALUE_FIELD )->SetText( symbol->GetValue( this, false ) );
symbol->GetField( FOOTPRINT_FIELD )->SetText( symbol->GetFootprint( this, false ) );
symbol->UpdateUnit( symbol->GetUnitSelection( this ) );
LastScreen()->Update( item );
LastScreen()->Update( item, false );
}
}
+20 -37
View File
@@ -340,15 +340,32 @@ SCH_ITEM* SCH_EDITOR_CONTROL::nextMatch( SCH_SCREEN* aScreen, SCH_SHEET_PATH* aS
if( aAfter != nullptr )
{
past_item = false;
if( aAfter->Type() == SCH_PIN_T || aAfter->Type() == SCH_FIELD_T )
aAfter = static_cast<SCH_ITEM*>( aAfter->GetParent() );
}
std::vector<SCH_ITEM*> sorted_items;
for( SCH_ITEM* item : aScreen->Items() )
{
if( SCH_SYMBOL* sym = dyn_cast<SCH_SYMBOL*>( item ) )
{
for( SCH_FIELD& field : sym->GetFields() )
sorted_items.push_back( &field );
for( SCH_PIN* pin : sym->GetPins() )
sorted_items.push_back( pin );
}
if( SCH_SHEET* sheet = dyn_cast<SCH_SHEET*>( item ) )
{
for( SCH_FIELD& field : sheet->GetFields() )
sorted_items.push_back( &field );
for( SCH_SHEET_PIN* pin : sheet->GetPins() )
sorted_items.push_back( pin );
}
sorted_items.push_back( item );
}
std::sort( sorted_items.begin(), sorted_items.end(),
[&]( SCH_ITEM* a, SCH_ITEM* b )
@@ -379,40 +396,6 @@ SCH_ITEM* SCH_EDITOR_CONTROL::nextMatch( SCH_SCREEN* aScreen, SCH_SHEET_PATH* aS
if( item->Matches( aData, aSheet ) )
return item;
if( item->Type() == SCH_SYMBOL_T )
{
SCH_SYMBOL* cmp = static_cast<SCH_SYMBOL*>( item );
for( SCH_FIELD& field : cmp->GetFields() )
{
if( field.Matches( aData, aSheet ) )
return &field;
}
for( SCH_PIN* pin : cmp->GetPins() )
{
if( pin->Matches( aData, aSheet ) )
return pin;
}
}
if( item->Type() == SCH_SHEET_T )
{
SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
for( SCH_FIELD& field : sheet->GetFields() )
{
if( field.Matches( aData, aSheet ) )
return &field;
}
for( SCH_SHEET_PIN* pin : sheet->GetPins() )
{
if( pin->Matches( aData, aSheet ) )
return pin;
}
}
}
}
+4 -2
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014-2017 CERN
* Copyright (C) 2018-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2018-2023 KiCad Developers, see AUTHORS.txt for contributors.
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
@@ -1332,7 +1332,9 @@ int DRAWING_TOOL::PlaceImportedGraphics( const TOOL_EVENT& aEvent )
int DRAWING_TOOL::SetAnchor( const TOOL_EVENT& aEvent )
{
wxASSERT( m_isFootprintEditor );
// Make sense only in FP editor
if( !m_isFootprintEditor )
return 0;
if( !m_frame->GetModel() )
return 0;