modedit: Store single copy of the footprint in undo

When changing elements in the module editor, each element shares the
same parent.  Undo commits store a copy of the parent as it existed
before the change.  For footprints with many elements, this creates
large, slow undo commits as a copy of the full footprint is stored for
each element being edited.

This keeps a single copy of the footprint in the undo stack per edit.

Fixes: lp:1780526
* https://bugs.launchpad.net/kicad/+bug/1780526
This commit is contained in:
Seth Hillbrand 2018-07-30 21:52:21 -07:00
parent 80e7a83fb0
commit 016c02a42d
1 changed files with 42 additions and 10 deletions

View File

@ -463,14 +463,22 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
if( lockFlags == SELECTION_LOCKED )
break;
// Save items, so changes can be undone
for( auto item : selection )
// When editing modules, all items have the same parent
if( EditingModules() )
{
// Don't double move footprint pads, fields, etc.
if( item->GetParent() && item->GetParent()->IsSelected() )
continue;
m_commit->Modify( selection.Front() );
}
else
{
// Save items, so changes can be undone
for( auto item : selection )
{
// Don't double move footprint pads, fields, etc.
if( item->GetParent() && item->GetParent()->IsSelected() )
continue;
m_commit->Modify( item );
m_commit->Modify( item );
}
}
m_cursor = controls->GetCursorPosition();
@ -705,9 +713,15 @@ int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
updateModificationPoint( selection );
const int rotateAngle = TOOL_EVT_UTILS::GetEventRotationAngle( *editFrame, aEvent );
// When editing modules, all items have the same parent
if( EditingModules() )
{
m_commit->Modify( selection.Front() );
}
for( auto item : selection )
{
if( !item->IsNew() )
if( !item->IsNew() && !EditingModules() )
m_commit->Modify( item );
static_cast<BOARD_ITEM*>( item )->Rotate( selection.GetReferencePoint(), rotateAngle );
@ -777,6 +791,12 @@ int EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
auto refPoint = selection.GetReferencePoint();
wxPoint mirrorPoint( refPoint.x, refPoint.y );
// When editing modules, all items have the same parent
if( EditingModules() )
{
m_commit->Modify( selection.Front() );
}
for( auto item : selection )
{
// only modify items we can mirror
@ -786,7 +806,7 @@ int EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
case PCB_MODULE_TEXT_T:
case PCB_PAD_T:
// Only create undo entry for items on the board
if( !item->IsNew() )
if( !item->IsNew() && !EditingModules() )
m_commit->Modify( item );
break;
@ -850,9 +870,15 @@ int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent )
updateModificationPoint( selection );
auto modPoint = selection.GetReferencePoint();
// When editing modules, all items have the same parent
if( EditingModules() )
{
m_commit->Modify( selection.Front() );
}
for( auto item : selection )
{
if( !item->IsNew() )
if( !item->IsNew() && !EditingModules() )
m_commit->Modify( item );
static_cast<BOARD_ITEM*>( item )->Flip( modPoint );
@ -942,9 +968,15 @@ int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent )
// Make sure the rotation is from the right reference point
rotPoint += finalMoveVector;
// When editing modules, all items have the same parent
if( EditingModules() )
{
m_commit->Modify( selection.Front() );
}
for( auto item : selection )
{
if( !item->IsNew() )
if( !item->IsNew() && !EditingModules() )
m_commit->Modify( item );
static_cast<BOARD_ITEM*>( item )->Move( finalMoveVector );