From d24a2afaca7e8b99ca4f938638fe644afc9db5a1 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Mon, 27 May 2019 11:40:52 +0100 Subject: [PATCH] Fix duplicate to work like paste to keep pins from getting duplicated. Also fixes the post-duplicate move to start at the cursor pos. Also fixes the fact that duplicate wasn't getting its hotkey. Fixes: lp:1830596 * https://bugs.launchpad.net/kicad/+bug/1830596 --- eeschema/ee_hotkeys.h | 1 - eeschema/libedit/menubar_libedit.cpp | 6 ++ eeschema/menubar.cpp | 18 +++-- eeschema/tools/lib_edit_tool.cpp | 99 +++++++++++++++------------- eeschema/tools/lib_move_tool.cpp | 2 +- eeschema/tools/sch_edit_tool.cpp | 6 +- eeschema/tools/sch_move_tool.cpp | 2 +- include/hotkeys_basic.h | 1 + pcbnew/hotkeys.h | 1 - 9 files changed, 73 insertions(+), 63 deletions(-) diff --git a/eeschema/ee_hotkeys.h b/eeschema/ee_hotkeys.h index d72f8c21c6..2fb2094e7a 100644 --- a/eeschema/ee_hotkeys.h +++ b/eeschema/ee_hotkeys.h @@ -46,7 +46,6 @@ enum hotkey_id_command { HK_EDIT_COMPONENT_WITH_LIBEDIT, HK_MIRROR_X, HK_MIRROR_Y, - HK_DUPLICATE, HK_MOVE, HK_DRAG, HK_SELECT_NODE, diff --git a/eeschema/libedit/menubar_libedit.cpp b/eeschema/libedit/menubar_libedit.cpp index c27b89c3fd..469480291d 100644 --- a/eeschema/libedit/menubar_libedit.cpp +++ b/eeschema/libedit/menubar_libedit.cpp @@ -131,6 +131,12 @@ void LIB_EDIT_FRAME::ReCreateMenuBar() editMenu->AddItem( ACTIONS::undo, enableUndoCondition ); editMenu->AddItem( ACTIONS::redo, enableRedoCondition ); + editMenu->AddSeparator(); + editMenu->AddItem( ACTIONS::cut, EE_CONDITIONS::NotEmpty ); + editMenu->AddItem( ACTIONS::copy, EE_CONDITIONS::NotEmpty ); + editMenu->AddItem( ACTIONS::paste, EE_CONDITIONS::Idle ); + editMenu->AddItem( ACTIONS::duplicate, EE_CONDITIONS::NotEmpty ); + editMenu->AddSeparator(); editMenu->AddItem( EE_ACTIONS::symbolProperties, havePartCondition ); editMenu->AddItem( EE_ACTIONS::pinTable, havePartCondition ); diff --git a/eeschema/menubar.cpp b/eeschema/menubar.cpp index 13835e56ec..c1ca7a5d7e 100644 --- a/eeschema/menubar.cpp +++ b/eeschema/menubar.cpp @@ -152,31 +152,29 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() auto enableRedoCondition = [ this ] ( const SELECTION& sel ) { return GetScreen() && GetScreen()->GetRedoCommandCount() > 0; }; - auto noActiveToolCondition = [ this ] ( const SELECTION& aSelection ) { - return GetToolId() == ID_NO_TOOL_SELECTED; - }; editMenu->AddItem( ACTIONS::undo, enableUndoCondition ); editMenu->AddItem( ACTIONS::redo, enableRedoCondition ); editMenu->AddSeparator(); - editMenu->AddItem( ACTIONS::cut, SELECTION_CONDITIONS::NotEmpty ); - editMenu->AddItem( ACTIONS::copy, SELECTION_CONDITIONS::NotEmpty ); - editMenu->AddItem( ACTIONS::paste, noActiveToolCondition ); + editMenu->AddItem( ACTIONS::cut, EE_CONDITIONS::NotEmpty ); + editMenu->AddItem( ACTIONS::copy, EE_CONDITIONS::NotEmpty ); + editMenu->AddItem( ACTIONS::paste, EE_CONDITIONS::Idle ); + editMenu->AddItem( ACTIONS::duplicate, EE_CONDITIONS::NotEmpty ); editMenu->AddSeparator(); - editMenu->AddItem( EE_ACTIONS::deleteItemCursor, SELECTION_CONDITIONS::ShowAlways ); + editMenu->AddItem( EE_ACTIONS::deleteItemCursor, EE_CONDITIONS::ShowAlways ); // Find editMenu->AddSeparator(); - editMenu->AddItem( ACTIONS::find, SELECTION_CONDITIONS::ShowAlways ); - editMenu->AddItem( ACTIONS::findAndReplace, SELECTION_CONDITIONS::ShowAlways ); + editMenu->AddItem( ACTIONS::find, EE_CONDITIONS::ShowAlways ); + editMenu->AddItem( ACTIONS::findAndReplace, EE_CONDITIONS::ShowAlways ); editMenu->AddSeparator(); // Update field values editMenu->AddItem( ID_UPDATE_FIELDS, _( "Update Fields from Library..." ), _( "Sets symbol fields to original library values" ), - update_fields_xpm, SELECTION_CONDITIONS::ShowAlways ); + update_fields_xpm, EE_CONDITIONS::ShowAlways ); // // Menu View: diff --git a/eeschema/tools/lib_edit_tool.cpp b/eeschema/tools/lib_edit_tool.cpp index 029147e833..043961018d 100644 --- a/eeschema/tools/lib_edit_tool.cpp +++ b/eeschema/tools/lib_edit_tool.cpp @@ -76,7 +76,6 @@ bool LIB_EDIT_TOOL::Init() moveMenu.AddItem( EE_ACTIONS::rotateCW, EE_CONDITIONS::NotEmpty, 200 ); moveMenu.AddItem( EE_ACTIONS::mirrorX, EE_CONDITIONS::NotEmpty, 200 ); moveMenu.AddItem( EE_ACTIONS::mirrorY, EE_CONDITIONS::NotEmpty, 200 ); - moveMenu.AddItem( EE_ACTIONS::duplicate, EE_CONDITIONS::NotEmpty, 200 ); moveMenu.AddItem( EE_ACTIONS::doDelete, EE_CONDITIONS::NotEmpty, 200 ); moveMenu.AddItem( EE_ACTIONS::properties, EE_CONDITIONS::Count( 1 ), 200 ); @@ -84,6 +83,7 @@ bool LIB_EDIT_TOOL::Init() moveMenu.AddSeparator( EE_CONDITIONS::IdleSelection, 300 ); moveMenu.AddItem( ACTIONS::cut, EE_CONDITIONS::IdleSelection, 300 ); moveMenu.AddItem( ACTIONS::copy, EE_CONDITIONS::IdleSelection, 300 ); + moveMenu.AddItem( ACTIONS::duplicate, EE_CONDITIONS::NotEmpty, 300 ); } // @@ -92,12 +92,12 @@ bool LIB_EDIT_TOOL::Init() CONDITIONAL_MENU& drawMenu = drawingTools->GetToolMenu().GetMenu(); drawMenu.AddSeparator( EE_CONDITIONS::NotEmpty, 200 ); - drawMenu.AddItem( EE_ACTIONS::rotateCCW, EE_CONDITIONS::IdleSelection, 200 ); - drawMenu.AddItem( EE_ACTIONS::rotateCW, EE_CONDITIONS::IdleSelection, 200 ); - drawMenu.AddItem( EE_ACTIONS::mirrorX, EE_CONDITIONS::IdleSelection, 200 ); - drawMenu.AddItem( EE_ACTIONS::mirrorY, EE_CONDITIONS::IdleSelection, 200 ); + drawMenu.AddItem( EE_ACTIONS::rotateCCW, EE_CONDITIONS::IdleSelection, 200 ); + drawMenu.AddItem( EE_ACTIONS::rotateCW, EE_CONDITIONS::IdleSelection, 200 ); + drawMenu.AddItem( EE_ACTIONS::mirrorX, EE_CONDITIONS::IdleSelection, 200 ); + drawMenu.AddItem( EE_ACTIONS::mirrorY, EE_CONDITIONS::IdleSelection, 200 ); - drawMenu.AddItem( EE_ACTIONS::properties, EE_CONDITIONS::Count( 1 ), 200 ); + drawMenu.AddItem( EE_ACTIONS::properties, EE_CONDITIONS::Count( 1 ), 200 ); // // Add editing actions to the selection tool menu @@ -108,7 +108,6 @@ bool LIB_EDIT_TOOL::Init() selToolMenu.AddItem( EE_ACTIONS::rotateCW, EE_CONDITIONS::NotEmpty, 200 ); selToolMenu.AddItem( EE_ACTIONS::mirrorX, EE_CONDITIONS::NotEmpty, 200 ); selToolMenu.AddItem( EE_ACTIONS::mirrorY, EE_CONDITIONS::NotEmpty, 200 ); - selToolMenu.AddItem( EE_ACTIONS::duplicate, EE_CONDITIONS::NotEmpty, 200 ); selToolMenu.AddItem( EE_ACTIONS::doDelete, EE_CONDITIONS::NotEmpty, 200 ); selToolMenu.AddItem( EE_ACTIONS::properties, EE_CONDITIONS::Count( 1 ), 200 ); @@ -117,6 +116,7 @@ bool LIB_EDIT_TOOL::Init() selToolMenu.AddItem( ACTIONS::cut, EE_CONDITIONS::IdleSelection, 300 ); selToolMenu.AddItem( ACTIONS::copy, EE_CONDITIONS::IdleSelection, 300 ); selToolMenu.AddItem( ACTIONS::paste, EE_CONDITIONS::Idle, 300 ); + selToolMenu.AddItem( ACTIONS::duplicate, EE_CONDITIONS::NotEmpty, 300 ); return true; } @@ -222,43 +222,6 @@ static KICAD_T nonFields[] = }; -int LIB_EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent ) -{ - LIB_PART* part = m_frame->GetCurPart(); - SELECTION& selection = m_selectionTool->RequestSelection( nonFields ); - - if( selection.GetSize() == 0 ) - return 0; - - // Doing a duplicate of a new object doesn't really make any sense; we'd just end - // up dragging around a stack of objects... - if( selection.Front()->IsNew() ) - return 0; - - if( !selection.Front()->IsMoving() ) - saveCopyInUndoList( m_frame->GetCurPart(), UR_LIBEDIT ); - - EDA_ITEMS newItems; - - for( unsigned ii = 0; ii < selection.GetSize(); ++ii ) - { - LIB_ITEM* oldItem = static_cast( selection.GetItem( ii ) ); - LIB_ITEM* newItem = (LIB_ITEM*) oldItem->Clone(); - newItem->SetFlags( IS_NEW ); - newItems.push_back( newItem ); - - part->GetDrawItems().push_back( newItem ); - getView()->Add( newItem ); - } - - m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true ); - m_toolMgr->RunAction( EE_ACTIONS::addItemsToSel, true, &newItems ); - m_toolMgr->RunAction( EE_ACTIONS::move, false ); - - return 0; -} - - int LIB_EDIT_TOOL::DoDelete( const TOOL_EVENT& aEvent ) { LIB_PART* part = m_frame->GetCurPart(); @@ -667,7 +630,51 @@ int LIB_EDIT_TOOL::Paste( const TOOL_EVENT& aEvent ) { LIB_ITEM* item = (LIB_ITEM*) selection.GetTopLeftItem(); - selection.SetReferencePoint( item->GetPosition() ); + selection.SetReferencePoint( wxPoint( item->GetPosition().x, -item->GetPosition().y ) ); + m_toolMgr->RunAction( EE_ACTIONS::move, false ); + } + + return 0; +} + + +int LIB_EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent ) +{ + LIB_PART* part = m_frame->GetCurPart(); + SELECTION& selection = m_selectionTool->RequestSelection( nonFields ); + + if( selection.GetSize() == 0 ) + return 0; + + // Doing a duplicate of a new object doesn't really make any sense; we'd just end + // up dragging around a stack of objects... + if( selection.Front()->IsNew() ) + return 0; + + if( !selection.Front()->IsMoving() ) + saveCopyInUndoList( m_frame->GetCurPart(), UR_LIBEDIT ); + + EDA_ITEMS newItems; + + for( unsigned ii = 0; ii < selection.GetSize(); ++ii ) + { + LIB_ITEM* oldItem = static_cast( selection.GetItem( ii ) ); + LIB_ITEM* newItem = (LIB_ITEM*) oldItem->Clone(); + oldItem->ClearFlags( SELECTED ); + newItem->SetFlags( IS_NEW | IS_PASTED | SELECTED ); + newItems.push_back( newItem ); + + part->GetDrawItems().push_back( newItem ); + getView()->Add( newItem ); + } + + m_selectionTool->RebuildSelection(); + + if( !selection.Empty() ) + { + LIB_ITEM* item = (LIB_ITEM*) selection.GetTopLeftItem(); + + selection.SetReferencePoint( wxPoint( item->GetPosition().x, -item->GetPosition().y ) ); m_toolMgr->RunAction( EE_ACTIONS::move, false ); } @@ -677,7 +684,7 @@ int LIB_EDIT_TOOL::Paste( const TOOL_EVENT& aEvent ) void LIB_EDIT_TOOL::setTransitions() { - Go( &LIB_EDIT_TOOL::Duplicate, EE_ACTIONS::duplicate.MakeEvent() ); + Go( &LIB_EDIT_TOOL::Duplicate, ACTIONS::duplicate.MakeEvent() ); Go( &LIB_EDIT_TOOL::Rotate, EE_ACTIONS::rotateCW.MakeEvent() ); Go( &LIB_EDIT_TOOL::Rotate, EE_ACTIONS::rotateCCW.MakeEvent() ); Go( &LIB_EDIT_TOOL::Mirror, EE_ACTIONS::mirrorX.MakeEvent() ); diff --git a/eeschema/tools/lib_move_tool.cpp b/eeschema/tools/lib_move_tool.cpp index 2411bf6454..fd69f6beb5 100644 --- a/eeschema/tools/lib_move_tool.cpp +++ b/eeschema/tools/lib_move_tool.cpp @@ -221,7 +221,7 @@ int LIB_MOVE_TOOL::Main( const TOOL_EVENT& aEvent ) // Exit on a remove operation; there is no further processing for removed items. break; } - else if( evt->IsAction( &EE_ACTIONS::duplicate ) ) + else if( evt->IsAction( &ACTIONS::duplicate ) ) { if( selection.Front()->IsNew() ) { diff --git a/eeschema/tools/sch_edit_tool.cpp b/eeschema/tools/sch_edit_tool.cpp index 3864120068..308c4765b1 100644 --- a/eeschema/tools/sch_edit_tool.cpp +++ b/eeschema/tools/sch_edit_tool.cpp @@ -341,7 +341,6 @@ bool SCH_EDIT_TOOL::Init() moveMenu.AddItem( EE_ACTIONS::rotateCW, orientCondition ); moveMenu.AddItem( EE_ACTIONS::mirrorX, orientCondition ); moveMenu.AddItem( EE_ACTIONS::mirrorY, orientCondition ); - moveMenu.AddItem( EE_ACTIONS::duplicate, duplicateCondition ); moveMenu.AddItem( EE_ACTIONS::doDelete, E_C::NotEmpty ); moveMenu.AddItem( EE_ACTIONS::properties, propertiesCondition ); @@ -358,6 +357,7 @@ bool SCH_EDIT_TOOL::Init() moveMenu.AddSeparator( E_C::IdleSelection ); moveMenu.AddItem( ACTIONS::cut, E_C::IdleSelection ); moveMenu.AddItem( ACTIONS::copy, E_C::IdleSelection ); + moveMenu.AddItem( ACTIONS::duplicate, duplicateCondition ); } // @@ -401,7 +401,6 @@ bool SCH_EDIT_TOOL::Init() selToolMenu.AddItem( EE_ACTIONS::rotateCW, orientCondition, 200 ); selToolMenu.AddItem( EE_ACTIONS::mirrorX, orientCondition, 200 ); selToolMenu.AddItem( EE_ACTIONS::mirrorY, orientCondition, 200 ); - selToolMenu.AddItem( EE_ACTIONS::duplicate, duplicateCondition, 200 ); selToolMenu.AddItem( EE_ACTIONS::doDelete, E_C::NotEmpty, 200 ); selToolMenu.AddItem( EE_ACTIONS::properties, propertiesCondition, 200 ); @@ -430,6 +429,7 @@ bool SCH_EDIT_TOOL::Init() selToolMenu.AddItem( ACTIONS::cut, E_C::IdleSelection, 300 ); selToolMenu.AddItem( ACTIONS::copy, E_C::IdleSelection, 300 ); selToolMenu.AddItem( ACTIONS::paste, E_C::Idle, 300 ); + selToolMenu.AddItem( ACTIONS::duplicate, duplicateCondition, 300 ); return true; } @@ -1336,7 +1336,7 @@ int SCH_EDIT_TOOL::CleanupSheetPins( const TOOL_EVENT& aEvent ) void SCH_EDIT_TOOL::setTransitions() { - Go( &SCH_EDIT_TOOL::Duplicate, EE_ACTIONS::duplicate.MakeEvent() ); + Go( &SCH_EDIT_TOOL::Duplicate, ACTIONS::duplicate.MakeEvent() ); Go( &SCH_EDIT_TOOL::RepeatDrawItem, EE_ACTIONS::repeatDrawItem.MakeEvent() ); Go( &SCH_EDIT_TOOL::Rotate, EE_ACTIONS::rotateCW.MakeEvent() ); Go( &SCH_EDIT_TOOL::Rotate, EE_ACTIONS::rotateCCW.MakeEvent() ); diff --git a/eeschema/tools/sch_move_tool.cpp b/eeschema/tools/sch_move_tool.cpp index 69b19a213d..43815d8ce4 100644 --- a/eeschema/tools/sch_move_tool.cpp +++ b/eeschema/tools/sch_move_tool.cpp @@ -378,7 +378,7 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent ) // Exit on a remove operation; there is no further processing for removed items. break; } - else if( evt->IsAction( &EE_ACTIONS::duplicate ) ) + else if( evt->IsAction( &ACTIONS::duplicate ) ) { if( selection.Front()->IsNew() ) { diff --git a/include/hotkeys_basic.h b/include/hotkeys_basic.h index 50142ec7f3..ddcb8a7b51 100644 --- a/include/hotkeys_basic.h +++ b/include/hotkeys_basic.h @@ -270,6 +270,7 @@ enum common_hotkey_id_command { HK_CUT, HK_COPY, HK_PASTE, + HK_DUPLICATE, HK_DELETE, HK_FIND, HK_FIND_NEXT, diff --git a/pcbnew/hotkeys.h b/pcbnew/hotkeys.h index 87d9b1b000..a6ef64d4c0 100644 --- a/pcbnew/hotkeys.h +++ b/pcbnew/hotkeys.h @@ -66,7 +66,6 @@ enum hotkey_id_command { HK_3D_VIEWER, HK_EDIT_ITEM, HK_EDIT_MODULE_WITH_MODEDIT, - HK_DUPLICATE, HK_DUPLICATE_ITEM_AND_INCREMENT, HK_CREATE_ARRAY, HK_PLACE_ITEM,