diff --git a/eeschema/bus-wire-junction.cpp b/eeschema/bus-wire-junction.cpp index 5ff4bfb92c..d2d6351913 100644 --- a/eeschema/bus-wire-junction.cpp +++ b/eeschema/bus-wire-junction.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -56,6 +57,7 @@ bool SCH_EDIT_FRAME::TrimWire( SCH_COMMIT* aCommit, const VECTOR2I& aStart, cons std::vector wires; BOX2I bb( aStart ); + SCH_LINE_WIRE_BUS_TOOL* lwbTool = m_toolManager->GetTool(); 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 items; diff --git a/eeschema/schematic.cpp b/eeschema/schematic.cpp index 9043bafbc8..528a774d5a 100644 --- a/eeschema/schematic.cpp +++ b/eeschema/schematic.cpp @@ -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 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( 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 ) ) { diff --git a/eeschema/schematic.h b/eeschema/schematic.h index abb92065be..5923220294 100644 --- a/eeschema/schematic.h +++ b/eeschema/schematic.h @@ -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. */ diff --git a/eeschema/tools/sch_edit_tool.cpp b/eeschema/tools/sch_edit_tool.cpp index 94f221f164..07948147a7 100644 --- a/eeschema/tools/sch_edit_tool.cpp +++ b/eeschema/tools/sch_edit_tool.cpp @@ -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(); std::vector 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 ); diff --git a/eeschema/tools/sch_line_wire_bus_tool.cpp b/eeschema/tools/sch_line_wire_bus_tool.cpp index 2e46439cbd..9739fbbe56 100644 --- a/eeschema/tools/sch_line_wire_bus_tool.cpp +++ b/eeschema/tools/sch_line_wire_bus_tool.cpp @@ -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 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( 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() ); diff --git a/eeschema/tools/sch_line_wire_bus_tool.h b/eeschema/tools/sch_line_wire_bus_tool.h index c64d79a8e8..4681ce7453 100644 --- a/eeschema/tools/sch_line_wire_bus_tool.h +++ b/eeschema/tools/sch_line_wire_bus_tool.h @@ -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 */ diff --git a/eeschema/tools/sch_move_tool.cpp b/eeschema/tools/sch_move_tool.cpp index 6b575329f9..03499017d0 100644 --- a/eeschema/tools/sch_move_tool.cpp +++ b/eeschema/tools/sch_move_tool.cpp @@ -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(); + // 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(); lwbTool->TrimOverLappingWires( aCommit, &selectionCopy ); lwbTool->AddJunctionsIfNeeded( aCommit, &selectionCopy );