Commit aaa1cc3e authored by Wayne Stambaugh's avatar Wayne Stambaugh
Browse files

Eeschema object list and other minor improvements.

* Convert Eeschema from manually linked list to DLIST for storing
  SCH_ITEM objects.
* Add helper functions to SCH_SCREEN for appending list of SCH_ITEM
  objects.
* Fix bug in wire editing code for accurate undo/redo behavior.
* Add member to DLIST to append another DLIST.
* Other minor code cleaning.
parent a1ff3261
Loading
Loading
Loading
Loading
+3 −5
Original line number Original line Diff line number Diff line
@@ -2,7 +2,6 @@
 * This program source code file is part of KiCad, a free EDA CAD application.
 * This program source code file is part of KiCad, a free EDA CAD application.
 *
 *
 * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
 * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
 * Copyright (C) 2008-20011 Wayne Stambaugh <stambaughw@verizon.net>
 * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
 * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
 *
 *
 * This program is free software; you can redistribute it and/or
 * This program is free software; you can redistribute it and/or
@@ -217,15 +216,14 @@ EDA_ITEM& EDA_ITEM::operator=( const EDA_ITEM& aItem )
{
{
    if( &aItem != this )
    if( &aItem != this )
    {
    {
        m_StructType = aItem.Type();
        m_Image = aItem.m_Image;
        Pnext = aItem.Pnext;
        Pback = aItem.Pback;
        m_StructType = aItem.m_StructType;
        m_StructType = aItem.m_StructType;
        m_Parent = aItem.m_Parent;
        m_Parent = aItem.m_Parent;
        m_Son = aItem.m_Son;
        m_Son = aItem.m_Son;
        m_Flags = aItem.m_Flags;
        m_Flags = aItem.m_Flags;
        SetTimeStamp( aItem.m_TimeStamp );
        m_TimeStamp = aItem.m_TimeStamp;
        m_Status = aItem.m_Status;
        m_Status = aItem.m_Status;
        m_forceVisible = aItem.m_forceVisible;
    }
    }


    return *this;
    return *this;
+30 −0
Original line number Original line Diff line number Diff line
@@ -85,6 +85,36 @@ void DHEAD::append( EDA_ITEM* aNewElement )
}
}




void DHEAD::append( DHEAD& aList )
{
    wxCHECK_RET( aList.GetCount() != 0, wxT( "Attempt to append empty list." ) );

    // Change the item's list to me.
    for( EDA_ITEM* item = aList.first;  item != NULL;  item = item->Next() )
        item->SetList( this );

    if( first )       // list is not empty, set last item's next to the first item in aList
    {
        wxCHECK_RET( last != NULL, wxT( "Last list element not set." ) );

        last->SetNext( aList.first );
        aList.first->SetBack( last );
        last = aList.last;
    }
    else              // list is empty, first and last are same as aList
    {
        first = aList.first;
        last  = aList.last;
    }

    count += aList.count;

    aList.count = 0;
    aList.first = NULL;
    aList.last = NULL;
}


void DHEAD::insert( EDA_ITEM* aNewElement, EDA_ITEM* aAfterMe )
void DHEAD::insert( EDA_ITEM* aNewElement, EDA_ITEM* aAfterMe )
{
{
    wxASSERT( aNewElement != NULL );
    wxASSERT( aNewElement != NULL );
+0 −18
Original line number Original line Diff line number Diff line
@@ -2,7 +2,6 @@
 * This program source code file is part of KiCad, a free EDA CAD application.
 * This program source code file is part of KiCad, a free EDA CAD application.
 *
 *
 * Copyright (C) 2006 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
 * Copyright (C) 2006 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
 * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
 * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
 * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
 *
 *
 * This program is free software; you can redistribute it and/or
 * This program is free software; you can redistribute it and/or
@@ -102,23 +101,6 @@ bool SCH_ITEM::operator < ( const SCH_ITEM& aItem ) const
}
}




SCH_ITEM& SCH_ITEM::operator=( const SCH_ITEM& aItem )
{
    wxCHECK_MSG( Type() == aItem.Type(), *this,
                 wxT( "Cannot assign object type " ) + aItem.GetClass() + wxT( " to type " ) +
                 GetClass() );

    if( &aItem != this )
    {
        EDA_ITEM::operator=( aItem );
        m_Layer = aItem.m_Layer;
        m_connections = aItem.m_connections;
    }

    return *this;
}


void SCH_ITEM::doPlot( PLOTTER* aPlotter )
void SCH_ITEM::doPlot( PLOTTER* aPlotter )
{
{
    wxFAIL_MSG( wxT( "doPlot() method not implemented for class " ) + GetClass() );
    wxFAIL_MSG( wxT( "doPlot() method not implemented for class " ) + GetClass() );
+1 −2
Original line number Original line Diff line number Diff line
@@ -559,8 +559,7 @@ void SCH_EDIT_FRAME::PasteListOfItems( wxDC* DC )


        SetSchItemParent( Struct, GetScreen() );
        SetSchItemParent( Struct, GetScreen() );
        Struct->Draw( m_canvas, DC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE );
        Struct->Draw( m_canvas, DC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE );
        Struct->SetNext( GetScreen()->GetDrawItems() );
        GetScreen()->Append( Struct );
        GetScreen()->SetDrawItems( Struct );
    }
    }


    SaveCopyInUndoList( picklist, UR_NEW );
    SaveCopyInUndoList( picklist, UR_NEW );
+146 −205
Original line number Original line Diff line number Diff line
@@ -2,7 +2,6 @@
 * This program source code file is part of KiCad, a free EDA CAD application.
 * This program source code file is part of KiCad, a free EDA CAD application.
 *
 *
 * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
 * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
 * Copyright (C) 2008-2011 Wayne Stambaugh <stambaughw@verizon.net>
 * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
 * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
 *
 *
 * This program is free software; you can redistribute it and/or
 * This program is free software; you can redistribute it and/or
@@ -51,8 +50,10 @@
static void AbortCreateNewLine( EDA_DRAW_PANEL* Panel, wxDC* DC );
static void AbortCreateNewLine( EDA_DRAW_PANEL* Panel, wxDC* DC );
static void ComputeBreakPoint( SCH_LINE* segment, const wxPoint& new_pos );
static void ComputeBreakPoint( SCH_LINE* segment, const wxPoint& new_pos );


SCH_ITEM* s_OldWiresList;
static DLIST< SCH_ITEM > s_wires;
wxPoint   s_ConnexionStartPoint;
static DLIST< SCH_ITEM > s_oldWires;

static wxPoint s_startPoint;




/**
/**
@@ -61,19 +62,17 @@ wxPoint s_ConnexionStartPoint;
static void DrawSegment( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
static void DrawSegment( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
                         bool aErase )
                         bool aErase )
{
{
    SCH_LINE* CurrentLine = (SCH_LINE*) aPanel->GetScreen()->GetCurItem();
    SCH_LINE* segment;
    SCH_LINE* segment;
    int color;
    int color;


    if( CurrentLine == NULL )
    if( s_wires.GetCount() == 0 )
        return;
        return;


    color = ReturnLayerColor( CurrentLine->GetLayer() ) ^ HIGHLIGHT_FLAG;
    segment = (SCH_LINE*) s_wires.begin();
    color = ReturnLayerColor( segment->GetLayer() ) ^ HIGHLIGHT_FLAG;


    if( aErase )
    if( aErase )
    {
    {
        segment = CurrentLine;

        while( segment )
        while( segment )
        {
        {
            if( !segment->IsNull() )  // Redraw if segment length != 0
            if( !segment->IsNull() )  // Redraw if segment length != 0
@@ -86,11 +85,11 @@ static void DrawSegment( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosi
    wxPoint endpos = aPanel->GetScreen()->GetCrossHairPosition();
    wxPoint endpos = aPanel->GetScreen()->GetCrossHairPosition();


    if( g_HVLines ) /* Coerce the line to vertical or horizontal one: */
    if( g_HVLines ) /* Coerce the line to vertical or horizontal one: */
        ComputeBreakPoint( CurrentLine, endpos );
        ComputeBreakPoint( (SCH_LINE*) s_wires.GetLast()->Back(), endpos );
    else
    else
        CurrentLine->SetEndPoint( endpos );
        ( (SCH_LINE*) s_wires.GetLast() )->SetEndPoint( endpos );


    segment = CurrentLine;
    segment = (SCH_LINE*) s_wires.begin();


    while( segment )
    while( segment )
    {
    {
@@ -104,257 +103,193 @@ static void DrawSegment( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosi


void SCH_EDIT_FRAME::BeginSegment( wxDC* DC, int type )
void SCH_EDIT_FRAME::BeginSegment( wxDC* DC, int type )
{
{
    SCH_LINE* oldsegment, * newsegment, * nextsegment;
    SCH_LINE* segment;
    SCH_LINE* nextSegment;
    wxPoint   cursorpos = GetScreen()->GetCrossHairPosition();
    wxPoint   cursorpos = GetScreen()->GetCrossHairPosition();


    if( GetScreen()->GetCurItem() && (GetScreen()->GetCurItem()->GetFlags() == 0) )
    segment = (SCH_LINE*) GetScreen()->GetCurItem();
        GetScreen()->SetCurItem( NULL );

    if( GetScreen()->GetCurItem() )
    {
        switch( GetScreen()->GetCurItem()->Type() )
        {
        case SCH_LINE_T:
        case SCH_POLYLINE_T:
            break;

        default:
            return;
        }
    }

    oldsegment = newsegment = (SCH_LINE*) GetScreen()->GetCurItem();


    if( !newsegment )  /* first point : Create first wire or bus */
    if( !segment )  /* first point : Create first wire or bus */
    {
    {
        s_ConnexionStartPoint = cursorpos;
        s_startPoint = cursorpos;
        s_OldWiresList = GetScreen()->ExtractWires( true );
        GetScreen()->ExtractWires( s_oldWires, true );
        GetScreen()->SchematicCleanUp( m_canvas );
        GetScreen()->SchematicCleanUp( m_canvas );


        switch( type )
        switch( type )
        {
        {
        default:
        default:
            newsegment = new SCH_LINE( cursorpos, LAYER_NOTES );
            segment = new SCH_LINE( cursorpos, LAYER_NOTES );
            break;
            break;


        case LAYER_WIRE:
        case LAYER_WIRE:
            newsegment = new SCH_LINE( cursorpos, LAYER_WIRE );
            segment = new SCH_LINE( cursorpos, LAYER_WIRE );


            /* A junction will be created later, when we'll know the
            /* A junction will be created later, when we'll know the
             * segment end position, and if the junction is really needed */
             * segment end position, and if the junction is really needed */
            break;
            break;


        case LAYER_BUS:
        case LAYER_BUS:
            newsegment = new SCH_LINE( cursorpos, LAYER_BUS );
            segment = new SCH_LINE( cursorpos, LAYER_BUS );
            break;
            break;
        }
        }


        newsegment->SetFlags( IS_NEW );
        segment->SetFlags( IS_NEW );
        s_wires.PushBack( segment );
        GetScreen()->SetCurItem( segment );


        if( g_HVLines ) // We need 2 segments to go from a given start pin to an end point
        // We need 2 segments to go from a given start pin to an end point when the horizontal
        // and vertical lines only switch is on.
        if( g_HVLines )
        {
        {
            nextsegment = new SCH_LINE( *newsegment );
            nextSegment = new SCH_LINE( *segment );
            nextsegment->SetFlags( IS_NEW );
            nextSegment->SetFlags( IS_NEW );
            newsegment->SetNext( nextsegment );
            s_wires.PushBack( nextSegment );
            nextsegment->SetBack( newsegment );
            GetScreen()->SetCurItem( nextSegment );
        }
        }


        GetScreen()->SetCurItem( newsegment );
        m_canvas->SetMouseCapture( DrawSegment, AbortCreateNewLine );
        m_canvas->SetMouseCapture( DrawSegment, AbortCreateNewLine );
        m_itemToRepeat = NULL;
        m_itemToRepeat = NULL;
    }
    }
    else    // A segment is in progress: terminates the current segment and add a new segment.
    else    // A segment is in progress: terminates the current segment and add a new segment.
    {
    {
        nextsegment = oldsegment->Next();
        SCH_LINE* prevSegment = (SCH_LINE*) segment->Back();

        wxLogDebug( wxT( "Adding new segment after " ) + segment->GetSelectMenuText() );


        if( !g_HVLines )
        if( !g_HVLines )
        {
        {
            // if only one segment is needed and it has length = 0, do not create a new one.
            // If only one segment is needed and it has a zero length, do not create a new one.
            if( oldsegment->IsNull() )
            if( segment->IsNull() )
                return;
                return;
        }
        }
        else
        else
        {
        {
            /* if we want 2 segment and the last two have len = 0, do not
            wxCHECK_RET( prevSegment != NULL, wxT( "Failed to create second line segment." ) );
             * create a new one */

            if( oldsegment->IsNull() && nextsegment && nextsegment->IsNull() )
            // If two segments are required and they both have zero length, do not
            // create a new one.
            if( prevSegment && prevSegment->IsNull() && segment->IsNull() )
                return;
                return;
        }
        }


        m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
        m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );


        /* Creates the new segment, or terminates the command
        // Terminate the command if the end point is on a pin, junction, or another wire or bus.
         * if the end point is on a pin, junction or an other wire or bus */
        if( GetScreen()->IsTerminalPoint( cursorpos, segment->GetLayer() ) )
        if( GetScreen()->IsTerminalPoint( cursorpos, oldsegment->GetLayer() ) )
        {
        {
            EndSegment( DC );
            EndSegment( DC );
            return;
            return;
        }
        }


        oldsegment->SetNext( GetScreen()->GetDrawItems() );
        // Create a new segment, and chain it after the current new segment.
        GetScreen()->SetDrawItems( oldsegment );
        nextSegment = new SCH_LINE( *segment );
        m_canvas->CrossHairOff( DC );     // Erase schematic cursor
        nextSegment->SetStartPoint( cursorpos );
        oldsegment->Draw( m_canvas, DC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE );
        s_wires.PushBack( nextSegment );
        m_canvas->CrossHairOn( DC );      // Display schematic cursor

        /* Create a new segment, and chain it after the current new segment */
        if( nextsegment )
        {
            newsegment = new SCH_LINE( *nextsegment );
            nextsegment->SetStartPoint( newsegment->GetEndPoint() );
            nextsegment->SetNext( NULL );
            nextsegment->SetBack( newsegment );
            newsegment->SetNext( nextsegment );
            newsegment->SetBack( NULL );
        }
        else
        {
            newsegment = new SCH_LINE( *oldsegment );
            newsegment->SetStartPoint( oldsegment->GetEndPoint() );
        }


        newsegment->SetEndPoint( cursorpos );
        segment->SetEndPoint( cursorpos );
        oldsegment->ClearFlags( IS_NEW );
        segment->ClearFlags( IS_NEW );
        oldsegment->SetFlags( SELECTED );
        segment->SetFlags( SELECTED );
        newsegment->SetFlags( IS_NEW );
        nextSegment->SetFlags( IS_NEW );
        GetScreen()->SetCurItem( newsegment );
        GetScreen()->SetCurItem( nextSegment );
        m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
        m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );

        /* This is the first segment: Now we know the start segment position.
         * Create a junction if needed. Note: a junction can be needed later,
         * if the new segment is merged (after a cleanup) with an older one
         * (tested when the connection will be finished)*/
        if( oldsegment->GetStartPoint() == s_ConnexionStartPoint )
        {
            if( GetScreen()->IsJunctionNeeded( s_ConnexionStartPoint ) )
                AddJunction( DC, s_ConnexionStartPoint );
        }
    }
    }
}
}




void SCH_EDIT_FRAME::EndSegment( wxDC* DC )
void SCH_EDIT_FRAME::EndSegment( wxDC* DC )
{
{
    SCH_LINE* firstsegment = (SCH_LINE*) GetScreen()->GetCurItem();
    SCH_SCREEN* screen = GetScreen();
    SCH_LINE* lastsegment = firstsegment;
    SCH_LINE* segment = (SCH_LINE*) screen->GetCurItem();
    SCH_LINE* segment;

    if( firstsegment == NULL )
        return;


    if( !firstsegment->IsNew() )
    if( segment == NULL || segment->Type() != SCH_LINE_T || !segment->IsNew() )
        return;
        return;


    /* Delete Null segments and Put line it in Drawlist */
    // Delete zero length segments and clear item flags.
    lastsegment = firstsegment;
    SCH_ITEM* item = s_wires.begin();


    while( lastsegment )
    while( item )
    {
    {
        SCH_LINE* nextsegment = lastsegment->Next();
        item->ClearFlags();


        if( lastsegment->IsNull() )
        wxCHECK_RET( item->Type() == SCH_LINE_T, wxT( "Unexpected object type in wire list." ) );
        {
            SCH_LINE* previous_segment = lastsegment->Back();


            if( firstsegment == lastsegment )
        segment = (SCH_LINE*) item;
                firstsegment = nextsegment;


            if( nextsegment )
        if( segment->IsNull() )
                nextsegment->SetBack( NULL );
        {
            wxLogDebug( wxT( "Removing null segment: " ) + segment->GetSelectMenuText() );


            if( previous_segment )
            SCH_ITEM* previousSegment = item->Back();
                previous_segment->SetNext( nextsegment );


            delete lastsegment;
            delete s_wires.Remove( item );
        }


        lastsegment = nextsegment;
            if( previousSegment == NULL )
                item = s_wires.begin();
            else
                item = previousSegment;
        }
        }


    /* put the segment list to the main linked list */
        item = item->Next();
    segment = lastsegment = firstsegment;

    while( segment )
    {
        lastsegment = segment;
        segment     = segment->Next();
        lastsegment->SetNext( GetScreen()->GetDrawItems() );
        GetScreen()->SetDrawItems( lastsegment );
    }
    }


    if( s_wires.GetCount() == 0 )
        return;

    // Get the last non-null wire.
    m_itemToRepeat = segment = (SCH_LINE*) s_wires.GetLast();
    screen->SetCurItem( NULL );
    m_canvas->EndMouseCapture( -1, -1, wxEmptyString, false );
    m_canvas->EndMouseCapture( -1, -1, wxEmptyString, false );
    GetScreen()->SetCurItem( NULL );


    wxPoint end_point, alt_end_point;
    DLIST< SCH_ITEM > tmp;


    /* A junction can be needed to connect the last segment
    for( item = s_wires.begin();  item != NULL;  item = item->Next() )
     *  usually to m_end coordinate.
        tmp.PushBack( (SCH_ITEM*) item->Clone() );
     *  But if the last segment is removed by a cleanup, because of redundancy,
     * a junction can be needed to connect the previous segment m_end
     * coordinate with is also the lastsegment->m_start coordinate */
    if( lastsegment )
    {
        end_point     = lastsegment->GetEndPoint();
        alt_end_point = lastsegment->GetStartPoint();
    }


    GetScreen()->SchematicCleanUp( m_canvas );
    // Temporarily add the new segments to the schematic item list to test if any
    // junctions are required.
    screen->Append( tmp );


    /* clear flags and find last segment entered, for repeat function */
    // Correct and remove segments that need merged.
    segment = (SCH_LINE*) GetScreen()->GetDrawItems();
    screen->SchematicCleanUp( m_canvas, DC );


    while( segment )
    // A junction may be needed to connect the last segment.  If the last segment was
    {
    // removed by a cleanup, a junction may be needed to connect the segment's end point
        if( segment->GetFlags() )
    // which is also the same as the previous segment's start point.
        {
    if( screen->IsJunctionNeeded( segment->GetEndPoint() ) )
            if( !m_itemToRepeat )
        s_wires.Append( AddJunction( DC, segment->GetEndPoint() ) );
                m_itemToRepeat = segment;
    else if( screen->IsJunctionNeeded( segment->GetStartPoint() ) )
        }
        s_wires.Append( AddJunction( DC, segment->GetStartPoint() ) );


        segment->ClearFlags();
    // Automatically place a junction on the start point if necessary because the cleanup
        segment = segment->Next();
    // can suppress intermediate points by merging wire segments.
    }
    if( screen->IsJunctionNeeded( s_startPoint ) )
        s_wires.Append( AddJunction( DC, s_startPoint ) );


    // Automatic place of a junction on the end point, if needed
    // Make a copy of the original wires, buses, and junctions.
    if( lastsegment )
    for( item = s_oldWires.begin();  item != NULL;  item = item->Next() )
    {
        tmp.PushBack( (SCH_ITEM*) item->Clone() );
        if( GetScreen()->IsJunctionNeeded( end_point ) )
            AddJunction( DC, end_point );
        else if( GetScreen()->IsJunctionNeeded( alt_end_point ) )
            AddJunction( DC, alt_end_point );
    }


    /* Automatic place of a junction on the start point if necessary because
    // Restore the old wires.
     * the cleanup can suppress intermediate points by merging wire segments */
    if( tmp.GetCount() != 0 )
    if( GetScreen()->IsJunctionNeeded( s_ConnexionStartPoint ) )
        screen->ReplaceWires( tmp );
        AddJunction( DC, s_ConnexionStartPoint );


    GetScreen()->TestDanglingEnds( m_canvas, DC );
    // Now add the new wires and any required junctions to the schematic item list.
    screen->Append( s_wires );


    /* Redraw wires and junctions which can be changed by TestDanglingEnds() */
    screen->SchematicCleanUp( m_canvas, DC );
    m_canvas->CrossHairOff( DC );   // Erase schematic cursor
    EDA_ITEM* item = GetScreen()->GetDrawItems();


    while( item )
    // Put the snap shot of the previous wire, buses, and junctions in the undo/redo list.
    {
    PICKED_ITEMS_LIST oldItems;
        switch( item->Type() )
        {
        case SCH_JUNCTION_T:
        case SCH_LINE_T:
            m_canvas->RefreshDrawingRect( item->GetBoundingBox() );
            break;


        default:
    oldItems.m_Status = UR_WIRE_IMAGE;
            break;
        }


        item = item->Next();
    while( s_oldWires.GetCount() != 0 )
    {
        ITEM_PICKER picker = ITEM_PICKER( s_oldWires.PopFront(), UR_WIRE_IMAGE );
        oldItems.PushItem( picker );
    }
    }


    m_canvas->CrossHairOn( DC );    // Display schematic cursor
    SaveCopyInUndoList( oldItems, UR_WIRE_IMAGE );

    SaveCopyInUndoList( s_OldWiresList, UR_WIRE_IMAGE );
    s_OldWiresList = NULL;


    OnModify();
    OnModify();
}
}
@@ -364,45 +299,53 @@ void SCH_EDIT_FRAME::EndSegment( wxDC* DC )
 * Function ComputeBreakPoint
 * Function ComputeBreakPoint
 * computes the middle coordinate for 2 segments from the start point to \a aPosition
 * computes the middle coordinate for 2 segments from the start point to \a aPosition
 * with the segments kept in the horizontal or vertical axis only.
 * with the segments kept in the horizontal or vertical axis only.
 *
 * @param aSegment A pointer to a #SCH_LINE object containing the first line break point
 *                 to compute.
 * @param aPosition A reference to a wxPoint object containing the coordinates of the
 *                  position used to calculate the line break point.
 */
 */
static void ComputeBreakPoint( SCH_LINE* aSegment, const wxPoint& aPosition )
static void ComputeBreakPoint( SCH_LINE* aSegment, const wxPoint& aPosition )
{
{
    SCH_LINE* nextsegment     = aSegment->Next();
    wxCHECK_RET( aSegment != NULL, wxT( "Cannot compute break point of NULL line segment." ) );
    wxPoint   middle_position = aPosition;

    SCH_LINE* nextSegment = aSegment->Next();
    wxPoint midPoint = aPosition;

    wxCHECK_RET( nextSegment != NULL,
                 wxT( "Cannot compute break point of NULL second line segment." ) );


    if( nextsegment == NULL )
        return;
#if 0
#if 0
    if( ABS( middle_position.x - aSegment->GetStartPoint().x ) <
    if( ABS( midPoint.x - aSegment->GetStartPoint().x ) <
        ABS( middle_position.y - aSegment->GetStartPoint().y ) )
        ABS( midPoint.y - aSegment->GetStartPoint().y ) )
        middle_position.x = aSegment->GetStartPoint().x;
        midPoint.x = aSegment->GetStartPoint().x;
    else
    else
        middle_position.y = aSegment->GetStartPoint().y;
        midPoint.y = aSegment->GetStartPoint().y;
#else
#else
    int iDx = aSegment->GetEndPoint().x - aSegment->GetStartPoint().x;
    int iDx = aSegment->GetEndPoint().x - aSegment->GetStartPoint().x;
    int iDy = aSegment->GetEndPoint().y - aSegment->GetStartPoint().y;
    int iDy = aSegment->GetEndPoint().y - aSegment->GetStartPoint().y;


    if( iDy != 0 )         // keep the first segment orientation (currently horizontal)
    if( iDy != 0 )         // keep the first segment orientation (currently horizontal)
    {
    {
        middle_position.x = aSegment->GetStartPoint().x;
        midPoint.x = aSegment->GetStartPoint().x;
    }
    }
    else if( iDx != 0 )    // keep the first segment orientation (currently vertical)
    else if( iDx != 0 )    // keep the first segment orientation (currently vertical)
    {
    {
        middle_position.y = aSegment->GetStartPoint().y;
        midPoint.y = aSegment->GetStartPoint().y;
    }
    }
    else
    else
    {
    {
        if( ABS( middle_position.x - aSegment->GetStartPoint().x ) <
        if( ABS( midPoint.x - aSegment->GetStartPoint().x ) <
            ABS( middle_position.y - aSegment->GetStartPoint().y ) )
            ABS( midPoint.y - aSegment->GetStartPoint().y ) )
            middle_position.x = aSegment->GetStartPoint().x;
            midPoint.x = aSegment->GetStartPoint().x;
        else
        else
            middle_position.y = aSegment->GetStartPoint().y;
            midPoint.y = aSegment->GetStartPoint().y;
    }
    }
#endif
#endif


    aSegment->SetEndPoint( middle_position );
    aSegment->SetEndPoint( midPoint );
    nextsegment->SetStartPoint( middle_position );
    nextSegment->SetStartPoint( midPoint );
    nextsegment->SetEndPoint( aPosition );
    nextSegment->SetEndPoint( aPosition );
}
}




@@ -443,7 +386,7 @@ void SCH_EDIT_FRAME::DeleteCurrentSegment( wxDC* DC )
        DrawSegment( m_canvas, DC, wxDefaultPosition, false );
        DrawSegment( m_canvas, DC, wxDefaultPosition, false );
    }
    }


    screen->RemoveFromDrawList( screen->GetCurItem() );
    screen->Remove( screen->GetCurItem() );
    m_canvas->SetMouseCaptureCallback( NULL );
    m_canvas->SetMouseCaptureCallback( NULL );
    screen->SetCurItem( NULL );
    screen->SetCurItem( NULL );
}
}
@@ -460,12 +403,12 @@ SCH_JUNCTION* SCH_EDIT_FRAME::AddJunction( wxDC* aDC, const wxPoint& aPosition,
    junction->Draw( m_canvas, aDC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE );
    junction->Draw( m_canvas, aDC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE );
    m_canvas->CrossHairOn( aDC );      // Display schematic cursor
    m_canvas->CrossHairOn( aDC );      // Display schematic cursor


    junction->SetNext( GetScreen()->GetDrawItems() );
    GetScreen()->SetDrawItems( junction );
    OnModify();

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


    return junction;
    return junction;
}
}
@@ -482,8 +425,7 @@ SCH_NO_CONNECT* SCH_EDIT_FRAME::AddNoConnect( wxDC* aDC, const wxPoint& aPositio
    NewNoConnect->Draw( m_canvas, aDC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE );
    NewNoConnect->Draw( m_canvas, aDC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE );
    m_canvas->CrossHairOn( aDC );      // Display schematic cursor
    m_canvas->CrossHairOn( aDC );      // Display schematic cursor


    NewNoConnect->SetNext( GetScreen()->GetDrawItems() );
    GetScreen()->Append( NewNoConnect );
    GetScreen()->SetDrawItems( NewNoConnect );
    OnModify();
    OnModify();
    SaveCopyInUndoList( NewNoConnect, UR_NEW );
    SaveCopyInUndoList( NewNoConnect, UR_NEW );
    return NewNoConnect;
    return NewNoConnect;
@@ -498,9 +440,9 @@ static void AbortCreateNewLine( EDA_DRAW_PANEL* Panel, wxDC* DC )


    if( screen->GetCurItem() )
    if( screen->GetCurItem() )
    {
    {
        screen->RemoveFromDrawList( (SCH_ITEM*) screen->GetCurItem() );
        s_wires.DeleteAll();
        s_oldWires.DeleteAll();
        screen->SetCurItem( NULL );
        screen->SetCurItem( NULL );
        screen->ReplaceWires( s_OldWiresList );
        Panel->Refresh();
        Panel->Refresh();
    }
    }
    else
    else
@@ -540,8 +482,7 @@ void SCH_EDIT_FRAME::RepeatDrawItem( wxDC* DC )


    if( m_itemToRepeat )
    if( m_itemToRepeat )
    {
    {
        m_itemToRepeat->SetNext( GetScreen()->GetDrawItems() );
        GetScreen()->Append( m_itemToRepeat );
        GetScreen()->SetDrawItems( m_itemToRepeat );
        GetScreen()->TestDanglingEnds();
        GetScreen()->TestDanglingEnds();
        m_itemToRepeat->Draw( m_canvas, DC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE );
        m_itemToRepeat->Draw( m_canvas, DC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE );
        SaveCopyInUndoList( m_itemToRepeat, UR_NEW );
        SaveCopyInUndoList( m_itemToRepeat, UR_NEW );
Loading