From 06e1e4c62c41fb15851a618c080c3ca03b5f7d6d Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Sun, 30 Nov 2025 12:23:23 +0000 Subject: [PATCH] Drawing tools must police their own handling of paste. Doing otherwise disables paste even when the tool is idle. Fixes https://gitlab.com/kicad/code/kicad/-/issues/22373 (cherry picked from commit b7c561b23228d5afc46311ff735143ea099f8634) --- eeschema/sch_edit_frame.cpp | 4 +- eeschema/tools/sch_drawing_tools.cpp | 64 ++++++++++++++++++++-------- 2 files changed, 48 insertions(+), 20 deletions(-) diff --git a/eeschema/sch_edit_frame.cpp b/eeschema/sch_edit_frame.cpp index 118ea3b0a1..52a50d9a43 100644 --- a/eeschema/sch_edit_frame.cpp +++ b/eeschema/sch_edit_frame.cpp @@ -638,8 +638,8 @@ void SCH_EDIT_FRAME::setupUIConditions() mgr->SetConditions( ACTIONS::cut, ENABLE( hasElements ) ); mgr->SetConditions( ACTIONS::copy, ENABLE( hasElements ) ); mgr->SetConditions( ACTIONS::copyAsText, ENABLE( hasElements ) ); - mgr->SetConditions( ACTIONS::paste, ENABLE( SELECTION_CONDITIONS::Idle && cond.NoActiveTool() ) ); - mgr->SetConditions( ACTIONS::pasteSpecial, ENABLE( SELECTION_CONDITIONS::Idle && cond.NoActiveTool() ) ); + mgr->SetConditions( ACTIONS::paste, ENABLE( SELECTION_CONDITIONS::Idle ) ); + mgr->SetConditions( ACTIONS::pasteSpecial, ENABLE( SELECTION_CONDITIONS::Idle ) ); mgr->SetConditions( ACTIONS::doDelete, ENABLE( hasElements ) ); mgr->SetConditions( ACTIONS::duplicate, ENABLE( hasElements ) ); mgr->SetConditions( ACTIONS::selectAll, ENABLE( hasElements ) ); diff --git a/eeschema/tools/sch_drawing_tools.cpp b/eeschema/tools/sch_drawing_tools.cpp index 12aec9fd7e..3eb16a70e8 100644 --- a/eeschema/tools/sch_drawing_tools.cpp +++ b/eeschema/tools/sch_drawing_tools.cpp @@ -512,17 +512,16 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent ) } } else if( evt->IsAction( &ACTIONS::duplicate ) - || evt->IsAction( &SCH_ACTIONS::repeatDrawItem ) ) + || evt->IsAction( &SCH_ACTIONS::repeatDrawItem ) + || evt->IsAction( &ACTIONS::paste ) ) { if( symbol ) { - // This doesn't really make sense; we'll just end up dragging a stack of - // objects so we ignore the duplicate and just carry on. wxBell(); continue; } - // Exit. The duplicate will run in its own loop. + // Exit. The duplicate/repeat/paste will run in its own loop. m_frame->PopTool( aEvent ); evt->SetPassEvent(); break; @@ -1139,7 +1138,8 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent ) m_menu->ShowContextMenu( m_selectionTool->GetSelection() ); } else if( evt->IsAction( &ACTIONS::duplicate ) - || evt->IsAction( &SCH_ACTIONS::repeatDrawItem ) ) + || evt->IsAction( &SCH_ACTIONS::repeatDrawItem ) + || evt->IsAction( &ACTIONS::paste ) ) { if( image ) { @@ -1149,7 +1149,7 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent ) continue; } - // Exit. The duplicate will run in its own loop. + // Exit. The duplicate/repeat/paste will run in its own loop. m_frame->PopTool( aEvent ); evt->SetPassEvent(); break; @@ -2206,17 +2206,16 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent ) evt->Parameter() ); } else if( evt->IsAction( &ACTIONS::duplicate ) - || evt->IsAction( &SCH_ACTIONS::repeatDrawItem ) ) + || evt->IsAction( &SCH_ACTIONS::repeatDrawItem ) + || evt->IsAction( &ACTIONS::paste ) ) { if( item ) { - // This doesn't really make sense; we'll just end up dragging a stack of - // objects so we ignore the duplicate and just carry on. wxBell(); continue; } - // Exit. The duplicate will run in its own loop. + // Exit. The duplicate/repeat/paste will run in its own loop. m_frame->PopTool( aEvent ); evt->SetPassEvent(); break; @@ -2492,17 +2491,17 @@ int SCH_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent ) m_toolMgr->PostAction( ACTIONS::activatePointEditor ); } } - else if( evt->IsAction( &ACTIONS::duplicate ) || evt->IsAction( &SCH_ACTIONS::repeatDrawItem ) ) + else if( evt->IsAction( &ACTIONS::duplicate ) + || evt->IsAction( &SCH_ACTIONS::repeatDrawItem ) + || evt->IsAction( &ACTIONS::paste ) ) { if( item ) { - // This doesn't really make sense; we'll just end up dragging a stack of - // objects so we ignore the duplicate and just carry on. wxBell(); continue; } - // Exit. The duplicate will run in its own loop. + // Exit. The duplicate/repeat/paste will run in its own loop. m_frame->PopTool( aEvent ); evt->SetPassEvent(); break; @@ -2706,6 +2705,21 @@ int SCH_DRAWING_TOOLS::DrawRuleArea( const TOOL_EVENT& aEvent ) { polyGeomMgr.SetCursorPosition( cursorPos ); } + else if( evt->IsAction( &ACTIONS::duplicate ) + || evt->IsAction( &SCH_ACTIONS::repeatDrawItem ) + || evt->IsAction( &ACTIONS::paste ) ) + { + if( started ) + { + wxBell(); + continue; + } + + // Exit. The duplicate/repeat/paste will run in its own loop. + m_frame->PopTool( aEvent ); + evt->SetPassEvent(); + break; + } else { evt->SetPassEvent(); @@ -2926,6 +2940,21 @@ int SCH_DRAWING_TOOLS::DrawTable( const TOOL_EVENT& aEvent ) m_menu->ShowContextMenu( m_selectionTool->GetSelection() ); } + else if( evt->IsAction( &ACTIONS::duplicate ) + || evt->IsAction( &SCH_ACTIONS::repeatDrawItem ) + || evt->IsAction( &ACTIONS::paste ) ) + { + if( table ) + { + wxBell(); + continue; + } + + // Exit. The duplicate/repeat/paste will run in its own loop. + m_frame->PopTool( aEvent ); + evt->SetPassEvent(); + break; + } else if( table && evt->IsAction( &ACTIONS::redo ) ) { wxBell(); @@ -3214,17 +3243,16 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent ) sheet = nullptr; } else if( evt->IsAction( &ACTIONS::duplicate ) - || evt->IsAction( &SCH_ACTIONS::repeatDrawItem ) ) + || evt->IsAction( &SCH_ACTIONS::repeatDrawItem ) + || evt->IsAction( &ACTIONS::paste ) ) { if( sheet ) { - // This doesn't really make sense; we'll just end up dragging a stack of - // objects so we ignore the duplicate and just carry on. wxBell(); continue; } - // Exit. The duplicate will run in its own loop. + // Exit. The duplicate/repeat/paste will run in its own loop. m_frame->PopTool( aEvent ); evt->SetPassEvent(); break;