From a69869f72afb9d96788db4d66f45836cbf40f580 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Fri, 13 Oct 2023 13:51:27 +0100 Subject: [PATCH] Simplify undo/redo for pad edit mode. Also simplifies high-contrast-mode handling to fix a bug when exiting pad edit mode via an undo. Fixes https://gitlab.com/kicad/code/kicad/-/issues/15845 --- pcbnew/graphics_cleaner.cpp | 5 ++- pcbnew/tools/pad_tool.cpp | 74 ++++++++++++++++++------------------- pcbnew/tools/pad_tool.h | 11 +++--- 3 files changed, 44 insertions(+), 46 deletions(-) diff --git a/pcbnew/graphics_cleaner.cpp b/pcbnew/graphics_cleaner.cpp index df7b3244df..200313f252 100644 --- a/pcbnew/graphics_cleaner.cpp +++ b/pcbnew/graphics_cleaner.cpp @@ -356,7 +356,10 @@ void GRAPHICS_CLEANER::mergePads() if( padToNetTieGroupMap[ pad->GetNumber() ] >= 0 ) continue; - std::vector shapes = padTool->RecombinePad( pad, m_dryRun, m_commit ); + if( m_commit.GetStatus( m_parentFootprint ) == 0 ) + m_commit.Modify( m_parentFootprint ); + + std::vector shapes = padTool->RecombinePad( pad, m_dryRun ); if( !shapes.empty() ) { diff --git a/pcbnew/tools/pad_tool.cpp b/pcbnew/tools/pad_tool.cpp index a804641404..3f90a864c5 100644 --- a/pcbnew/tools/pad_tool.cpp +++ b/pcbnew/tools/pad_tool.cpp @@ -51,7 +51,7 @@ using KIGFX::PCB_RENDER_SETTINGS; PAD_TOOL::PAD_TOOL() : PCB_TOOL_BASE( "pcbnew.PadTool" ), - m_wasHighContrast( false ), + m_previousHighContrastMode( HIGH_CONTRAST_MODE::NORMAL ), m_editPad( niluuid ) {} @@ -68,10 +68,12 @@ void PAD_TOOL::Reset( RESET_REASON aReason ) if( board() && board()->GetItem( m_editPad ) == DELETED_BOARD_ITEM::GetInstance() ) { PCB_DISPLAY_OPTIONS opts = frame()->GetDisplayOptions(); - bool highContrast = ( opts.m_ContrastModeDisplay != HIGH_CONTRAST_MODE::NORMAL ); - if( m_wasHighContrast != highContrast ) - m_toolMgr->RunAction( ACTIONS::highContrastMode ); + if( m_previousHighContrastMode != opts.m_ContrastModeDisplay ) + { + opts.m_ContrastModeDisplay = m_previousHighContrastMode; + frame()->SetDisplayOptions( opts ); + } frame()->GetInfoBar()->Dismiss(); @@ -615,7 +617,6 @@ int PAD_TOOL::EditPad( const TOOL_EVENT& aEvent ) Activate(); - PCB_DISPLAY_OPTIONS opts = frame()->GetDisplayOptions(); KIGFX::PCB_PAINTER* painter = static_cast( view()->GetPainter() ); PCB_RENDER_SETTINGS* settings = painter->GetSettings(); PCB_SELECTION& selection = m_toolMgr->GetTool()->GetSelection(); @@ -627,20 +628,24 @@ int PAD_TOOL::EditPad( const TOOL_EVENT& aEvent ) if( pad ) { BOARD_COMMIT commit( frame() ); - RecombinePad( pad, false, commit ); - commit.Push( _( "Recombine pad" ) ); + commit.Modify( pad->GetParentFootprint() ); + RecombinePad( pad, false ); + commit.Push( _( "Edit Pad" ) ); } m_editPad = niluuid; } else if( selection.Size() == 1 && selection[0]->Type() == PCB_PAD_T ) { + PCB_LAYER_ID layer; PAD* pad = static_cast( selection[0] ); - PCB_LAYER_ID layer = explodePad( pad ); + BOARD_COMMIT commit( frame() ); - m_editPad = pad->m_Uuid; + commit.Modify( pad->GetParentFootprint() ); + explodePad( pad, &layer ); + commit.Push( _( "Edit Pad" ) ); - m_wasHighContrast = ( opts.m_ContrastModeDisplay != HIGH_CONTRAST_MODE::NORMAL ); + m_toolMgr->RunAction( PCB_ACTIONS::selectionClear ); frame()->SetActiveLayer( layer ); settings->m_PadEditModePad = pad; @@ -696,7 +701,6 @@ int PAD_TOOL::OnUndoRedo( const TOOL_EVENT& aEvent ) void PAD_TOOL::enterPadEditMode() { PCB_DISPLAY_OPTIONS opts = frame()->GetDisplayOptions(); - bool highContrast = opts.m_ContrastModeDisplay != HIGH_CONTRAST_MODE::NORMAL; WX_INFOBAR* infoBar = frame()->GetInfoBar(); wxString msg; @@ -706,8 +710,13 @@ void PAD_TOOL::enterPadEditMode() return dynamic_cast( aItem ) != nullptr; } ); - if( !highContrast ) - m_toolMgr->RunAction( ACTIONS::highContrastMode ); + m_previousHighContrastMode = opts.m_ContrastModeDisplay; + + if( opts.m_ContrastModeDisplay == HIGH_CONTRAST_MODE::NORMAL ) + { + opts.m_ContrastModeDisplay = HIGH_CONTRAST_MODE::DIMMED; + frame()->SetDisplayOptions( opts ); + } if( PCB_ACTIONS::explodePad.GetHotKey() == PCB_ACTIONS::recombinePad.GetHotKey() ) { @@ -728,10 +737,12 @@ void PAD_TOOL::enterPadEditMode() void PAD_TOOL::exitPadEditMode() { PCB_DISPLAY_OPTIONS opts = frame()->GetDisplayOptions(); - bool highContrast = opts.m_ContrastModeDisplay != HIGH_CONTRAST_MODE::NORMAL; - if( m_wasHighContrast != highContrast ) - m_toolMgr->RunAction( ACTIONS::highContrastMode ); + if( m_previousHighContrastMode != opts.m_ContrastModeDisplay ) + { + opts.m_ContrastModeDisplay = m_previousHighContrastMode; + frame()->SetDisplayOptions( opts ); + } // Note: KIGFX::REPAINT isn't enough for things that go from invisible to visible as // they won't be found in the view layer's itemset for re-painting. @@ -749,22 +760,17 @@ void PAD_TOOL::exitPadEditMode() } -PCB_LAYER_ID PAD_TOOL::explodePad( PAD* aPad ) +void PAD_TOOL::explodePad( PAD* aPad, PCB_LAYER_ID* aLayer ) { - PCB_LAYER_ID layer; - BOARD_COMMIT commit( frame() ); - if( aPad->IsOnLayer( F_Cu ) ) - layer = F_Cu; + *aLayer = F_Cu; else if( aPad->IsOnLayer( B_Cu ) ) - layer = B_Cu; + *aLayer = B_Cu; else - layer = *aPad->GetLayerSet().UIOrder(); + *aLayer = *aPad->GetLayerSet().UIOrder(); if( aPad->GetShape() == PAD_SHAPE::CUSTOM ) { - commit.Modify( aPad ); - for( const std::shared_ptr& primitive : aPad->GetPrimitives() ) { PCB_SHAPE* shape = static_cast( primitive->Duplicate() ); @@ -772,7 +778,7 @@ PCB_LAYER_ID PAD_TOOL::explodePad( PAD* aPad ) shape->SetParent( board()->GetFirstFootprint() ); shape->Rotate( VECTOR2I( 0, 0 ), aPad->GetOrientation() ); shape->Move( aPad->ShapePos() ); - shape->SetLayer( layer ); + shape->SetLayer( *aLayer ); if( shape->IsProxyItem() && shape->GetShape() == SHAPE_T::SEGMENT ) { @@ -782,7 +788,8 @@ PCB_LAYER_ID PAD_TOOL::explodePad( PAD* aPad ) shape->SetWidth( pcbIUScale.mmToIU( ZONE_THERMAL_RELIEF_COPPER_WIDTH_MM ) ); } - commit.Add( shape ); + board()->GetFirstFootprint()->Add( shape ); + frame()->GetCanvas()->GetView()->Add( shape ); } aPad->SetShape( aPad->GetAnchorPadShape() ); @@ -791,14 +798,10 @@ PCB_LAYER_ID PAD_TOOL::explodePad( PAD* aPad ) aPad->SetFlags( ENTERED ); m_editPad = aPad->m_Uuid; - - commit.Push( _("Edit pad shapes") ); - m_toolMgr->RunAction( PCB_ACTIONS::selectionClear ); - return layer; } -std::vector PAD_TOOL::RecombinePad( PAD* aPad, bool aIsDryRun, BOARD_COMMIT& aCommit ) +std::vector PAD_TOOL::RecombinePad( PAD* aPad, bool aIsDryRun ) { int maxError = board()->GetDesignSettings().m_MaxError; FOOTPRINT* footprint = aPad->GetParentFootprint(); @@ -875,8 +878,6 @@ std::vector PAD_TOOL::RecombinePad( PAD* aPad, bool aIsDryRun, BOARD // custom-shape pad. if( !aIsDryRun && findNext( layer ) && aPad->GetShape() != PAD_SHAPE::CUSTOM ) { - aCommit.Modify( aPad ); - if( aPad->GetShape() == PAD_SHAPE::CIRCLE || aPad->GetShape() == PAD_SHAPE::RECTANGLE ) { // Use the existing pad as an anchor @@ -919,8 +920,6 @@ std::vector PAD_TOOL::RecombinePad( PAD* aPad, bool aIsDryRun, BOARD primitive->Rotate( VECTOR2I( 0, 0 ), - aPad->GetOrientation() ); aPad->AddPrimitive( primitive ); - - aCommit.Remove( fpShape ); } // See if there are other shapes that match and mark them for delete. (KiCad won't @@ -929,9 +928,6 @@ std::vector PAD_TOOL::RecombinePad( PAD* aPad, bool aIsDryRun, BOARD { other->SetFlags( SKIP_STRUCT ); mergedShapes.push_back( other ); - - if( !aIsDryRun ) - aCommit.Remove( other ); } } diff --git a/pcbnew/tools/pad_tool.h b/pcbnew/tools/pad_tool.h index 3fb6f6c4fb..8d807b4e0b 100644 --- a/pcbnew/tools/pad_tool.h +++ b/pcbnew/tools/pad_tool.h @@ -71,10 +71,9 @@ public: * Recombine an exploded pad (or one produced with overlapping polygons in an older version). * @param aPad the pad to run the recombination algorithm on * @param aIsDryRun if true the list will be generated but no changes will be made - * @param aCommit the commit to add any changes to * @return a list of PCB_SHAPEs that will be combined */ - std::vector RecombinePad( PAD* aPad, bool aIsDryRun, BOARD_COMMIT& aCommit ); + std::vector RecombinePad( PAD* aPad, bool aIsDryRun ); private: ///< Bind handlers to corresponding TOOL_ACTIONs. @@ -89,16 +88,16 @@ private: ///< Push pad settings from a pad to other pads on board or footprint. int pushPadSettings( const TOOL_EVENT& aEvent ); - PCB_LAYER_ID explodePad( PAD* aPad ); + void explodePad( PAD* aPad, PCB_LAYER_ID* aLayer ); void enterPadEditMode(); void exitPadEditMode(); private: - wxString m_lastPadNumber; + wxString m_lastPadNumber; - bool m_wasHighContrast; - KIID m_editPad; + HIGH_CONTRAST_MODE m_previousHighContrastMode; + KIID m_editPad; }; #endif // __PAD_TOOL_H