From ef6866757e516a2f8ee9fa84d3d4757f7a2c33f9 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Fri, 16 Jun 2023 21:44:16 +0100 Subject: [PATCH] Treat undo as backspace and/or escape when drawing. Ignore redo. Undo == backspace when drawing a polygon or chained lines. Otherwise it's an escape. Fixes https://gitlab.com/kicad/code/kicad/-/issues/14961 --- common/preview_items/polygon_geom_manager.cpp | 8 +++- eeschema/sch_edit_frame.cpp | 13 +++++- eeschema/tools/sch_drawing_tools.cpp | 36 +++++++++++++--- eeschema/tools/sch_line_wire_bus_tool.cpp | 6 ++- include/preview_items/polygon_geom_manager.h | 4 +- .../preview_items/two_point_geom_manager.h | 7 +--- include/tool/editor_conditions.h | 4 +- pcbnew/pcb_edit_frame.cpp | 13 +++++- pcbnew/tools/drawing_tool.cpp | 42 +++++++++++++++---- 9 files changed, 107 insertions(+), 26 deletions(-) diff --git a/common/preview_items/polygon_geom_manager.cpp b/common/preview_items/polygon_geom_manager.cpp index 59f3e908ea..126393586e 100644 --- a/common/preview_items/polygon_geom_manager.cpp +++ b/common/preview_items/polygon_geom_manager.cpp @@ -1,7 +1,7 @@ /* * This program source code file is part of KICAD, a free EDA CAD application. * - * Copyright (C) 2017-2022 Kicad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2017-2023 Kicad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -117,6 +117,12 @@ bool POLYGON_GEOM_MANAGER::IsPolygonInProgress() const } +int POLYGON_GEOM_MANAGER::PolygonPointCount() const +{ + return m_lockedPoints.PointCount(); +} + + bool POLYGON_GEOM_MANAGER::NewPointClosesOutline( const VECTOR2I& aPt ) const { return m_lockedPoints.PointCount() > 0 && m_lockedPoints.CPoint( 0 ) == aPt; diff --git a/eeschema/sch_edit_frame.cpp b/eeschema/sch_edit_frame.cpp index c020996890..852922f4c1 100644 --- a/eeschema/sch_edit_frame.cpp +++ b/eeschema/sch_edit_frame.cpp @@ -476,7 +476,7 @@ void SCH_EDIT_FRAME::setupUIConditions() { SCH_BASE_FRAME::setupUIConditions(); - ACTION_MANAGER* mgr = m_toolManager->GetActionManager(); + ACTION_MANAGER* mgr = m_toolManager->GetActionManager(); SCH_EDITOR_CONDITIONS cond( this ); wxASSERT( mgr ); @@ -506,11 +506,20 @@ void SCH_EDIT_FRAME::setupUIConditions() return m_auimgr.GetPane( NetNavigatorPaneName() ).IsShown(); }; + auto undoCond = + [ this ] (const SELECTION& aSel ) + { + if( SCH_LINE_WIRE_BUS_TOOL::IsDrawingLineWireOrBus( aSel ) ) + return true; + + return GetUndoCommandCount() > 0; + }; + #define ENABLE( x ) ACTION_CONDITIONS().Enable( x ) #define CHECK( x ) ACTION_CONDITIONS().Check( x ) mgr->SetConditions( ACTIONS::save, ENABLE( SELECTION_CONDITIONS::ShowAlways ) ); - mgr->SetConditions( ACTIONS::undo, ENABLE( cond.UndoAvailable() ) ); + mgr->SetConditions( ACTIONS::undo, ENABLE( undoCond ) ); mgr->SetConditions( ACTIONS::redo, ENABLE( cond.RedoAvailable() ) ); mgr->SetConditions( EE_ACTIONS::showSearch, CHECK( searchPaneCond ) ); diff --git a/eeschema/tools/sch_drawing_tools.cpp b/eeschema/tools/sch_drawing_tools.cpp index 788ae600e7..ecba87e45b 100644 --- a/eeschema/tools/sch_drawing_tools.cpp +++ b/eeschema/tools/sch_drawing_tools.cpp @@ -254,7 +254,7 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent ) bool isSyntheticClick = symbol && evt->IsActivate() && evt->HasPosition() && evt->Matches( aEvent ); - if( evt->IsCancelInteractive() ) + if( evt->IsCancelInteractive() || evt->IsAction( &ACTIONS::undo ) ) { m_frame->GetInfoBar()->Dismiss(); @@ -451,6 +451,10 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent ) { cleanup(); } + else if( evt->IsAction( &ACTIONS::redo ) ) + { + wxBell(); + } else { evt->SetPassEvent(); @@ -546,7 +550,7 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent ) bool isSyntheticClick = image && evt->IsActivate() && evt->HasPosition() && evt->Matches( aEvent ); - if( evt->IsCancelInteractive() ) + if( evt->IsCancelInteractive() || evt->IsAction( &ACTIONS::undo ) ) { m_frame->GetInfoBar()->Dismiss(); @@ -685,6 +689,10 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent ) { cleanup(); } + else if( evt->IsAction( &ACTIONS::redo ) ) + { + wxBell(); + } else { evt->SetPassEvent(); @@ -798,7 +806,7 @@ int SCH_DRAWING_TOOLS::SingleClickPlace( const TOOL_EVENT& aEvent ) cursorPos = grid.BestSnapAnchor( cursorPos, LAYER_CONNECTABLE, nullptr ); controls->ForceCursorPosition( true, cursorPos ); - if( evt->IsCancelInteractive() ) + if( evt->IsCancelInteractive() || evt->IsAction( &ACTIONS::undo ) ) { m_frame->PopTool( aEvent ); break; @@ -929,6 +937,10 @@ int SCH_DRAWING_TOOLS::SingleClickPlace( const TOOL_EVENT& aEvent ) evt->SetPassEvent(); } } + else if( evt->IsAction( &ACTIONS::redo ) ) + { + wxBell(); + } else { evt->SetPassEvent(); @@ -1244,7 +1256,7 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent ) } }; - if( evt->IsCancelInteractive() ) + if( evt->IsCancelInteractive() || evt->IsAction( &ACTIONS::undo ) ) { m_frame->GetInfoBar()->Dismiss(); @@ -1499,6 +1511,10 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent ) { cleanup(); } + else if( evt->IsAction( &ACTIONS::redo ) ) + { + wxBell(); + } else { evt->SetPassEvent(); @@ -1576,7 +1592,7 @@ int SCH_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent ) bool isSyntheticClick = item && evt->IsActivate() && evt->HasPosition() && evt->Matches( aEvent ); - if( evt->IsCancelInteractive() ) + if( evt->IsCancelInteractive() || evt->IsAction( &ACTIONS::undo ) ) { if( item ) { @@ -1725,6 +1741,10 @@ int SCH_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent ) m_menu.ShowContextMenu( m_selectionTool->GetSelection() ); } + else if( evt->IsAction( &ACTIONS::redo ) ) + { + wxBell(); + } else { evt->SetPassEvent(); @@ -1792,7 +1812,7 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent ) bool isSyntheticClick = sheet && evt->IsActivate() && evt->HasPosition() && evt->Matches( aEvent ); - if( evt->IsCancelInteractive() ) + if( evt->IsCancelInteractive() || evt->IsAction( &ACTIONS::undo ) ) { m_frame->GetInfoBar()->Dismiss(); @@ -1916,6 +1936,10 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent ) m_menu.ShowContextMenu( m_selectionTool->GetSelection() ); } + else if( evt->IsAction( &ACTIONS::redo ) ) + { + wxBell(); + } else { evt->SetPassEvent(); diff --git a/eeschema/tools/sch_line_wire_bus_tool.cpp b/eeschema/tools/sch_line_wire_bus_tool.cpp index 6ea2ebc061..4719033a69 100644 --- a/eeschema/tools/sch_line_wire_bus_tool.cpp +++ b/eeschema/tools/sch_line_wire_bus_tool.cpp @@ -892,7 +892,7 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( const TOOL_EVENT& aTool, int aType, m_view->AddToPreview( wire->Clone() ); } } - else if( evt->IsAction( &EE_ACTIONS::undoLastSegment ) ) + else if( evt->IsAction( &EE_ACTIONS::undoLastSegment ) || evt->IsAction( &ACTIONS::undo ) ) { if( ( currentMode == LINE_MODE::LINE_MODE_FREE && m_wires.size() > 1 ) || ( LINE_MODE::LINE_MODE_90 && m_wires.size() > 2 ) ) @@ -1005,6 +1005,10 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( const TOOL_EVENT& aTool, int aType, { cleanup(); } + else if( evt->IsAction( &ACTIONS::redo ) ) + { + wxBell(); + } else { evt->SetPassEvent(); diff --git a/include/preview_items/polygon_geom_manager.h b/include/preview_items/polygon_geom_manager.h index 4325a9755c..e8913f77a4 100644 --- a/include/preview_items/polygon_geom_manager.h +++ b/include/preview_items/polygon_geom_manager.h @@ -1,7 +1,7 @@ /* * This program source code file is part of KICAD, a free EDA CAD application. * - * Copyright (C) 2017-2022 Kicad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2017-2023 Kicad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -141,6 +141,8 @@ public: */ bool IsPolygonInProgress() const; + int PolygonPointCount() const; + /** * @return true if locking in the given point would close the current polygon. */ diff --git a/include/preview_items/two_point_geom_manager.h b/include/preview_items/two_point_geom_manager.h index 775d18b348..a7302830d7 100644 --- a/include/preview_items/two_point_geom_manager.h +++ b/include/preview_items/two_point_geom_manager.h @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2017-2021 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2017-2023 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -60,13 +60,10 @@ public: void SetEnd( const VECTOR2I& aEnd ) { if( m_angleSnap ) - { m_end = GetVectorSnapped45( aEnd - m_origin ) + m_origin; - } else - { m_end = aEnd; - } + setGeometryChanged(); } diff --git a/include/tool/editor_conditions.h b/include/tool/editor_conditions.h index f542f069ea..a3eacfdda9 100644 --- a/include/tool/editor_conditions.h +++ b/include/tool/editor_conditions.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2020 Ian McInerney - * Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -61,7 +61,7 @@ public: * * @return Functor testing if the undo queue has items. */ - SELECTION_CONDITION UndoAvailable(); + virtual SELECTION_CONDITION UndoAvailable(); /** * Create a functor that tests if there are any items in the redo queue. diff --git a/pcbnew/pcb_edit_frame.cpp b/pcbnew/pcb_edit_frame.cpp index b1d7366ad3..a05bd72327 100644 --- a/pcbnew/pcb_edit_frame.cpp +++ b/pcbnew/pcb_edit_frame.cpp @@ -681,13 +681,24 @@ void PCB_EDIT_FRAME::setupUIConditions() ACTION_MANAGER* mgr = m_toolManager->GetActionManager(); PCB_EDITOR_CONDITIONS cond( this ); + auto undoCond = + [ this ] (const SELECTION& aSel ) + { + DRAWING_TOOL* drawingTool = m_toolManager->GetTool(); + + if( drawingTool && drawingTool->GetDrawingMode() != DRAWING_TOOL::MODE::NONE ) + return true; + + return GetUndoCommandCount() > 0; + }; + wxASSERT( mgr ); #define ENABLE( x ) ACTION_CONDITIONS().Enable( x ) #define CHECK( x ) ACTION_CONDITIONS().Check( x ) mgr->SetConditions( ACTIONS::save, ENABLE( SELECTION_CONDITIONS::ShowAlways ) ); - mgr->SetConditions( ACTIONS::undo, ENABLE( cond.UndoAvailable() ) ); + mgr->SetConditions( ACTIONS::undo, ENABLE( undoCond ) ); mgr->SetConditions( ACTIONS::redo, ENABLE( cond.RedoAvailable() ) ); mgr->SetConditions( ACTIONS::toggleGrid, CHECK( cond.GridVisible() ) ); diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index cf5bc80101..94c93d14b5 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -599,7 +599,7 @@ int DRAWING_TOOL::PlaceImage( const TOOL_EVENT& aEvent ) COORDS_PADDING ); m_controls->ForceCursorPosition( true, cursorPos ); - if( evt->IsCancelInteractive() ) + if( evt->IsCancelInteractive() || evt->IsAction( &ACTIONS::undo ) ) { if( image ) { @@ -740,6 +740,10 @@ int DRAWING_TOOL::PlaceImage( const TOOL_EVENT& aEvent ) { wxBell(); } + else if( evt->IsAction( &ACTIONS::redo ) ) + { + wxBell(); + } else { evt->SetPassEvent(); @@ -831,7 +835,7 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent ) COORDS_PADDING ); m_controls->ForceCursorPosition( true, cursorPos ); - if( evt->IsCancelInteractive() ) + if( evt->IsCancelInteractive() || evt->IsAction( &ACTIONS::undo ) ) { if( text ) { @@ -995,6 +999,10 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent ) evt->SetPassEvent(); } } + else if( evt->IsAction( &ACTIONS::redo ) ) + { + wxBell(); + } else { evt->SetPassEvent(); @@ -1115,7 +1123,7 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent ) m_controls->ForceCursorPosition( true, cursorPos ); - if( evt->IsCancelInteractive() ) + if( evt->IsCancelInteractive() || evt->IsAction( &ACTIONS::undo ) ) { m_controls->SetAutoPan( false ); @@ -1440,6 +1448,10 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent ) { wxBell(); } + else if( evt->IsAction( &ACTIONS::redo ) ) + { + wxBell(); + } else { evt->SetPassEvent(); @@ -1851,7 +1863,7 @@ bool DRAWING_TOOL::drawShape( const TOOL_EVENT& aTool, PCB_SHAPE** aGraphic, COORDS_PADDING ); m_controls->ForceCursorPosition( true, cursorPos ); - if( evt->IsCancelInteractive() ) + if( evt->IsCancelInteractive() || evt->IsAction( &ACTIONS::undo ) ) { cleanup(); @@ -2066,6 +2078,10 @@ bool DRAWING_TOOL::drawShape( const TOOL_EVENT& aTool, PCB_SHAPE** aGraphic, m_view->Update( &preview ); frame()->SetMsgPanel( graphic ); } + else if( evt->IsAction( &ACTIONS::redo ) ) + { + wxBell(); + } else if( graphic && evt->IsAction( &PCB_ACTIONS::decWidth ) ) { if( (unsigned) m_stroke.GetWidth() > WIDTH_STEP ) @@ -2225,7 +2241,7 @@ bool DRAWING_TOOL::drawArc( const TOOL_EVENT& aTool, PCB_SHAPE** aGraphic, grid.BestSnapAnchor( m_controls->GetMousePosition(), graphic ), COORDS_PADDING ); m_controls->ForceCursorPosition( true, cursorPos ); - if( evt->IsCancelInteractive() ) + if( evt->IsCancelInteractive() || evt->IsAction( &ACTIONS::undo ) ) { cleanup(); @@ -2386,6 +2402,10 @@ bool DRAWING_TOOL::drawArc( const TOOL_EVENT& aTool, PCB_SHAPE** aGraphic, { wxBell(); } + else if( evt->IsAction( &ACTIONS::redo ) ) + { + wxBell(); + } else { evt->SetPassEvent(); @@ -2548,9 +2568,13 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent ) polyGeomMgr.SetLeaderMode( Is45Limited() ? POLYGON_GEOM_MANAGER::LEADER_MODE::DEG45 : POLYGON_GEOM_MANAGER::LEADER_MODE::DIRECT ); - if( evt->IsCancelInteractive() ) + if( evt->IsCancelInteractive() || evt->IsAction( &ACTIONS::undo ) ) { - if( polyGeomMgr.IsPolygonInProgress() ) + if( polyGeomMgr.PolygonPointCount() >= 2 && evt->IsAction( &ACTIONS::undo ) ) + { + polyGeomMgr.DeleteLastCorner(); + } + else if( polyGeomMgr.IsPolygonInProgress() ) { cleanup(); } @@ -2672,6 +2696,10 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent ) // m_view->Update( &zoneAsst ); evt->SetPassEvent(); }*/ + else if( evt->IsAction( &ACTIONS::redo ) ) + { + wxBell(); + } else { evt->SetPassEvent();