eeschema: Insert junctions when repeating

This is the v6 analog to 697234dd5

Fixes: lp:1832253
* https://bugs.launchpad.net/kicad/+bug/1832253
This commit is contained in:
Seth Hillbrand 2019-06-18 20:10:21 -07:00
parent 1ef2f84f72
commit e16bf40e60
7 changed files with 77 additions and 59 deletions

View File

@ -609,6 +609,10 @@ TOOL_ACTION EE_ACTIONS::toggleForceHV( "eeschema.EditorControl.forceHVLines",
// SCH_LINE_WIRE_BUS_TOOL // 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", TOOL_ACTION EE_ACTIONS::drawWire( "eeschema.InteractiveDrawingLineWireBus.drawWires",
AS_GLOBAL, AS_GLOBAL,
'W', LEGACY_HK_NAME( "Begin Wire" ), 'W', LEGACY_HK_NAME( "Begin Wire" ),

View File

@ -73,6 +73,7 @@ public:
static TOOL_ACTION unlock; static TOOL_ACTION unlock;
// Schematic Tools // Schematic Tools
static TOOL_ACTION addNeededJunctions;
static TOOL_ACTION pickerTool; static TOOL_ACTION pickerTool;
static TOOL_ACTION placeSymbol; static TOOL_ACTION placeSymbol;
static TOOL_ACTION placePower; static TOOL_ACTION placePower;

View File

@ -837,7 +837,13 @@ int SCH_EDIT_TOOL::RepeatDrawItem( const TOOL_EVENT& aEvent )
newItem->ClearFlags(); newItem->ClearFlags();
if( newItem->IsConnectable() ) if( newItem->IsConnectable() )
{
auto selection = m_selectionTool->GetSelection();
m_toolMgr->RunAction( EE_ACTIONS::addNeededJunctions, true, &selection );
m_frame->SchematicCleanUp();
m_frame->TestDanglingEnds(); m_frame->TestDanglingEnds();
}
// newItem newItem, now that it has been moved, thus saving new position. // newItem newItem, now that it has been moved, thus saving new position.
m_frame->SaveCopyForRepeatItem( newItem ); m_frame->SaveCopyForRepeatItem( newItem );

View File

@ -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<EE_SELECTION*>();
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<SCH_ITEM*>( 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 );
}
return 0;
}
void SCH_LINE_WIRE_BUS_TOOL::setTransitions() 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::drawWire.MakeEvent() );
Go( &SCH_LINE_WIRE_BUS_TOOL::DrawSegments, EE_ACTIONS::drawBus.MakeEvent() ); Go( &SCH_LINE_WIRE_BUS_TOOL::DrawSegments, EE_ACTIONS::drawBus.MakeEvent() );
Go( &SCH_LINE_WIRE_BUS_TOOL::DrawSegments, EE_ACTIONS::drawLines.MakeEvent() ); Go( &SCH_LINE_WIRE_BUS_TOOL::DrawSegments, EE_ACTIONS::drawLines.MakeEvent() );

View File

@ -74,6 +74,11 @@ public:
static bool IsDrawingBus( const SELECTION& aSelection ); static bool IsDrawingBus( const SELECTION& aSelection );
static bool IsDrawingLineWireOrBus( 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: private:
int doDrawSegments( int aType, SCH_LINE* aSegment, bool aImmediateMode ); int doDrawSegments( int aType, SCH_LINE* aSegment, bool aImmediateMode );
SCH_LINE* startSegments( int aType, const VECTOR2D& aPos ); SCH_LINE* startSegments( int aType, const VECTOR2D& aPos );

View File

@ -430,7 +430,7 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
} }
else else
{ {
addJunctionsIfNeeded( selection ); m_toolMgr->RunAction( EE_ACTIONS::addNeededJunctions, true, &selection );
m_frame->SchematicCleanUp(); m_frame->SchematicCleanUp();
m_frame->TestDanglingEnds(); 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<SCH_ITEM*>( 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 ) void SCH_MOVE_TOOL::moveItem( EDA_ITEM* aItem, VECTOR2I aDelta, bool isDrag )
{ {
switch( aItem->Type() ) switch( aItem->Type() )

View File

@ -56,10 +56,6 @@ private:
///> Connected wires are included with any un-connected ends flagged (STARTPOINT or ENDPOINT). ///> Connected wires are included with any un-connected ends flagged (STARTPOINT or ENDPOINT).
void getConnectedDragItems( SCH_ITEM* aOriginalItem, wxPoint aPoint, EDA_ITEMS& aList ); 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. ///> Sets up handlers for various events.
void setTransitions() override; void setTransitions() override;