bool SCH_SCREEN::BreakSegment( const wxPoint& aPoint ) { SCH_LINE* segment; SCH_LINE* newSegment; bool brokenSegments = false; for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() ) { if( (item->Type() != SCH_LINE_T) || (item->GetLayer() == LAYER_NOTES) ) continue; segment = (SCH_LINE*) item; if( !segment->HitTest( aPoint, 0 ) || segment->IsEndPoint( aPoint ) ) continue; // Break the segment at aPoint and create a new segment. newSegment = new SCH_LINE( *segment ); newSegment->SetStartPoint( aPoint ); segment->SetEndPoint( aPoint ); m_drawList.Insert( newSegment, segment->Next() ); item = newSegment; brokenSegments = true; } return brokenSegments; }
void AddMenusForWire( wxMenu* PopMenu, SCH_LINE* Wire, SCH_EDIT_FRAME* frame ) { SCH_SCREEN* screen = frame->GetScreen(); wxPoint pos = frame->GetCrossHairPosition(); wxString msg; if( Wire == NULL ) { msg = AddHotkeyName( _( "Begin Wire" ), g_Schematic_Hokeys_Descr, HK_BEGIN_WIRE ); AddMenuItem( PopMenu, ID_POPUP_SCH_BEGIN_WIRE, msg, KiBitmap( add_line_xpm ) ); return; } bool is_new = Wire->IsNew(); if( is_new ) { msg = AddHotkeyName( _( "Wire End" ), g_Schematic_Hokeys_Descr, HK_END_CURR_LINEWIREBUS ); AddMenuItem( PopMenu, ID_POPUP_END_LINE, msg, KiBitmap( checked_ok_xpm ) ); return; } msg = AddHotkeyName( _( "Drag Wire" ), g_Schematic_Hokeys_Descr, HK_DRAG ); AddMenuItem( PopMenu, ID_SCH_DRAG_ITEM, msg, KiBitmap( move_track_xpm ) ); PopMenu->AppendSeparator(); msg = AddHotkeyName( _( "Delete Wire" ), g_Schematic_Hokeys_Descr, HK_DELETE ); AddMenuItem( PopMenu, ID_POPUP_SCH_DELETE, msg, KiBitmap( delete_xpm ) ); AddMenuItem( PopMenu, ID_POPUP_SCH_DELETE_NODE, _( "Delete Node" ), KiBitmap( delete_node_xpm ) ); AddMenuItem( PopMenu, ID_POPUP_SCH_DELETE_CONNECTION, _( "Delete Connection" ), KiBitmap( delete_connection_xpm ) ); SCH_LINE* line = screen->GetWireOrBus( frame->GetCrossHairPosition() ); if( line && !line->IsEndPoint( frame->GetCrossHairPosition() ) ) AddMenuItem( PopMenu, ID_POPUP_SCH_BREAK_WIRE, _( "Break Wire" ), KiBitmap( break_line_xpm ) ); PopMenu->AppendSeparator(); msg = AddHotkeyName( _( "Add Junction" ), g_Schematic_Hokeys_Descr, HK_ADD_JUNCTION ); AddMenuItem( PopMenu, ID_POPUP_SCH_ADD_JUNCTION, msg, KiBitmap( add_junction_xpm ) ); msg = AddHotkeyName( _( "Add Label" ), g_Schematic_Hokeys_Descr, HK_ADD_LABEL ); AddMenuItem( PopMenu, ID_POPUP_SCH_ADD_LABEL, msg, KiBitmap( add_line_label_xpm ) ); // Add global label command only if the cursor is over one end of the wire. if( Wire->IsEndPoint( pos ) ) AddMenuItem( PopMenu, ID_POPUP_SCH_ADD_GLABEL, _( "Add Global Label" ), KiBitmap( add_glabel_xpm ) ); }
bool SCH_COLLECTOR::IsDraggableJunction() const { int wireEndCount = 0; int wireMidPoint = 0; int junctionCount = 0; for( size_t i = 0; i < m_List.size(); i++ ) { SCH_ITEM* item = (SCH_ITEM*) m_List[ i ]; KICAD_T type = item->Type(); if( type == SCH_JUNCTION_T ) { junctionCount++; continue; } if( type == SCH_LINE_T ) { if( item->GetLayer() != LAYER_WIRE ) return false; SCH_LINE* line = (SCH_LINE*) item; if( line->IsEndPoint( m_RefPos ) ) wireEndCount++; else wireMidPoint++; continue; } // Any other item types indicate that this collection is not a draggable junction. return false; } return (wireEndCount >= 3) || ((wireEndCount >= 1) && (wireMidPoint == 1)) || ((wireMidPoint >= 2) && (junctionCount == 1)); }
int SCH_SCREEN::GetConnection( const wxPoint& aPosition, PICKED_ITEMS_LIST& aList, bool aFullConnection ) { SCH_ITEM* item; EDA_ITEM* tmp; EDA_ITEMS list; // Clear flags member for all items. ClearDrawingState(); BreakSegmentsOnJunctions(); if( GetNode( aPosition, list ) == 0 ) return 0; for( size_t i = 0; i < list.size(); i++ ) { item = (SCH_ITEM*) list[ i ]; item->SetFlags( SELECTEDNODE | STRUCT_DELETED ); /* Put this structure in the picked list: */ ITEM_PICKER picker( item, UR_DELETED ); aList.PushItem( picker ); } // Mark all wires, junctions, .. connected to the item(s) found. if( aFullConnection ) { SCH_LINE* segment; for( item = m_drawList.begin(); item; item = item->Next() ) { if( !(item->GetFlags() & SELECTEDNODE) ) continue; if( item->Type() != SCH_LINE_T ) continue; MarkConnections( (SCH_LINE*) item ); } // Search all attached wires (i.e wire with one new dangling end ) for( item = m_drawList.begin(); item; item = item->Next() ) { bool noconnect = false; if( item->GetFlags() & STRUCT_DELETED ) continue; // Already seen if( !(item->GetFlags() & CANDIDATE) ) continue; // not a candidate if( item->Type() != SCH_LINE_T ) continue; item->SetFlags( SKIP_STRUCT ); segment = (SCH_LINE*) item; /* If the wire start point is connected to a wire that was already found * and now is not connected, add the wire to the list. */ for( tmp = m_drawList.begin(); tmp; tmp = tmp->Next() ) { // Ensure tmp is a previously deleted segment: if( ( tmp->GetFlags() & STRUCT_DELETED ) == 0 ) continue; if( tmp->Type() != SCH_LINE_T ) continue; SCH_LINE* testSegment = (SCH_LINE*) tmp; // Test for segment connected to the previously deleted segment: if( testSegment->IsEndPoint( segment->GetStartPoint() ) ) break; } // when tmp != NULL, segment is a new candidate: // put it in deleted list if // the start point is not connected to an other item (like pin) if( tmp && !CountConnectedItems( segment->GetStartPoint(), true ) ) noconnect = true; /* If the wire end point is connected to a wire that has already been found * and now is not connected, add the wire to the list. */ for( tmp = m_drawList.begin(); tmp; tmp = tmp->Next() ) { // Ensure tmp is a previously deleted segment: if( ( tmp->GetFlags() & STRUCT_DELETED ) == 0 ) continue; if( tmp->Type() != SCH_LINE_T ) continue; SCH_LINE* testSegment = (SCH_LINE*) tmp; // Test for segment connected to the previously deleted segment: if( testSegment->IsEndPoint( segment->GetEndPoint() ) ) break; } // when tmp != NULL, segment is a new candidate: // put it in deleted list if // the end point is not connected to an other item (like pin) if( tmp && !CountConnectedItems( segment->GetEndPoint(), true ) ) noconnect = true; item->ClearFlags( SKIP_STRUCT ); if( noconnect ) { item->SetFlags( STRUCT_DELETED ); ITEM_PICKER picker( item, UR_DELETED ); aList.PushItem( picker ); item = m_drawList.begin(); } } // Get redundant junctions (junctions which connect < 3 end wires // and no pin) for( item = m_drawList.begin(); item; item = item->Next() ) { if( item->GetFlags() & STRUCT_DELETED ) continue; if( !(item->GetFlags() & CANDIDATE) ) continue; if( item->Type() != SCH_JUNCTION_T ) continue; SCH_JUNCTION* junction = (SCH_JUNCTION*) item; if( CountConnectedItems( junction->GetPosition(), false ) <= 2 ) { item->SetFlags( STRUCT_DELETED ); ITEM_PICKER picker( item, UR_DELETED ); aList.PushItem( picker ); } } for( item = m_drawList.begin(); item; item = item->Next() ) { if( item->GetFlags() & STRUCT_DELETED ) continue; if( item->Type() != SCH_LABEL_T ) continue; tmp = GetWireOrBus( ( (SCH_TEXT*) item )->GetPosition() ); if( tmp && tmp->GetFlags() & STRUCT_DELETED ) { item->SetFlags( STRUCT_DELETED ); ITEM_PICKER picker( item, UR_DELETED ); aList.PushItem( picker ); } } } ClearDrawingState(); return aList.GetCount(); }