From 016c02a42d89c1d54446d5d9e96e58c43d88d123 Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Mon, 30 Jul 2018 21:52:21 -0700 Subject: [PATCH] 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 --- pcbnew/tools/edit_tool.cpp | 52 ++++++++++++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index ad86f0725d..c6a4f9920b 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -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( 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( 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( item )->Move( finalMoveVector );