mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-13 17:53:11 +02:00
Move wire/junction actions out of SCHEMATIC
They are tool actions and require that the tool holder is valid, so they really need to be where this is only ever true Fixes https://gitlab.com/kicad/code/kicad/-/issues/21510
This commit is contained in:
parent
cea77b7e9b
commit
0586f02f00
@ -31,6 +31,7 @@
|
||||
#include <sch_no_connect.h>
|
||||
#include <sch_commit.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tools/sch_line_wire_bus_tool.h>
|
||||
#include <tools/sch_selection_tool.h>
|
||||
#include <trigo.h>
|
||||
|
||||
@ -56,6 +57,7 @@ bool SCH_EDIT_FRAME::TrimWire( SCH_COMMIT* aCommit, const VECTOR2I& aStart, cons
|
||||
std::vector<SCH_LINE*> wires;
|
||||
BOX2I bb( aStart );
|
||||
|
||||
SCH_LINE_WIRE_BUS_TOOL* lwbTool = m_toolManager->GetTool<SCH_LINE_WIRE_BUS_TOOL>();
|
||||
bb.Merge( aEnd );
|
||||
|
||||
// We cannot modify the RTree while iterating, so push the possible
|
||||
@ -90,14 +92,14 @@ bool SCH_EDIT_FRAME::TrimWire( SCH_COMMIT* aCommit, const VECTOR2I& aStart, cons
|
||||
// Step 1: break the segment on one end.
|
||||
// Ensure that *line points to the segment containing aEnd
|
||||
SCH_LINE* new_line;
|
||||
Schematic().BreakSegment( aCommit, line, aStart, &new_line, screen );
|
||||
lwbTool->BreakSegment( aCommit, line, aStart, &new_line, screen );
|
||||
|
||||
if( IsPointOnSegment( new_line->GetStartPoint(), new_line->GetEndPoint(), aEnd ) )
|
||||
line = new_line;
|
||||
|
||||
// Step 2: break the remaining segment.
|
||||
// Ensure that *line _also_ contains aStart. This is our overlapping segment
|
||||
Schematic().BreakSegment( aCommit, line, aEnd, &new_line, screen );
|
||||
lwbTool->BreakSegment( aCommit, line, aEnd, &new_line, screen );
|
||||
|
||||
if( IsPointOnSegment( new_line->GetStartPoint(), new_line->GetEndPoint(), aStart ) )
|
||||
line = new_line;
|
||||
@ -184,20 +186,6 @@ void SCH_EDIT_FRAME::DeleteJunction( SCH_COMMIT* aCommit, SCH_ITEM* aJunction )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SCH_JUNCTION* SCH_EDIT_FRAME::AddJunction( SCH_COMMIT* aCommit, SCH_SCREEN* aScreen,
|
||||
const VECTOR2I& aPos )
|
||||
{
|
||||
SCH_JUNCTION* junction = new SCH_JUNCTION( aPos );
|
||||
|
||||
AddToScreen( junction, aScreen );
|
||||
aCommit->Added( junction, aScreen );
|
||||
|
||||
Schematic().BreakSegments( aCommit, aPos, aScreen );
|
||||
|
||||
return junction;
|
||||
}
|
||||
|
||||
void SCH_EDIT_FRAME::UpdateHopOveredWires( SCH_ITEM* aItem )
|
||||
{
|
||||
std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR> items;
|
||||
|
@ -1038,67 +1038,6 @@ bool SCHEMATIC::IsComplexHierarchy() const
|
||||
}
|
||||
|
||||
|
||||
void SCHEMATIC::BreakSegment( SCH_COMMIT* aCommit, SCH_LINE* aSegment, const VECTOR2I& aPoint,
|
||||
SCH_LINE** aNewSegment, SCH_SCREEN* aScreen )
|
||||
{
|
||||
// Save the copy of aSegment before breaking it
|
||||
aCommit->Modify( aSegment, aScreen );
|
||||
|
||||
SCH_LINE* newSegment = aSegment->BreakAt( aCommit, aPoint );
|
||||
|
||||
aSegment->SetFlags( IS_CHANGED | IS_BROKEN );
|
||||
newSegment->SetFlags( IS_NEW | IS_BROKEN );
|
||||
|
||||
if( m_schematicHolder )
|
||||
m_schematicHolder->AddToScreen( newSegment, aScreen );
|
||||
|
||||
aCommit->Added( newSegment, aScreen );
|
||||
|
||||
*aNewSegment = newSegment;
|
||||
}
|
||||
|
||||
|
||||
bool SCHEMATIC::BreakSegments( SCH_COMMIT* aCommit, const VECTOR2I& aPos, SCH_SCREEN* aScreen )
|
||||
{
|
||||
bool brokenSegments = false;
|
||||
SCH_LINE* new_line;
|
||||
|
||||
for( SCH_LINE* wire : aScreen->GetBusesAndWires( aPos, true ) )
|
||||
{
|
||||
BreakSegment( aCommit, wire, aPos, &new_line, aScreen );
|
||||
brokenSegments = true;
|
||||
}
|
||||
|
||||
return brokenSegments;
|
||||
}
|
||||
|
||||
|
||||
bool SCHEMATIC::BreakSegmentsOnJunctions( SCH_COMMIT* aCommit, SCH_SCREEN* aScreen )
|
||||
{
|
||||
bool brokenSegments = false;
|
||||
|
||||
std::set<VECTOR2I> point_set;
|
||||
|
||||
for( SCH_ITEM* item : aScreen->Items().OfType( SCH_JUNCTION_T ) )
|
||||
point_set.insert( item->GetPosition() );
|
||||
|
||||
for( SCH_ITEM* item : aScreen->Items().OfType( SCH_BUS_WIRE_ENTRY_T ) )
|
||||
{
|
||||
SCH_BUS_WIRE_ENTRY* entry = static_cast<SCH_BUS_WIRE_ENTRY*>( item );
|
||||
point_set.insert( entry->GetPosition() );
|
||||
point_set.insert( entry->GetEnd() );
|
||||
}
|
||||
|
||||
for( const VECTOR2I& pt : point_set )
|
||||
{
|
||||
BreakSegments( aCommit, pt, aScreen );
|
||||
brokenSegments = true;
|
||||
}
|
||||
|
||||
return brokenSegments;
|
||||
}
|
||||
|
||||
|
||||
void SCHEMATIC::CleanUp( SCH_COMMIT* aCommit, SCH_SCREEN* aScreen )
|
||||
{
|
||||
SCH_SELECTION_TOOL* selectionTool = m_schematicHolder ? m_schematicHolder->GetSelectionTool() : nullptr;
|
||||
@ -1130,7 +1069,6 @@ void SCHEMATIC::CleanUp( SCH_COMMIT* aCommit, SCH_SCREEN* aScreen )
|
||||
}
|
||||
};
|
||||
|
||||
BreakSegmentsOnJunctions( aCommit, aScreen );
|
||||
|
||||
for( SCH_ITEM* item : aScreen->Items().OfType( SCH_JUNCTION_T ) )
|
||||
{
|
||||
|
@ -287,39 +287,6 @@ public:
|
||||
*/
|
||||
void FixupJunctionsAfterImport();
|
||||
|
||||
/**
|
||||
* Break a single segment into two at the specified point.
|
||||
*
|
||||
* @param aCommit Transaction container used to record changes for undo/redo
|
||||
* @param aSegment Line segment to break
|
||||
* @param aPoint Point at which to break the segment
|
||||
* @param aNewSegment Pointer to the newly created segment (if created)
|
||||
* @param aScreen is the screen to examine
|
||||
*/
|
||||
void BreakSegment( SCH_COMMIT* aCommit, SCH_LINE* aSegment, const VECTOR2I& aPoint, SCH_LINE** aNewSegment,
|
||||
SCH_SCREEN* aScreen );
|
||||
|
||||
/**
|
||||
* Check every wire and bus for a intersection at \a aPoint and break into two segments
|
||||
* at \a aPoint if an intersection is found.
|
||||
*
|
||||
* @param aCommit Transaction container used to record changes for undo/redo
|
||||
* @param aPoint Test this point for an intersection.
|
||||
* @param aScreen is the screen to examine.
|
||||
* @return True if any wires or buses were broken.
|
||||
*/
|
||||
bool BreakSegments( SCH_COMMIT* aCommit, const VECTOR2I& aPoint, SCH_SCREEN* aScreen );
|
||||
|
||||
/**
|
||||
* Test all junctions and bus entries in the schematic for intersections with wires and
|
||||
* buses and breaks any intersections into multiple segments.
|
||||
*
|
||||
* @param aCommit Transaction container used to record changes for undo/redo
|
||||
* @param aScreen is the screen to examine.
|
||||
* @return True if any wires or buses were broken.
|
||||
*/
|
||||
bool BreakSegmentsOnJunctions( SCH_COMMIT* aCommit, SCH_SCREEN* aScreen );
|
||||
|
||||
/**
|
||||
* Scan existing markers and record data from any that are Excluded.
|
||||
*/
|
||||
|
@ -2874,6 +2874,8 @@ int SCH_EDIT_TOOL::BreakWire( const TOOL_EVENT& aEvent )
|
||||
SCH_SELECTION& selection = m_selectionTool->RequestSelection( { SCH_LINE_T } );
|
||||
SCH_SCREEN* screen = m_frame->GetScreen();
|
||||
SCH_COMMIT commit( m_toolMgr );
|
||||
|
||||
SCH_LINE_WIRE_BUS_TOOL* lwbTool = m_toolMgr->GetTool<SCH_LINE_WIRE_BUS_TOOL>();
|
||||
std::vector<SCH_LINE*> lines;
|
||||
|
||||
// Save the current orthogonal mode so we can restore it later
|
||||
@ -2908,9 +2910,9 @@ int SCH_EDIT_TOOL::BreakWire( const TOOL_EVENT& aEvent )
|
||||
|
||||
// We let the user select the break point if they're on a single line
|
||||
if( lines.size() == 1 && line->HitTest( cursorPos ) && !line->IsEndPoint( cursorPos ) )
|
||||
m_frame->Schematic().BreakSegment( &commit, line, cursorPos, &newLine, screen );
|
||||
lwbTool->BreakSegment( &commit, line, cursorPos, &newLine, screen );
|
||||
else
|
||||
m_frame->Schematic().BreakSegment( &commit, line, line->GetMidPoint(), &newLine, screen );
|
||||
lwbTool->BreakSegment( &commit, line, line->GetMidPoint(), &newLine, screen );
|
||||
|
||||
// Make sure both endpoints are deselected
|
||||
newLine->ClearFlags( ENDPOINT | STARTPOINT );
|
||||
|
@ -1288,7 +1288,7 @@ void SCH_LINE_WIRE_BUS_TOOL::finishSegments( SCH_COMMIT& aCommit )
|
||||
for( const VECTOR2I& pt : new_ends )
|
||||
{
|
||||
if( m_frame->GetScreen()->IsExplicitJunctionNeeded( pt ) )
|
||||
m_frame->AddJunction( &aCommit, m_frame->GetScreen(), pt );
|
||||
AddJunction( &aCommit, m_frame->GetScreen(), pt );
|
||||
}
|
||||
|
||||
if( m_busUnfold.in_progress )
|
||||
@ -1363,12 +1363,85 @@ int SCH_LINE_WIRE_BUS_TOOL::AddJunctionsIfNeeded( SCH_COMMIT* aCommit, SCH_SELEC
|
||||
}
|
||||
|
||||
for( const VECTOR2I& point : screen->GetNeededJunctions( allItems ) )
|
||||
m_frame->AddJunction( aCommit, m_frame->GetScreen(), point );
|
||||
AddJunction( aCommit, m_frame->GetScreen(), point );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void SCH_LINE_WIRE_BUS_TOOL::BreakSegment( SCH_COMMIT* aCommit, SCH_LINE* aSegment, const VECTOR2I& aPoint,
|
||||
SCH_LINE** aNewSegment, SCH_SCREEN* aScreen )
|
||||
{
|
||||
// Save the copy of aSegment before breaking it
|
||||
aCommit->Modify( aSegment, aScreen );
|
||||
|
||||
SCH_LINE* newSegment = aSegment->BreakAt( aCommit, aPoint );
|
||||
|
||||
aSegment->SetFlags( IS_CHANGED | IS_BROKEN );
|
||||
newSegment->SetFlags( IS_NEW | IS_BROKEN );
|
||||
m_frame->AddToScreen( newSegment, aScreen );
|
||||
|
||||
aCommit->Added( newSegment, aScreen );
|
||||
|
||||
*aNewSegment = newSegment;
|
||||
}
|
||||
|
||||
|
||||
bool SCH_LINE_WIRE_BUS_TOOL::BreakSegments( SCH_COMMIT* aCommit, const VECTOR2I& aPos, SCH_SCREEN* aScreen )
|
||||
{
|
||||
bool brokenSegments = false;
|
||||
SCH_LINE* new_line;
|
||||
|
||||
for( SCH_LINE* wire : aScreen->GetBusesAndWires( aPos, true ) )
|
||||
{
|
||||
BreakSegment( aCommit, wire, aPos, &new_line, aScreen );
|
||||
brokenSegments = true;
|
||||
}
|
||||
|
||||
return brokenSegments;
|
||||
}
|
||||
|
||||
|
||||
bool SCH_LINE_WIRE_BUS_TOOL::BreakSegmentsOnJunctions( SCH_COMMIT* aCommit, SCH_SCREEN* aScreen )
|
||||
{
|
||||
bool brokenSegments = false;
|
||||
|
||||
std::set<VECTOR2I> point_set;
|
||||
|
||||
for( SCH_ITEM* item : aScreen->Items().OfType( SCH_JUNCTION_T ) )
|
||||
point_set.insert( item->GetPosition() );
|
||||
|
||||
for( SCH_ITEM* item : aScreen->Items().OfType( SCH_BUS_WIRE_ENTRY_T ) )
|
||||
{
|
||||
SCH_BUS_WIRE_ENTRY* entry = static_cast<SCH_BUS_WIRE_ENTRY*>( item );
|
||||
point_set.insert( entry->GetPosition() );
|
||||
point_set.insert( entry->GetEnd() );
|
||||
}
|
||||
|
||||
for( const VECTOR2I& pt : point_set )
|
||||
{
|
||||
BreakSegments( aCommit, pt, aScreen );
|
||||
brokenSegments = true;
|
||||
}
|
||||
|
||||
return brokenSegments;
|
||||
}
|
||||
|
||||
|
||||
SCH_JUNCTION* SCH_LINE_WIRE_BUS_TOOL::AddJunction( SCH_COMMIT* aCommit, SCH_SCREEN* aScreen,
|
||||
const VECTOR2I& aPos )
|
||||
{
|
||||
SCH_JUNCTION* junction = new SCH_JUNCTION( aPos );
|
||||
|
||||
m_frame->AddToScreen( junction, aScreen );
|
||||
aCommit->Added( junction, aScreen );
|
||||
|
||||
BreakSegments( aCommit, aPos, aScreen );
|
||||
|
||||
return junction;
|
||||
}
|
||||
|
||||
|
||||
void SCH_LINE_WIRE_BUS_TOOL::setTransitions()
|
||||
{
|
||||
Go( &SCH_LINE_WIRE_BUS_TOOL::DrawSegments, SCH_ACTIONS::drawWire.MakeEvent() );
|
||||
|
@ -79,6 +79,39 @@ public:
|
||||
/// @copydoc TOOL_INTERACTIVE::Init()
|
||||
bool Init() override;
|
||||
|
||||
/**
|
||||
* Break a single segment into two at the specified point.
|
||||
*
|
||||
* @param aCommit Transaction container used to record changes for undo/redo
|
||||
* @param aSegment Line segment to break
|
||||
* @param aPoint Point at which to break the segment
|
||||
* @param aNewSegment Pointer to the newly created segment (if created)
|
||||
* @param aScreen is the screen to examine
|
||||
*/
|
||||
void BreakSegment( SCH_COMMIT* aCommit, SCH_LINE* aSegment, const VECTOR2I& aPoint, SCH_LINE** aNewSegment,
|
||||
SCH_SCREEN* aScreen );
|
||||
|
||||
/**
|
||||
* Check every wire and bus for a intersection at \a aPoint and break into two segments
|
||||
* at \a aPoint if an intersection is found.
|
||||
*
|
||||
* @param aCommit Transaction container used to record changes for undo/redo
|
||||
* @param aPoint Test this point for an intersection.
|
||||
* @param aScreen is the screen to examine.
|
||||
* @return True if any wires or buses were broken.
|
||||
*/
|
||||
bool BreakSegments( SCH_COMMIT* aCommit, const VECTOR2I& aPoint, SCH_SCREEN* aScreen );
|
||||
|
||||
/**
|
||||
* Test all junctions and bus entries in the schematic for intersections with wires and
|
||||
* buses and breaks any intersections into multiple segments.
|
||||
*
|
||||
* @param aCommit Transaction container used to record changes for undo/redo
|
||||
* @param aScreen is the screen to examine.
|
||||
* @return True if any wires or buses were broken.
|
||||
*/
|
||||
bool BreakSegmentsOnJunctions( SCH_COMMIT* aCommit, SCH_SCREEN* aScreen );
|
||||
|
||||
int DrawSegments( const TOOL_EVENT& aEvent );
|
||||
int UnfoldBus( const TOOL_EVENT& aEvent );
|
||||
|
||||
@ -90,6 +123,8 @@ public:
|
||||
*/
|
||||
int AddJunctionsIfNeeded( SCH_COMMIT* aCommit, SCH_SELECTION* aSelection );
|
||||
|
||||
SCH_JUNCTION* AddJunction( SCH_COMMIT* aCommit, SCH_SCREEN* aScreen, const VECTOR2I& aPos );
|
||||
|
||||
/**
|
||||
* Logic to remove wires when overlapping correct items
|
||||
*/
|
||||
|
@ -1075,15 +1075,16 @@ bool SCH_MOVE_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, SCH_COMMIT* aComm
|
||||
|
||||
m_selectionTool->RemoveItemsFromSel( &m_dragAdditions, QUIET_MODE );
|
||||
|
||||
SCH_LINE_WIRE_BUS_TOOL* lwbTool = m_toolMgr->GetTool<SCH_LINE_WIRE_BUS_TOOL>();
|
||||
|
||||
// If we move items away from a junction, we _may_ want to add a junction there
|
||||
// to denote the state.
|
||||
for( const DANGLING_END_ITEM& it : internalPoints )
|
||||
{
|
||||
if( m_frame->GetScreen()->IsExplicitJunctionNeeded( it.GetPosition()) )
|
||||
m_frame->AddJunction( aCommit, m_frame->GetScreen(), it.GetPosition() );
|
||||
lwbTool->AddJunction( aCommit, m_frame->GetScreen(), it.GetPosition() );
|
||||
}
|
||||
|
||||
SCH_LINE_WIRE_BUS_TOOL* lwbTool = m_toolMgr->GetTool<SCH_LINE_WIRE_BUS_TOOL>();
|
||||
lwbTool->TrimOverLappingWires( aCommit, &selectionCopy );
|
||||
lwbTool->AddJunctionsIfNeeded( aCommit, &selectionCopy );
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user