diff --git a/eeschema/tools/ee_actions.cpp b/eeschema/tools/ee_actions.cpp index 8ee2621d66..2a6b1bce8e 100644 --- a/eeschema/tools/ee_actions.cpp +++ b/eeschema/tools/ee_actions.cpp @@ -609,6 +609,10 @@ TOOL_ACTION EE_ACTIONS::toggleForceHV( "eeschema.EditorControl.forceHVLines", // SCH_LINE_WIRE_BUS_TOOL // +TOOL_ACTION EE_ACTIONS::addNeededJunctions( + "eeschema.InteractiveDrawingLineWireBus.addNeededJunctions", AS_ACTIVE, 0, "", + _( "Add Junctions to Selection where needed" ), "", nullptr, AF_ACTIVATE ); + TOOL_ACTION EE_ACTIONS::drawWire( "eeschema.InteractiveDrawingLineWireBus.drawWires", AS_GLOBAL, 'W', LEGACY_HK_NAME( "Begin Wire" ), diff --git a/eeschema/tools/ee_actions.h b/eeschema/tools/ee_actions.h index f5a65ec4e0..e73a53f49f 100644 --- a/eeschema/tools/ee_actions.h +++ b/eeschema/tools/ee_actions.h @@ -73,6 +73,7 @@ public: static TOOL_ACTION unlock; // Schematic Tools + static TOOL_ACTION addNeededJunctions; static TOOL_ACTION pickerTool; static TOOL_ACTION placeSymbol; static TOOL_ACTION placePower; diff --git a/eeschema/tools/sch_edit_tool.cpp b/eeschema/tools/sch_edit_tool.cpp index 6a0a139527..4d9130f113 100644 --- a/eeschema/tools/sch_edit_tool.cpp +++ b/eeschema/tools/sch_edit_tool.cpp @@ -837,7 +837,13 @@ int SCH_EDIT_TOOL::RepeatDrawItem( const TOOL_EVENT& aEvent ) newItem->ClearFlags(); if( newItem->IsConnectable() ) + { + auto selection = m_selectionTool->GetSelection(); + + m_toolMgr->RunAction( EE_ACTIONS::addNeededJunctions, true, &selection ); + m_frame->SchematicCleanUp(); m_frame->TestDanglingEnds(); + } // newItem newItem, now that it has been moved, thus saving new position. m_frame->SaveCopyForRepeatItem( newItem ); diff --git a/eeschema/tools/sch_line_wire_bus_tool.cpp b/eeschema/tools/sch_line_wire_bus_tool.cpp index 580fc97e24..c78ce00e60 100644 --- a/eeschema/tools/sch_line_wire_bus_tool.cpp +++ b/eeschema/tools/sch_line_wire_bus_tool.cpp @@ -845,8 +845,68 @@ void SCH_LINE_WIRE_BUS_TOOL::finishSegments() } +int SCH_LINE_WIRE_BUS_TOOL::AddJunctionsIfNeeded( const TOOL_EVENT& aEvent ) +{ + EE_SELECTION* aSelection = aEvent.Parameter(); + + std::vector pts; + std::vector connections; + + m_frame->GetSchematicConnections( connections ); + + for( unsigned ii = 0; ii < aSelection->GetSize(); ii++ ) + { + SCH_ITEM* item = static_cast( aSelection->GetItem( ii ) ); + std::vector new_pts; + + if( !item->IsConnectable() ) + continue; + + item->GetConnectionPoints( new_pts ); + pts.insert( pts.end(), new_pts.begin(), new_pts.end() ); + + // If the item is a line, we also add any connection points from the rest of the schematic + // that terminate on the line after it is moved. + if( item->Type() == SCH_LINE_T ) + { + SCH_LINE* line = (SCH_LINE*) item; + for( auto i : connections ) + { + if( IsPointOnSegment( line->GetStartPoint(), line->GetEndPoint(), i ) ) + pts.push_back( i ); + } + } + else + { + // Clean up any wires that short non-wire connections in the list + for( auto point = new_pts.begin(); point != new_pts.end(); point++ ) + { + for( auto second_point = point + 1; second_point != new_pts.end(); second_point++ ) + m_frame->TrimWire( *point, *second_point ); + } + } + } + + // We always have some overlapping connection points. Drop duplicates here + std::sort( pts.begin(), pts.end(), []( const wxPoint& a, const wxPoint& b ) -> bool { + return a.x < b.x || ( a.x == b.x && a.y < b.y ); + } ); + + pts.erase( unique( pts.begin(), pts.end() ), pts.end() ); + + for( auto point : pts ) + { + if( m_frame->GetScreen()->IsJunctionNeeded( point, true ) ) + m_frame->AddJunction( point, true, false ); + } + + return 0; +} + + void SCH_LINE_WIRE_BUS_TOOL::setTransitions() { + Go( &SCH_LINE_WIRE_BUS_TOOL::AddJunctionsIfNeeded, EE_ACTIONS::addNeededJunctions.MakeEvent() ); Go( &SCH_LINE_WIRE_BUS_TOOL::DrawSegments, EE_ACTIONS::drawWire.MakeEvent() ); Go( &SCH_LINE_WIRE_BUS_TOOL::DrawSegments, EE_ACTIONS::drawBus.MakeEvent() ); Go( &SCH_LINE_WIRE_BUS_TOOL::DrawSegments, EE_ACTIONS::drawLines.MakeEvent() ); diff --git a/eeschema/tools/sch_line_wire_bus_tool.h b/eeschema/tools/sch_line_wire_bus_tool.h index e5a426dfa7..c1c5a35b24 100644 --- a/eeschema/tools/sch_line_wire_bus_tool.h +++ b/eeschema/tools/sch_line_wire_bus_tool.h @@ -74,6 +74,11 @@ public: static bool IsDrawingBus( const SELECTION& aSelection ); static bool IsDrawingLineWireOrBus( const SELECTION& aSelection ); + /** + * Handle the addition of junctions to a selection of objects + */ + int AddJunctionsIfNeeded( const TOOL_EVENT& aEvent ); + private: int doDrawSegments( int aType, SCH_LINE* aSegment, bool aImmediateMode ); SCH_LINE* startSegments( int aType, const VECTOR2D& aPos ); diff --git a/eeschema/tools/sch_move_tool.cpp b/eeschema/tools/sch_move_tool.cpp index f25011ea04..60c34cb54e 100644 --- a/eeschema/tools/sch_move_tool.cpp +++ b/eeschema/tools/sch_move_tool.cpp @@ -430,7 +430,7 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent ) } else { - addJunctionsIfNeeded( selection ); + m_toolMgr->RunAction( EE_ACTIONS::addNeededJunctions, true, &selection ); m_frame->SchematicCleanUp(); m_frame->TestDanglingEnds(); @@ -534,60 +534,6 @@ void SCH_MOVE_TOOL::getConnectedDragItems( SCH_ITEM* aOriginalItem, wxPoint aPoi } -void SCH_MOVE_TOOL::addJunctionsIfNeeded( EE_SELECTION& aSelection ) -{ - std::vector< wxPoint > pts; - std::vector< wxPoint > connections; - - m_frame->GetSchematicConnections( connections ); - - for( unsigned ii = 0; ii < aSelection.GetSize(); ii++ ) - { - SCH_ITEM* item = static_cast( aSelection.GetItem( ii ) ); - std::vector< wxPoint > new_pts; - - if( !item->IsConnectable() ) - continue; - - item->GetConnectionPoints( new_pts ); - pts.insert( pts.end(), new_pts.begin(), new_pts.end() ); - - // If the item is a line, we also add any connection points from the rest of the schematic - // that terminate on the line after it is moved. - if( item->Type() == SCH_LINE_T ) - { - SCH_LINE* line = (SCH_LINE*) item; - for( auto i : connections ) - { - if( IsPointOnSegment( line->GetStartPoint(), line->GetEndPoint(), i ) ) - pts.push_back( i ); - } - } - else - { - // Clean up any wires that short non-wire connections in the list - for( auto point = new_pts.begin(); point != new_pts.end(); point++ ) - { - for( auto second_point = point + 1; second_point != new_pts.end(); second_point++ ) - m_frame->TrimWire( *point, *second_point ); - } - } - } - - // We always have some overlapping connection points. Drop duplicates here - std::sort( pts.begin(), pts.end(), []( const wxPoint& a, const wxPoint& b ) -> bool - { return a.x < b.x || (a.x == b.x && a.y < b.y); } ); - - pts.erase( unique( pts.begin(), pts.end() ), pts.end() ); - - for( auto point : pts ) - { - if( m_frame->GetScreen()->IsJunctionNeeded( point, true ) ) - m_frame->AddJunction( point, true, false ); - } -} - - void SCH_MOVE_TOOL::moveItem( EDA_ITEM* aItem, VECTOR2I aDelta, bool isDrag ) { switch( aItem->Type() ) diff --git a/eeschema/tools/sch_move_tool.h b/eeschema/tools/sch_move_tool.h index 9de23e889c..7d1ea1fdb8 100644 --- a/eeschema/tools/sch_move_tool.h +++ b/eeschema/tools/sch_move_tool.h @@ -56,10 +56,6 @@ private: ///> Connected wires are included with any un-connected ends flagged (STARTPOINT or ENDPOINT). void getConnectedDragItems( SCH_ITEM* aOriginalItem, wxPoint aPoint, EDA_ITEMS& aList ); - ///> Adds junctions if needed to each item in the list after they have been - ///> moved. - void addJunctionsIfNeeded( EE_SELECTION& aSelection ); - ///> Sets up handlers for various events. void setTransitions() override;