Fp editor: do not change item UUIDs when loading a footprint from library.

Fixes #8066
https://gitlab.com/kicad/code/kicad/issues/8066
This commit is contained in:
jean-pierre charras 2021-03-30 11:38:03 +02:00
parent 78a60e9dfb
commit 6eb2e2a6e3
14 changed files with 59 additions and 16 deletions

View File

@ -365,13 +365,14 @@ bool FP_LIB_TABLE::FootprintExists( const wxString& aNickname, const wxString& a
} }
FOOTPRINT* FP_LIB_TABLE::FootprintLoad( const wxString& aNickname, const wxString& aFootprintName ) FOOTPRINT* FP_LIB_TABLE::FootprintLoad( const wxString& aNickname,
const wxString& aFootprintName, bool aKeepUUID )
{ {
const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true ); const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
wxASSERT( (PLUGIN*) row->plugin ); wxASSERT( (PLUGIN*) row->plugin );
FOOTPRINT* ret = row->plugin->FootprintLoad( row->GetFullURI( true ), aFootprintName, FOOTPRINT* ret = row->plugin->FootprintLoad( row->GetFullURI( true ), aFootprintName,
row->GetProperties() ); aKeepUUID, row->GetProperties() );
setLibNickname( ret, row->GetNickName(), aFootprintName ); setLibNickname( ret, row->GetNickName(), aFootprintName );
@ -439,14 +440,15 @@ void FP_LIB_TABLE::FootprintLibCreate( const wxString& aNickname )
} }
FOOTPRINT* FP_LIB_TABLE::FootprintLoadWithOptionalNickname( const LIB_ID& aFootprintId ) FOOTPRINT* FP_LIB_TABLE::FootprintLoadWithOptionalNickname( const LIB_ID& aFootprintId,
bool aKeepUUID )
{ {
wxString nickname = aFootprintId.GetLibNickname(); wxString nickname = aFootprintId.GetLibNickname();
wxString fpname = aFootprintId.GetLibItemName(); wxString fpname = aFootprintId.GetLibItemName();
if( nickname.size() ) if( nickname.size() )
{ {
return FootprintLoad( nickname, fpname ); return FootprintLoad( nickname, fpname, aKeepUUID );
} }
// nickname is empty, sequentially search (alphabetically) all libs/nicks for first match: // nickname is empty, sequentially search (alphabetically) all libs/nicks for first match:
@ -459,7 +461,7 @@ FOOTPRINT* FP_LIB_TABLE::FootprintLoadWithOptionalNickname( const LIB_ID& aFootp
{ {
// FootprintLoad() returns NULL on not found, does not throw exception // FootprintLoad() returns NULL on not found, does not throw exception
// unless there's an IO_ERROR. // unless there's an IO_ERROR.
FOOTPRINT* ret = FootprintLoad( nicks[i], fpname ); FOOTPRINT* ret = FootprintLoad( nicks[i], fpname, aKeepUUID );
if( ret ) if( ret )
return ret; return ret;

View File

@ -168,12 +168,16 @@ public:
* *
* @param aNickname is a locator for the "library", it is a "name" in #LIB_TABLE_ROW. * @param aNickname is a locator for the "library", it is a "name" in #LIB_TABLE_ROW.
* @param aFootprintName is the name of the footprint to load. * @param aFootprintName is the name of the footprint to load.
* @param aKeepUUID = true to keep initial items UUID, false to set new UUID
* normally true if loaded in the footprint editor, false
* if loaded in the board editor. Used only in kicad_plugin
* @return the footprint if found caller owns it, else NULL if not found. * @return the footprint if found caller owns it, else NULL if not found.
* *
* @throw IO_ERROR if the library cannot be found or read. No exception * @throw IO_ERROR if the library cannot be found or read. No exception
* is thrown in the case where aFootprintName cannot be found. * is thrown in the case where aFootprintName cannot be found.
*/ */
FOOTPRINT* FootprintLoad( const wxString& aNickname, const wxString& aFootprintName ); FOOTPRINT* FootprintLoad( const wxString& aNickname, const wxString& aFootprintName,
bool aKeepUUID = false );
/** /**
* Indicates whether or not the given footprint already exists in the given library. * Indicates whether or not the given footprint already exists in the given library.
@ -241,13 +245,18 @@ public:
* Load a footprint having @a aFootprintId with possibly an empty nickname. * Load a footprint having @a aFootprintId with possibly an empty nickname.
* *
* @param aFootprintId the [nickname] and footprint name of the footprint to load. * @param aFootprintId the [nickname] and footprint name of the footprint to load.
* @param aKeepUUID = true to keep initial items UUID, false to set new UUID
* normally true if loaded in the footprint editor, false
* if loaded in the board editor
* used only in kicad_plugin
* @return the #FOOTPRINT if found caller owns it, else NULL if not found. * @return the #FOOTPRINT if found caller owns it, else NULL if not found.
* *
* @throw IO_ERROR if the library cannot be found or read. No exception is * @throw IO_ERROR if the library cannot be found or read. No exception is
* thrown in the case where \a aFootprintName cannot be found. * thrown in the case where \a aFootprintName cannot be found.
* @throw PARSE_ERROR if @a aFootprintId is not parsed OK. * @throw PARSE_ERROR if @a aFootprintId is not parsed OK.
*/ */
FOOTPRINT* FootprintLoadWithOptionalNickname( const LIB_ID& aFootprintId ); FOOTPRINT* FootprintLoadWithOptionalNickname( const LIB_ID& aFootprintId,
bool aKeepUUID = false );
/** /**
* Load the global footprint library table into \a aTable. * Load the global footprint library table into \a aTable.

View File

@ -395,12 +395,17 @@ public:
* is known to support. The caller continues to own this object * is known to support. The caller continues to own this object
* (plugin may not delete it), and plugins should expect it to be * (plugin may not delete it), and plugins should expect it to be
* optionally NULL. * optionally NULL.
* @param aKeepUUID = true to keep initial items UUID, false to set new UUID
* normally true if loaded in the footprint editor, false
* if loaded in the board editor. Make sense only in kicad_plugin
* @return the #FOOTPRINT object if found caller owns it, else NULL if not found. * @return the #FOOTPRINT object if found caller owns it, else NULL if not found.
* *
* @throw IO_ERROR if the library cannot be found or read. No exception is thrown in * @throw IO_ERROR if the library cannot be found or read. No exception is thrown in
* the case where \a aFootprintName cannot be found. * the case where \a aFootprintName cannot be found.
*/ */
virtual FOOTPRINT* FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName, virtual FOOTPRINT* FootprintLoad( const wxString& aLibraryPath,
const wxString& aFootprintName,
bool aKeepUUID = false,
const PROPERTIES* aProperties = nullptr ); const PROPERTIES* aProperties = nullptr );
/** /**

View File

@ -333,9 +333,13 @@ FOOTPRINT* PCB_BASE_FRAME::loadFootprint( const LIB_ID& aFootprintId )
FOOTPRINT *footprint = nullptr; FOOTPRINT *footprint = nullptr;
// When loading a footprint from a library in the footprint editor
// the items UUIDs must be keep and not reinitialized
bool keepUUID = IsType( FRAME_FOOTPRINT_EDITOR );
try try
{ {
footprint = fptbl->FootprintLoadWithOptionalNickname( aFootprintId ); footprint = fptbl->FootprintLoadWithOptionalNickname( aFootprintId, keepUUID );
} }
catch( const IO_ERROR& ) catch( const IO_ERROR& )
{ {

View File

@ -941,6 +941,10 @@ void PAD::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>&
aList.emplace_back( wxString::Format( _( "Min Clearance: %s" ), aList.emplace_back( wxString::Format( _( "Min Clearance: %s" ),
MessageTextFromValue( units, clearance ) ), MessageTextFromValue( units, clearance ) ),
wxString::Format( _( "(from %s)" ), source ) ); wxString::Format( _( "(from %s)" ), source ) );
#if 0
// useful for debug only
aList.emplace_back( "UUID", m_Uuid.AsString() );
#endif
} }

View File

@ -84,7 +84,7 @@ const FOOTPRINT* PLUGIN::GetEnumeratedFootprint( const wxString& aLibraryPath,
const PROPERTIES* aProperties ) const PROPERTIES* aProperties )
{ {
// default implementation // default implementation
return FootprintLoad( aLibraryPath, aFootprintName, aProperties ); return FootprintLoad( aLibraryPath, aFootprintName, false, aProperties );
} }
@ -92,11 +92,13 @@ bool PLUGIN::FootprintExists( const wxString& aLibraryPath, const wxString& aFoo
const PROPERTIES* aProperties ) const PROPERTIES* aProperties )
{ {
// default implementation // default implementation
return FootprintLoad( aLibraryPath, aFootprintName, aProperties ) != nullptr; return FootprintLoad( aLibraryPath, aFootprintName, true, aProperties ) != nullptr;
} }
FOOTPRINT* PLUGIN::FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName, FOOTPRINT* PLUGIN::FootprintLoad( const wxString& aLibraryPath,
const wxString& aFootprintName,
bool aKeepUUID,
const PROPERTIES* aProperties ) const PROPERTIES* aProperties )
{ {
// not pure virtual so that plugins only have to implement subset of the PLUGIN interface. // not pure virtual so that plugins only have to implement subset of the PLUGIN interface.

View File

@ -2852,6 +2852,7 @@ void EAGLE_PLUGIN::FootprintEnumerate( wxArrayString& aFootprintNames, const wxS
FOOTPRINT* EAGLE_PLUGIN::FootprintLoad( const wxString& aLibraryPath, FOOTPRINT* EAGLE_PLUGIN::FootprintLoad( const wxString& aLibraryPath,
const wxString& aFootprintName, const wxString& aFootprintName,
bool aKeepUUID,
const PROPERTIES* aProperties ) const PROPERTIES* aProperties )
{ {
init( aProperties ); init( aProperties );

View File

@ -141,6 +141,7 @@ public:
bool aBestEfforts, const PROPERTIES* aProperties = nullptr) override; bool aBestEfforts, const PROPERTIES* aProperties = nullptr) override;
FOOTPRINT* FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName, FOOTPRINT* FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName,
bool aKeepUUID = false,
const PROPERTIES* aProperties = nullptr ) override; const PROPERTIES* aProperties = nullptr ) override;
long long GetLibraryTimestamp( const wxString& aLibraryPath ) const override long long GetLibraryTimestamp( const wxString& aLibraryPath ) const override

View File

@ -931,6 +931,7 @@ const FOOTPRINT* GPCB_PLUGIN::GetEnumeratedFootprint( const wxString& aLibraryPa
FOOTPRINT* GPCB_PLUGIN::FootprintLoad( const wxString& aLibraryPath, FOOTPRINT* GPCB_PLUGIN::FootprintLoad( const wxString& aLibraryPath,
const wxString& aFootprintName, const wxString& aFootprintName,
bool aKeepUUID,
const PROPERTIES* aProperties ) const PROPERTIES* aProperties )
{ {
const FOOTPRINT* footprint = getFootprint( aLibraryPath, aFootprintName, aProperties, true ); const FOOTPRINT* footprint = getFootprint( aLibraryPath, aFootprintName, aProperties, true );

View File

@ -57,13 +57,15 @@ public:
} }
void FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aLibraryPath, void FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aLibraryPath,
bool aBestEfforts, const PROPERTIES* aProperties = nullptr ) override; bool aBestEfforts,
const PROPERTIES* aProperties = nullptr ) override;
const FOOTPRINT* GetEnumeratedFootprint( const wxString& aLibraryPath, const FOOTPRINT* GetEnumeratedFootprint( const wxString& aLibraryPath,
const wxString& aFootprintName, const wxString& aFootprintName,
const PROPERTIES* aProperties = nullptr ) override; const PROPERTIES* aProperties = nullptr ) override;
FOOTPRINT* FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName, FOOTPRINT* FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName,
bool aKeepUUID = false,
const PROPERTIES* aProperties = nullptr ) override; const PROPERTIES* aProperties = nullptr ) override;
void FootprintDelete( const wxString& aLibraryPath, const wxString& aFootprintName, void FootprintDelete( const wxString& aLibraryPath, const wxString& aFootprintName,

View File

@ -2301,14 +2301,22 @@ bool PCB_IO::FootprintExists( const wxString& aLibraryPath, const wxString& aFoo
} }
FOOTPRINT* PCB_IO::FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName, FOOTPRINT* PCB_IO::FootprintLoad( const wxString& aLibraryPath,
const wxString& aFootprintName,
bool aKeepUUID,
const PROPERTIES* aProperties ) const PROPERTIES* aProperties )
{ {
const FOOTPRINT* footprint = getFootprint( aLibraryPath, aFootprintName, aProperties, true ); const FOOTPRINT* footprint = getFootprint( aLibraryPath, aFootprintName, aProperties, true );
if( footprint ) if( footprint )
{ {
FOOTPRINT* copy = static_cast<FOOTPRINT*>( footprint->Duplicate() ); FOOTPRINT* copy;
if( aKeepUUID )
copy = static_cast<FOOTPRINT*>( footprint->Clone() );
else
copy = static_cast<FOOTPRINT*>( footprint->Duplicate() );
copy->SetParent( nullptr ); copy->SetParent( nullptr );
return copy; return copy;
} }

View File

@ -166,6 +166,7 @@ public:
const PROPERTIES* aProperties = nullptr ) override; const PROPERTIES* aProperties = nullptr ) override;
FOOTPRINT* FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName, FOOTPRINT* FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName,
bool aKeepUUID = false,
const PROPERTIES* aProperties = nullptr ) override; const PROPERTIES* aProperties = nullptr ) override;
void FootprintSave( const wxString& aLibraryPath, const FOOTPRINT* aFootprint, void FootprintSave( const wxString& aLibraryPath, const FOOTPRINT* aFootprint,

View File

@ -3296,6 +3296,7 @@ void LEGACY_PLUGIN::FootprintEnumerate( wxArrayString& aFootprintNames, const wx
FOOTPRINT* LEGACY_PLUGIN::FootprintLoad( const wxString& aLibraryPath, FOOTPRINT* LEGACY_PLUGIN::FootprintLoad( const wxString& aLibraryPath,
const wxString& aFootprintName, const wxString& aFootprintName,
bool aKeepUUID,
const PROPERTIES* aProperties ) const PROPERTIES* aProperties )
{ {
LOCALE_IO toggle; // toggles on, then off, the C locale. LOCALE_IO toggle; // toggles on, then off, the C locale.

View File

@ -80,9 +80,11 @@ public:
const PROPERTIES* aProperties = nullptr, PROJECT* aProject = nullptr ) override; const PROPERTIES* aProperties = nullptr, PROJECT* aProject = nullptr ) override;
void FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aLibraryPath, void FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aLibraryPath,
bool aBestEfforts, const PROPERTIES* aProperties = nullptr ) override; bool aBestEfforts,
const PROPERTIES* aProperties = nullptr ) override;
FOOTPRINT* FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName, FOOTPRINT* FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName,
bool aKeepUUID = false,
const PROPERTIES* aProperties = nullptr ) override; const PROPERTIES* aProperties = nullptr ) override;
bool FootprintLibDelete( const wxString& aLibraryPath, bool FootprintLibDelete( const wxString& aLibraryPath,