diff --git a/pcbnew/component_class_manager.cpp b/pcbnew/component_class_manager.cpp index 54535f22c8..b902970712 100644 --- a/pcbnew/component_class_manager.cpp +++ b/pcbnew/component_class_manager.cpp @@ -89,8 +89,8 @@ COMPONENT_CLASS_MANAGER::COMPONENT_CLASS_MANAGER() } -COMPONENT_CLASS* -COMPONENT_CLASS_MANAGER::GetEffectiveComponentClass( std::unordered_set& classNames ) +COMPONENT_CLASS* COMPONENT_CLASS_MANAGER::GetEffectiveComponentClass( + const std::unordered_set& 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& classNames ) +wxString COMPONENT_CLASS_MANAGER::GetFullClassNameForConstituents( + const std::unordered_set& classNames ) { std::vector sortedClassNames( classNames.begin(), classNames.end() ); @@ -193,7 +193,7 @@ COMPONENT_CLASS_MANAGER::GetFullClassNameForConstituents( std::unordered_set& classNames ) +COMPONENT_CLASS_MANAGER::GetFullClassNameForConstituents( const std::vector& classNames ) { if( classNames.size() == 0 ) return wxEmptyString; diff --git a/pcbnew/component_class_manager.h b/pcbnew/component_class_manager.h index 782e6c5ec7..327c0528c3 100644 --- a/pcbnew/component_class_manager.h +++ b/pcbnew/component_class_manager.h @@ -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& classNames ); + static wxString + GetFullClassNameForConstituents( const std::unordered_set& 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& classNames ); + static wxString GetFullClassNameForConstituents( const std::vector& 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& classNames ); + COMPONENT_CLASS* GetEffectiveComponentClass( const std::unordered_set& classNames ); /// Returns the unassigned component class const COMPONENT_CLASS* GetNoneComponentClass() const { return m_noneClass.get(); } diff --git a/pcbnew/footprint.cpp b/pcbnew/footprint.cpp index 1d38b35ffe..488258bc13 100644 --- a/pcbnew/footprint.cpp +++ b/pcbnew/footprint.cpp @@ -4035,6 +4035,15 @@ wxString FOOTPRINT::GetComponentClassAsString() const } +void FOOTPRINT::ResolveComponentClassNames( + BOARD* aBoard, const std::unordered_set& aComponentClassNames ) +{ + const COMPONENT_CLASS* componentClass = + aBoard->GetComponentClassManager().GetEffectiveComponentClass( aComponentClassNames ); + SetComponentClass( componentClass ); +} + + static struct FOOTPRINT_DESC { FOOTPRINT_DESC() diff --git a/pcbnew/footprint.h b/pcbnew/footprint.h index 61513b735a..c25950f69b 100644 --- a/pcbnew/footprint.h +++ b/pcbnew/footprint.h @@ -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& classNames ) + { + m_transientComponentClassNames = classNames; + } + + /// Gets the transient component class names + const std::unordered_set& 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& 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 m_transientComponentClassNames; }; #endif // FOOTPRINT_H diff --git a/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr_parser.cpp b/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr_parser.cpp index 691063965f..aa9803881a 100644 --- a/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr_parser.cpp +++ b/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr_parser.cpp @@ -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; } diff --git a/pcbnew/tools/pcb_control.cpp b/pcbnew/tools/pcb_control.cpp index 2c429bbe19..9d12ee8fc9 100644 --- a/pcbnew/tools/pcb_control.cpp +++ b/pcbnew/tools/pcb_control.cpp @@ -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 ); }