Fix overzealous breakSegments()

We cannot break segements that are merely close or on endpoints, so we
filter these prior to the break routine.  Failing to do this was
overloading our undo stack with bogus values

Fixes https://gitlab.com/kicad/code/kicad/issues/7553

Fixes https://gitlab.com/kicad/code/kicad/issues/7557

Fixes https://gitlab.com/kicad/code/kicad/issues/7554
This commit is contained in:
Seth Hillbrand 2021-02-16 10:09:56 -08:00
parent df573255e0
commit 24795f5b12
3 changed files with 47 additions and 28 deletions

View File

@ -329,7 +329,15 @@ bool SCH_EDIT_FRAME::BreakSegments( const wxPoint& aPoint, SCH_SCREEN* aScreen )
for( auto item : aScreen->Items().Overlapping( SCH_LINE_T, aPoint ) ) for( auto item : aScreen->Items().Overlapping( SCH_LINE_T, aPoint ) )
{ {
if( item->IsType( wiresAndBuses ) ) if( item->IsType( wiresAndBuses ) )
wires.push_back( static_cast<SCH_LINE*>( item ) ); {
SCH_LINE* wire = static_cast<SCH_LINE*>( item );
if( IsPointOnSegment( wire->GetStartPoint(), wire->GetEndPoint(), aPoint )
&& !wire->IsEndPoint( aPoint ) )
{
wires.push_back( wire );
}
}
} }
for( auto wire : wires ) for( auto wire : wires )

View File

@ -97,8 +97,8 @@
void SCH_EDIT_FRAME::StartNewUndo() void SCH_EDIT_FRAME::StartNewUndo()
{ {
PICKED_ITEMS_LIST* blank = new PICKED_ITEMS_LIST(); PICKED_ITEMS_LIST* blank = new PICKED_ITEMS_LIST();
PushCommandToUndoList( blank ); PushCommandToUndoList( blank );
} }
@ -114,16 +114,16 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_SCREEN* aScreen,
// Connectivity may change // Connectivity may change
aItem->SetConnectivityDirty(); aItem->SetConnectivityDirty();
PICKED_ITEMS_LIST* lastUndo = PopCommandFromUndoList(); PICKED_ITEMS_LIST* lastUndo = PopCommandFromUndoList();
// If the last stack was empty, use that one instead of creating a new stack // If the last stack was empty, use that one instead of creating a new stack
if( lastUndo ) if( lastUndo )
{ {
if( aAppend || !lastUndo->GetCount() ) if( aAppend || !lastUndo->GetCount() )
commandToUndo = lastUndo; commandToUndo = lastUndo;
else else
PushCommandToUndoList( lastUndo ); PushCommandToUndoList( lastUndo );
} }
if( !commandToUndo ) if( !commandToUndo )
{ {
@ -175,8 +175,16 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
if( !aItemsList.GetCount() ) if( !aItemsList.GetCount() )
return; return;
if( aAppend ) PICKED_ITEMS_LIST* lastUndo = PopCommandFromUndoList();
commandToUndo = PopCommandFromUndoList();
// If the last stack was empty, use that one instead of creating a new stack
if( lastUndo )
{
if( aAppend || !lastUndo->GetCount() )
commandToUndo = lastUndo;
else
PushCommandToUndoList( lastUndo );
}
if( !commandToUndo ) if( !commandToUndo )
commandToUndo = new PICKED_ITEMS_LIST(); commandToUndo = new PICKED_ITEMS_LIST();
@ -267,7 +275,7 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
if( status == UNDO_REDO::NOP ) if( status == UNDO_REDO::NOP )
{ {
continue; continue;
} }
if( status == UNDO_REDO::NEWITEM ) if( status == UNDO_REDO::NEWITEM )
{ {
@ -343,8 +351,12 @@ void SCH_EDIT_FRAME::RollbackSchematicFromUndo()
PICKED_ITEMS_LIST* undo = PopCommandFromUndoList(); PICKED_ITEMS_LIST* undo = PopCommandFromUndoList();
// Skip empty frames // Skip empty frames
while( undo && undo->GetCount() == 1 && undo->GetPickedItemStatus( 0 ) == UNDO_REDO::NOP ) while( undo && ( !undo->GetCount()
undo = PopCommandFromUndoList(); || ( undo->GetCount() == 1 && undo->GetPickedItemStatus( 0 ) == UNDO_REDO::NOP ) ) )
{
delete undo;
undo = PopCommandFromUndoList();
}
if( undo ) if( undo )
{ {

View File

@ -66,7 +66,6 @@
#include <dialogs/dialog_edit_label.h> #include <dialogs/dialog_edit_label.h>
#include <core/kicad_algo.h> #include <core/kicad_algo.h>
#include <limits>
class SYMBOL_UNIT_MENU : public ACTION_MENU class SYMBOL_UNIT_MENU : public ACTION_MENU
{ {
@ -1692,21 +1691,21 @@ int SCH_EDIT_TOOL::BreakWire( const TOOL_EVENT& aEvent )
for( auto& item : selection ) for( auto& item : selection )
{ {
if( SCH_LINE* line = dyn_cast<SCH_LINE*>( item ) ) if( SCH_LINE* line = dyn_cast<SCH_LINE*>( item ) )
{ {
if( !line->IsEndPoint( cursorPos ) ) if( !line->IsEndPoint( cursorPos ) )
lines.push_back( line ); lines.push_back( line );
} }
} }
m_selectionTool->ClearSelection(); m_selectionTool->ClearSelection();
m_frame->StartNewUndo(); m_frame->StartNewUndo();
for( SCH_LINE* line : lines ) for( SCH_LINE* line : lines )
m_frame->BreakSegment( line, cursorPos ); m_frame->BreakSegment( line, cursorPos );
if( !lines.empty() ) if( !lines.empty() )
{ {
if( m_frame->GetScreen()->IsJunctionNeeded( cursorPos, true ) ) if( m_frame->GetScreen()->IsJunctionNeeded( cursorPos, true ) )
m_frame->AddJunction( m_frame->GetScreen(), cursorPos, true, false ); m_frame->AddJunction( m_frame->GetScreen(), cursorPos, true, false );