7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-21 00:21:25 +00:00

Delay resolution of component classes when pasting footprints

Fixes https://gitlab.com/kicad/code/kicad/-/issues/19862
This commit is contained in:
JamesJCode 2025-02-07 17:47:21 +00:00
parent a6fffb15ff
commit 5fda0d02e1
6 changed files with 60 additions and 14 deletions

View File

@ -89,8 +89,8 @@ COMPONENT_CLASS_MANAGER::COMPONENT_CLASS_MANAGER()
}
COMPONENT_CLASS*
COMPONENT_CLASS_MANAGER::GetEffectiveComponentClass( std::unordered_set<wxString>& classNames )
COMPONENT_CLASS* COMPONENT_CLASS_MANAGER::GetEffectiveComponentClass(
const std::unordered_set<wxString>& classNames )
{
if( classNames.size() == 0 )
return m_noneClass.get();
@ -177,8 +177,8 @@ void COMPONENT_CLASS_MANAGER::FinishNetlistUpdate()
}
wxString
COMPONENT_CLASS_MANAGER::GetFullClassNameForConstituents( std::unordered_set<wxString>& classNames )
wxString COMPONENT_CLASS_MANAGER::GetFullClassNameForConstituents(
const std::unordered_set<wxString>& classNames )
{
std::vector<wxString> sortedClassNames( classNames.begin(), classNames.end() );
@ -193,7 +193,7 @@ COMPONENT_CLASS_MANAGER::GetFullClassNameForConstituents( std::unordered_set<wxS
wxString
COMPONENT_CLASS_MANAGER::GetFullClassNameForConstituents( std::vector<wxString>& classNames )
COMPONENT_CLASS_MANAGER::GetFullClassNameForConstituents( const std::vector<wxString>& classNames )
{
if( classNames.size() == 0 )
return wxEmptyString;

View File

@ -87,16 +87,17 @@ public:
COMPONENT_CLASS_MANAGER();
/// @brief Gets the full effective class name for the given set of constituent classes
static wxString GetFullClassNameForConstituents( std::unordered_set<wxString>& classNames );
static wxString
GetFullClassNameForConstituents( const std::unordered_set<wxString>& classNames );
/// @brief Gets the full effective class name for the given set of constituent classes
/// @param classNames a sorted vector of consituent class names
static wxString GetFullClassNameForConstituents( std::vector<wxString>& classNames );
static wxString GetFullClassNameForConstituents( const std::vector<wxString>& classNames );
/// @brief Gets an effective component class for the given constituent class names
/// @param classes The names of the constituent component classes
/// @return Effective COMPONENT_CLASS object
COMPONENT_CLASS* GetEffectiveComponentClass( std::unordered_set<wxString>& classNames );
COMPONENT_CLASS* GetEffectiveComponentClass( const std::unordered_set<wxString>& classNames );
/// Returns the unassigned component class
const COMPONENT_CLASS* GetNoneComponentClass() const { return m_noneClass.get(); }

View File

@ -4035,6 +4035,15 @@ wxString FOOTPRINT::GetComponentClassAsString() const
}
void FOOTPRINT::ResolveComponentClassNames(
BOARD* aBoard, const std::unordered_set<wxString>& aComponentClassNames )
{
const COMPONENT_CLASS* componentClass =
aBoard->GetComponentClassManager().GetEffectiveComponentClass( aComponentClassNames );
SetComponentClass( componentClass );
}
static struct FOOTPRINT_DESC
{
FOOTPRINT_DESC()

View File

@ -1021,10 +1021,37 @@ public:
double Similarity( const BOARD_ITEM& aOther ) const override;
/// Sets the component class object pointer for this footprint
void SetComponentClass( const COMPONENT_CLASS* aClass ) { m_componentClass = aClass; }
/**
* @brief Sets the transient component class names
*
* This is used during paste operations as we can't resolve the component classes immediately
* until we have the true board context once the pasted items have been placed
*/
void SetTransientComponentClassNames( const std::unordered_set<wxString>& classNames )
{
m_transientComponentClassNames = classNames;
}
/// Gets the transient component class names
const std::unordered_set<wxString>& GetTransientComponentClassNames()
{
return m_transientComponentClassNames;
}
/// Remove the transient component class names
void ClearTransientComponentClassNames() { m_transientComponentClassNames.clear(); };
/// Resolves a set of component class names to this footprint's actual component class
void ResolveComponentClassNames( BOARD* aBoard,
const std::unordered_set<wxString>& aComponentClassNames );
/// Returns the component class for this footprint
const COMPONENT_CLASS* GetComponentClass() const { return m_componentClass; }
/// Used for display in the properties panel
wxString GetComponentClassAsString() const;
@ -1129,6 +1156,7 @@ private:
mutable std::mutex m_courtyard_cache_mutex;
const COMPONENT_CLASS* m_componentClass;
std::unordered_set<wxString> m_transientComponentClassNames;
};
#endif // FOOTPRINT_H

View File

@ -4879,13 +4879,10 @@ FOOTPRINT* PCB_IO_KICAD_SEXPR_PARSER::parseFOOTPRINT_unchecked( wxArrayString* a
NeedRIGHT();
}
footprint->SetTransientComponentClassNames( componentClassNames );
if( m_board )
{
const COMPONENT_CLASS* componentClass =
m_board->GetComponentClassManager().GetEffectiveComponentClass(
componentClassNames );
footprint->SetComponentClass( componentClass );
}
footprint->ResolveComponentClassNames( m_board, componentClassNames );
break;
}

View File

@ -1188,6 +1188,14 @@ int PCB_CONTROL::Paste( const TOOL_EVENT& aEvent )
}
else // isBoardEditor
{
// Fixup footprint component classes
for( FOOTPRINT* clipFootprint : clipBoard->Footprints() )
{
clipFootprint->ResolveComponentClassNames(
board(), clipFootprint->GetTransientComponentClassNames() );
clipFootprint->ClearTransientComponentClassNames();
}
if( mode == PASTE_MODE::REMOVE_ANNOTATIONS )
{
for( FOOTPRINT* clipFootprint : clipBoard->Footprints() )
@ -1217,6 +1225,9 @@ int PCB_CONTROL::Paste( const TOOL_EVENT& aEvent )
clipFootprint->SetReference( defaultRef );
clipFootprint->SetParent( board() );
clipFootprint->ResolveComponentClassNames(
board(), clipFootprint->GetTransientComponentClassNames() );
clipFootprint->ClearTransientComponentClassNames();
pastedItems.push_back( clipFootprint );
}