bool SCH_SCREEN::BreakSegmentsOnJunctions()
{
    bool brokenSegments = false;

    for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
    {
        if( item->Type() == SCH_JUNCTION_T )
        {
            SCH_JUNCTION* junction = ( SCH_JUNCTION* ) item;

            if( BreakSegment( junction->GetPosition() ) )
                brokenSegments = true;
        }
        else
        {
            SCH_BUS_ENTRY_BASE* busEntry = dynamic_cast<SCH_BUS_ENTRY_BASE*>( item );
            if( busEntry )
            {
                if( BreakSegment( busEntry->GetPosition() )
                 || BreakSegment( busEntry->m_End() ) )
                    brokenSegments = true;
            }
        }
    }

    return brokenSegments;
}
SCH_JUNCTION* SCH_EDIT_FRAME::AddJunction( wxDC* aDC, const wxPoint& aPosition,
                                           bool aPutInUndoList )
{
    SCH_JUNCTION* junction = new SCH_JUNCTION( aPosition );

    SetRepeatItem( junction );

    m_canvas->CrossHairOff( aDC );     // Erase schematic cursor
    junction->Draw( m_canvas, aDC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE );
    m_canvas->CrossHairOn( aDC );      // Display schematic cursor

    if( aPutInUndoList )
    {
        GetScreen()->Append( junction );
        SaveCopyInUndoList( junction, UR_NEW );
        OnModify();
    }

    return junction;
}
void SCH_SCREEN::MarkConnections( SCH_LINE* aSegment )
{
    wxCHECK_RET( (aSegment) && (aSegment->Type() == SCH_LINE_T),
                 wxT( "Invalid object pointer." ) );

    for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
    {
        if( item->GetFlags() & CANDIDATE )
            continue;

        if( item->Type() == SCH_JUNCTION_T )
        {
            SCH_JUNCTION* junction = (SCH_JUNCTION*) item;

            if( aSegment->IsEndPoint( junction->GetPosition() ) )
                item->SetFlags( CANDIDATE );

            continue;
        }

        if( item->Type() != SCH_LINE_T )
            continue;

        SCH_LINE* segment = (SCH_LINE*) item;

        if( aSegment->IsEndPoint( segment->GetStartPoint() )
            && !GetPin( segment->GetStartPoint(), NULL, true ) )
        {
            item->SetFlags( CANDIDATE );
            MarkConnections( segment );
        }

        if( aSegment->IsEndPoint( segment->GetEndPoint() )
            && !GetPin( segment->GetEndPoint(), NULL, true ) )
        {
            item->SetFlags( CANDIDATE );
            MarkConnections( segment );
        }
    }
}
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();
}