From 02c7fcdc8470076843cfa1e900b7cf68b98d58a9 Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Fri, 12 Feb 2021 17:15:45 -0800 Subject: [PATCH] Fix BreakWire tool Adds ability to start new commit to eeschema, allowing all AddItemsToUndoList to always append without foreknowledge. Keeps newly split wires on the tool until placed Fixes https://gitlab.com/kicad/code/kicad/issues/7512 --- eeschema/bus-wire-junction.cpp | 7 ------- eeschema/ee_collectors.cpp | 27 +++++++++++++++++++++++++++ eeschema/ee_collectors.h | 2 ++ eeschema/sch_edit_frame.h | 5 +++++ eeschema/schematic_undo_redo.cpp | 16 ++++++++++++++-- eeschema/tools/sch_edit_tool.cpp | 26 ++++++++++++++++++++++++-- eeschema/tools/sch_move_tool.cpp | 25 ++----------------------- 7 files changed, 74 insertions(+), 34 deletions(-) diff --git a/eeschema/bus-wire-junction.cpp b/eeschema/bus-wire-junction.cpp index a0ac489c9c..3232d5ad5d 100644 --- a/eeschema/bus-wire-junction.cpp +++ b/eeschema/bus-wire-junction.cpp @@ -295,12 +295,6 @@ bool SCH_EDIT_FRAME::SchematicCleanUp( SCH_SCREEN* aScreen ) bool SCH_EDIT_FRAME::BreakSegment( SCH_LINE* aSegment, const wxPoint& aPoint, SCH_LINE** aNewSegment, SCH_SCREEN* aScreen ) { - if( !IsPointOnSegment( aSegment->GetStartPoint(), aSegment->GetEndPoint(), aPoint ) - || aSegment->IsEndPoint( aPoint ) ) - { - return false; - } - if( aScreen == nullptr ) aScreen = GetScreen(); @@ -331,7 +325,6 @@ bool SCH_EDIT_FRAME::BreakSegments( const wxPoint& aPoint, SCH_SCREEN* aScreen ) bool brokenSegments = false; std::vector wires; - EDA_RECT bbox( aPoint, wxSize( 2, 2 ) ); for( auto item : aScreen->Items().Overlapping( SCH_LINE_T, aPoint ) ) { diff --git a/eeschema/ee_collectors.cpp b/eeschema/ee_collectors.cpp index a2f681901b..497d63e8cb 100644 --- a/eeschema/ee_collectors.cpp +++ b/eeschema/ee_collectors.cpp @@ -71,6 +71,33 @@ const KICAD_T EE_COLLECTOR::SheetsOnly[] = { }; +const KICAD_T EE_COLLECTOR::MovableItems[] = +{ + SCH_MARKER_T, + SCH_JUNCTION_T, + SCH_NO_CONNECT_T, + SCH_BUS_BUS_ENTRY_T, + SCH_BUS_WIRE_ENTRY_T, + SCH_LINE_T, + SCH_BITMAP_T, + SCH_TEXT_T, + SCH_LABEL_T, + SCH_GLOBAL_LABEL_T, + SCH_HIER_LABEL_T, + SCH_FIELD_T, + SCH_COMPONENT_T, + SCH_SHEET_PIN_T, + SCH_SHEET_T, + EOT +}; + + +const KICAD_T EE_COLLECTOR::WiresOnly[] = { + SCH_LINE_T, + EOT +}; + + const KICAD_T EE_COLLECTOR::FieldOwners[] = { SCH_COMPONENT_T, SCH_SHEET_T, diff --git a/eeschema/ee_collectors.h b/eeschema/ee_collectors.h index a7bf88c4c6..f7c30d6f68 100644 --- a/eeschema/ee_collectors.h +++ b/eeschema/ee_collectors.h @@ -44,8 +44,10 @@ class EE_COLLECTOR : public COLLECTOR public: static const KICAD_T AllItems[]; static const KICAD_T EditableItems[]; + static const KICAD_T MovableItems[]; static const KICAD_T ComponentsOnly[]; static const KICAD_T SheetsOnly[]; + static const KICAD_T WiresOnly[]; static const KICAD_T FieldOwners[]; EE_COLLECTOR( const KICAD_T* aScanTypes = EE_COLLECTOR::AllItems ) : diff --git a/eeschema/sch_edit_frame.h b/eeschema/sch_edit_frame.h index cb14e9d96a..819e963969 100644 --- a/eeschema/sch_edit_frame.h +++ b/eeschema/sch_edit_frame.h @@ -756,6 +756,11 @@ public: /* Undo - redo */ + /** + * Create a new, blank stack for future Undo commands to be pushed to + */ + void StartNewUndo(); + /** * Create a copy of the current schematic item, and put it in the undo list. * diff --git a/eeschema/schematic_undo_redo.cpp b/eeschema/schematic_undo_redo.cpp index 85fac5f7df..b7967eeadb 100644 --- a/eeschema/schematic_undo_redo.cpp +++ b/eeschema/schematic_undo_redo.cpp @@ -95,6 +95,13 @@ * swapped data is data modified by editing, so not all values are swapped */ +void SCH_EDIT_FRAME::StartNewUndo() +{ + PICKED_ITEMS_LIST* blank = new PICKED_ITEMS_LIST(); + PushCommandToUndoList( blank ); +} + + void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_SCREEN* aScreen, SCH_ITEM* aItem, UNDO_REDO aCommandType, @@ -107,8 +114,13 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_SCREEN* aScreen, // Connectivity may change aItem->SetConnectivityDirty(); - if( aAppend ) - commandToUndo = PopCommandFromUndoList(); + PICKED_ITEMS_LIST* lastUndo = PopCommandFromUndoList(); + + // If the last stack was empty, use that one instead of creating a new stack + if( aAppend || !lastUndo->GetCount() ) + commandToUndo = lastUndo; + else + PushCommandToUndoList( lastUndo ); if( !commandToUndo ) { diff --git a/eeschema/tools/sch_edit_tool.cpp b/eeschema/tools/sch_edit_tool.cpp index 9990cc615c..302b054f67 100644 --- a/eeschema/tools/sch_edit_tool.cpp +++ b/eeschema/tools/sch_edit_tool.cpp @@ -66,6 +66,8 @@ #include #include +#include + class SYMBOL_UNIT_MENU : public ACTION_MENU { public: @@ -1685,10 +1687,28 @@ int SCH_EDIT_TOOL::ChangeTextType( const TOOL_EVENT& aEvent ) int SCH_EDIT_TOOL::BreakWire( const TOOL_EVENT& aEvent ) { - auto cursorPos = wxPoint( getViewControls()->GetCursorPosition( !aEvent.Modifier( MD_ALT ) ) ); + wxPoint cursorPos = wxPoint( getViewControls()->GetCursorPosition( !aEvent.Modifier( MD_ALT ) ) ); + EE_SELECTION& selection = m_selectionTool->RequestSelection( EE_COLLECTOR::WiresOnly ); - if( m_frame->BreakSegments( cursorPos ) ) + std::vector lines; + + for( auto& item : selection ) { + if( SCH_LINE* line = dyn_cast( item ) ) + { + if( !line->IsEndPoint( cursorPos ) ) + lines.push_back( line ); + } + } + + m_selectionTool->ClearSelection(); + m_frame->StartNewUndo(); + + for( SCH_LINE* line : lines ) + m_frame->BreakSegment( line, cursorPos ); + + if( !lines.empty() ) + { if( m_frame->GetScreen()->IsJunctionNeeded( cursorPos, true ) ) m_frame->AddJunction( m_frame->GetScreen(), cursorPos, true, false ); @@ -1696,6 +1716,8 @@ int SCH_EDIT_TOOL::BreakWire( const TOOL_EVENT& aEvent ) m_frame->OnModify(); m_frame->GetCanvas()->Refresh(); + + m_toolMgr->RunAction( EE_ACTIONS::drag ); } return 0; diff --git a/eeschema/tools/sch_move_tool.cpp b/eeschema/tools/sch_move_tool.cpp index 1380ba824b..20bfab2401 100644 --- a/eeschema/tools/sch_move_tool.cpp +++ b/eeschema/tools/sch_move_tool.cpp @@ -81,27 +81,6 @@ bool SCH_MOVE_TOOL::Init() } -static const KICAD_T movableItems[] = -{ - SCH_MARKER_T, - SCH_JUNCTION_T, - SCH_NO_CONNECT_T, - SCH_BUS_BUS_ENTRY_T, - SCH_BUS_WIRE_ENTRY_T, - SCH_LINE_T, - SCH_BITMAP_T, - SCH_TEXT_T, - SCH_LABEL_T, - SCH_GLOBAL_LABEL_T, - SCH_HIER_LABEL_T, - SCH_FIELD_T, - SCH_COMPONENT_T, - SCH_SHEET_PIN_T, - SCH_SHEET_T, - EOT -}; - - /* TODO - Tom/Jeff - add preferences option "Move origin: always cursor / item origin" - add preferences option "Default drag action: drag items / move" @@ -150,7 +129,7 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent ) // Be sure that there is at least one item that we can move. If there's no selection try // looking for the stuff under mouse cursor (i.e. Kicad old-style hover selection). - EE_SELECTION& selection = m_selectionTool->RequestSelection( movableItems ); + EE_SELECTION& selection = m_selectionTool->RequestSelection( EE_COLLECTOR::MovableItems ); bool unselect = selection.IsHover(); // Keep an original copy of the starting points for cleanup after the move @@ -751,7 +730,7 @@ void SCH_MOVE_TOOL::moveItem( EDA_ITEM* aItem, const VECTOR2I& aDelta ) int SCH_MOVE_TOOL::AlignElements( const TOOL_EVENT& aEvent ) { EE_GRID_HELPER grid( m_toolMgr); - EE_SELECTION& selection = m_selectionTool->RequestSelection( movableItems ); + EE_SELECTION& selection = m_selectionTool->RequestSelection( EE_COLLECTOR::MovableItems ); bool append_undo = false; for( SCH_ITEM* it : m_frame->GetScreen()->Items() )