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
This commit is contained in:
Seth Hillbrand 2021-02-12 17:15:45 -08:00
parent 2773bcf35b
commit 02c7fcdc84
7 changed files with 74 additions and 34 deletions

View File

@ -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<SCH_LINE*> wires;
EDA_RECT bbox( aPoint, wxSize( 2, 2 ) );
for( auto item : aScreen->Items().Overlapping( SCH_LINE_T, aPoint ) )
{

View File

@ -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,

View File

@ -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 ) :

View File

@ -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.
*

View File

@ -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 )
{

View File

@ -66,6 +66,8 @@
#include <dialogs/dialog_edit_label.h>
#include <core/kicad_algo.h>
#include <limits>
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<SCH_LINE*> lines;
for( auto& item : selection )
{
if( SCH_LINE* line = dyn_cast<SCH_LINE*>( 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;

View File

@ -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() )