Preserve Uuids when editing board footprints.
One way to do this would have been to keep the Uuids in the editor copy. However, this opens us up to errors if we forget a Save As or export path and end up writing the Uuids out somewhere else. In the end, it felt safer to store a map of the original Uuids and restore them if we happen to save the editor footprint back to the board. Fixes https://gitlab.com/kicad/code/kicad/issues/7312
This commit is contained in:
parent
9ddfd82b91
commit
a868fb97b6
|
@ -520,7 +520,6 @@ void FOOTPRINT_EDIT_FRAME::LoadSettings( APP_SETTINGS_BASE* aCfg )
|
|||
GetDesignSettings() = cfg->m_DesignSettings;
|
||||
|
||||
m_displayOptions = cfg->m_Display;
|
||||
m_defaultLibWidth = cfg->m_LibWidth;
|
||||
|
||||
GetToolManager()->GetTool<PCB_SELECTION_TOOL>()->GetFilter() = cfg->m_SelectionFilter;
|
||||
m_selectionFilterPanel->SetCheckboxesFromFilter( cfg->m_SelectionFilter );
|
||||
|
|
|
@ -349,9 +349,7 @@ private:
|
|||
|
||||
std::unique_ptr<FOOTPRINT> m_revertModule;
|
||||
wxString m_footprintNameWhenLoaded;
|
||||
|
||||
int m_defaultLibWidth;
|
||||
|
||||
std::map<KIID, KIID> m_boardFootprintUuids;
|
||||
};
|
||||
|
||||
#endif // FOOTPRINT_EDIT_FRAME_H
|
||||
|
|
|
@ -46,7 +46,7 @@ void FOOTPRINT_EDIT_FRAME::LoadFootprintFromBoard( wxCommandEvent& event )
|
|||
}
|
||||
|
||||
|
||||
void FOOTPRINT_EDIT_FRAME::LoadFootprintFromLibrary( LIB_ID aFPID)
|
||||
void FOOTPRINT_EDIT_FRAME::LoadFootprintFromLibrary( LIB_ID aFPID )
|
||||
{
|
||||
bool is_last_fp_from_brd = IsCurrentFPFromBoard();
|
||||
|
||||
|
@ -243,8 +243,8 @@ void FOOTPRINT_EDIT_FRAME::SetActiveLayer( PCB_LAYER_ID aLayer )
|
|||
|
||||
bool FOOTPRINT_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl )
|
||||
{
|
||||
if( ! Clear_Pcb( true ) )
|
||||
return false; // //this command is aborted
|
||||
if( !Clear_Pcb( true ) )
|
||||
return false; // this command is aborted
|
||||
|
||||
GetCanvas()->GetViewControls()->SetCrossHairCursorPosition( VECTOR2D( 0, 0 ), false );
|
||||
ImportFootprint( aFileSet[ 0 ] );
|
||||
|
|
|
@ -862,20 +862,34 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprintToBoard( bool aAddNew )
|
|||
pcbframe->GetToolManager()->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||
BOARD_COMMIT commit( pcbframe );
|
||||
|
||||
// Create the "new" footprint
|
||||
FOOTPRINT* newFootprint = new FOOTPRINT( *editorFootprint );
|
||||
const_cast<KIID&>( newFootprint->m_Uuid ) = KIID();
|
||||
|
||||
// Create a copy for the board, first using Clone() to keep existing Uuids, and then either
|
||||
// resetting the uuids to the board values or assigning new Uuids.
|
||||
FOOTPRINT* newFootprint = static_cast<FOOTPRINT*>( editorFootprint->Clone() );
|
||||
newFootprint->SetParent( mainpcb );
|
||||
newFootprint->SetLink( niluuid );
|
||||
|
||||
auto fixUuid =
|
||||
[&]( KIID& aUuid )
|
||||
{
|
||||
if( editorFootprint->GetLink() != niluuid && m_boardFootprintUuids.count( aUuid ) )
|
||||
aUuid = m_boardFootprintUuids[ aUuid ];
|
||||
else
|
||||
aUuid = KIID();
|
||||
};
|
||||
|
||||
fixUuid( const_cast<KIID&>( newFootprint->m_Uuid ) );
|
||||
newFootprint->RunOnChildren(
|
||||
[&]( BOARD_ITEM* aChild )
|
||||
{
|
||||
fixUuid( const_cast<KIID&>( aChild->m_Uuid ) );
|
||||
} );
|
||||
|
||||
if( sourceFootprint ) // this is an update command
|
||||
{
|
||||
// In the main board the new footprint replaces the old one (pos, orient, ref, value,
|
||||
// connections and properties are kept) and the sourceFootprint (old footprint) is
|
||||
// deleted
|
||||
pcbframe->ExchangeFootprint( sourceFootprint, newFootprint, commit );
|
||||
const_cast<KIID&>( newFootprint->m_Uuid ) = editorFootprint->GetLink();
|
||||
commit.Push( wxT( "Update footprint" ) );
|
||||
}
|
||||
else // This is an insert command
|
||||
|
|
|
@ -96,6 +96,8 @@ bool FOOTPRINT_EDIT_FRAME::Clear_Pcb( bool aQuery )
|
|||
if( GetBoard() == NULL )
|
||||
return false;
|
||||
|
||||
bool is_last_fp_from_brd = IsCurrentFPFromBoard();
|
||||
|
||||
if( aQuery && IsContentModified() )
|
||||
{
|
||||
wxSafeYield( this, true ); // Allow frame to come to front before showing warning.
|
||||
|
@ -111,6 +113,9 @@ bool FOOTPRINT_EDIT_FRAME::Clear_Pcb( bool aQuery )
|
|||
}
|
||||
}
|
||||
|
||||
if( is_last_fp_from_brd )
|
||||
m_boardFootprintUuids.clear();
|
||||
|
||||
// Clear undo and redo lists because we want a full deletion
|
||||
ClearUndoRedoList();
|
||||
GetScreen()->ClrModify();
|
||||
|
|
|
@ -106,18 +106,31 @@ bool FOOTPRINT_EDIT_FRAME::LoadFootprintFromBoard( FOOTPRINT* aFootprint )
|
|||
if( !Clear_Pcb( true ) )
|
||||
return false;
|
||||
|
||||
newFootprint = (FOOTPRINT*) aFootprint->Duplicate();
|
||||
m_boardFootprintUuids.clear();
|
||||
|
||||
auto recordAndUpdateUuid =
|
||||
[&]( BOARD_ITEM* aItem )
|
||||
{
|
||||
KIID newId;
|
||||
m_boardFootprintUuids[ newId ] = aItem->m_Uuid;
|
||||
const_cast<KIID&>( aItem->m_Uuid ) = newId;
|
||||
};
|
||||
|
||||
newFootprint = (FOOTPRINT*) aFootprint->Clone(); // Keep existing uuids
|
||||
newFootprint->SetParent( GetBoard() );
|
||||
newFootprint->SetLink( aFootprint->m_Uuid );
|
||||
|
||||
newFootprint->ClearFlags();
|
||||
newFootprint->RunOnChildren( []( BOARD_ITEM* aItem )
|
||||
{
|
||||
if( aItem->Type() == PCB_PAD_T )
|
||||
aItem->SetLocked( false );
|
||||
recordAndUpdateUuid( newFootprint );
|
||||
newFootprint->RunOnChildren(
|
||||
[&]( BOARD_ITEM* aItem )
|
||||
{
|
||||
if( aItem->Type() == PCB_PAD_T )
|
||||
aItem->SetLocked( false );
|
||||
|
||||
aItem->ClearFlags();
|
||||
} );
|
||||
aItem->ClearFlags();
|
||||
recordAndUpdateUuid( aItem );
|
||||
} );
|
||||
|
||||
AddFootprintToBoard( newFootprint );
|
||||
|
||||
|
|
|
@ -1399,7 +1399,7 @@ void BOARD_EDITOR_CONTROL::setTransitions()
|
|||
|
||||
// Placing tools
|
||||
Go( &BOARD_EDITOR_CONTROL::PlaceTarget, PCB_ACTIONS::placeTarget.MakeEvent() );
|
||||
Go( &BOARD_EDITOR_CONTROL::PlaceFootprint, PCB_ACTIONS::placeFootprint.MakeEvent() );
|
||||
Go( &BOARD_EDITOR_CONTROL::PlaceFootprint, PCB_ACTIONS::placeFootprint.MakeEvent() );
|
||||
Go( &BOARD_EDITOR_CONTROL::DrillOrigin, PCB_ACTIONS::drillOrigin.MakeEvent() );
|
||||
|
||||
Go( &BOARD_EDITOR_CONTROL::EditFpInFpEditor, PCB_ACTIONS::editFpInFpEditor.MakeEvent() );
|
||||
|
|
|
@ -357,6 +357,8 @@ int FOOTPRINT_EDITOR_CONTROL::DeleteFootprint( const TOOL_EVENT& aEvent )
|
|||
|
||||
int FOOTPRINT_EDITOR_CONTROL::ImportFootprint( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
bool is_last_fp_from_brd = m_frame->IsCurrentFPFromBoard();
|
||||
|
||||
if( !m_frame->Clear_Pcb( true ) )
|
||||
return -1; // this command is aborted
|
||||
|
||||
|
@ -368,6 +370,13 @@ int FOOTPRINT_EDITOR_CONTROL::ImportFootprint( const TOOL_EVENT& aEvent )
|
|||
|
||||
frame()->ClearUndoRedoList();
|
||||
|
||||
// Update the save items if needed.
|
||||
if( is_last_fp_from_brd )
|
||||
{
|
||||
m_frame->ReCreateMenuBar();
|
||||
m_frame->ReCreateHToolbar();
|
||||
}
|
||||
|
||||
m_toolMgr->RunAction( ACTIONS::zoomFitScreen, true );
|
||||
m_frame->OnModify();
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue