Commit 8e846082 authored by jean-pierre charras's avatar jean-pierre charras
Browse files

Pcbnew: Fix incorrect behavior of undo/redo command (this issue happens only...

Pcbnew: Fix incorrect behavior of undo/redo command (this issue happens only when a new track is created, and an old redundant track is deleted)
Minor code cleaning
parent 716d21d8
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -98,6 +98,7 @@ public:
                                        * copy of an active item) and m_Link points the active
                                        * item in schematic */

public:
    ITEM_PICKER( EDA_ITEM* aItem = NULL, UNDO_REDO_T aUndoRedoStatus = UR_UNSPECIFIED );

    EDA_ITEM* GetItem() const { return m_PickedItem; }
@@ -106,6 +107,8 @@ public:

    KICAD_T GetItemType() const { return m_PickedItemType; }

    void SetStatus( UNDO_REDO_T aStatus ) { m_UndoRedoStatus = aStatus; }

    void SetItemType( KICAD_T aType ) { m_PickedItemType = aType; }

    void SetLink( EDA_ITEM* aItem ) { m_Link = aItem; }
+10 −6
Original line number Diff line number Diff line
@@ -399,10 +399,6 @@ void PCB_EDIT_FRAME::SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList,
             */
            if( commandToUndo->GetPickedItemLink( ii ) == NULL )
                commandToUndo->SetPickedItemLink( item->Clone(), ii );

            if( commandToUndo->GetPickedItemLink( ii ) == NULL )
                 wxMessageBox( wxT( "SaveCopyInUndoList() in UR_CHANGED mode: NULL link" ) );

            break;

        case UR_MOVED:
@@ -459,7 +455,7 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
    // Undo in the reverse order of list creation: (this can allow stacked changes
    // like the same item can be changes and deleted in the same complex command

    TestForExistingItem( GetBoard(), NULL ); // Build list of existing items, for integrity test
    bool build_item_list = true;    // if true the list of esiting items must be rebuilt
    for( int ii = aList->GetCount()-1; ii >= 0 ; ii--  )
    {
        item = (BOARD_ITEM*) aList->GetPickedItem( ii );
@@ -470,9 +466,16 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
         *   - if a call to SaveCopyInUndoList was forgotten in Pcbnew
         *   - in zones outlines, when a change in one zone merges this zone with an other
         * This test avoids a Pcbnew crash
         * the test is made only to avoid crashes, so it is not needed for deleted or new items
         */
        if( aList->GetPickedItemStatus( ii ) != UR_DELETED )
        UNDO_REDO_T status = aList->GetPickedItemStatus( ii );
        if( status != UR_DELETED && status != UR_NEW )
        {
            if( build_item_list )
                // Build list of existing items, for integrity test
                TestForExistingItem( GetBoard(), NULL );
            build_item_list = false;

            if( !TestForExistingItem( GetBoard(), item ) )
            {
                // Remove this non existant item
@@ -517,6 +520,7 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
        case UR_DELETED:    /* deleted items are put in List, as new items */
            aList->SetPickedItemStatus( UR_NEW, ii );
            GetBoard()->Add( item );
            build_item_list = true;
            break;

        case UR_MOVED:
+26 −44
Original line number Diff line number Diff line
@@ -2074,6 +2074,11 @@ BOARD_CONNECTED_ITEM* BOARD::GetLockPoint( const wxPoint& aPosition, int aLayerM

TRACK* BOARD::CreateLockPoint( wxPoint& aPosition, TRACK* aSegment, PICKED_ITEMS_LIST* aList )
{
    /* creates an intermediate point on aSegment and break it into two segments
     * at aPosition.
     * The new segment starts from aPosition and ends at the end point of
     * aSegment. The original segment now ends at aPosition.
     */
    if( aSegment->m_Start == aPosition || aSegment->m_End == aPosition )
        return NULL;

@@ -2087,43 +2092,26 @@ TRACK* BOARD::CreateLockPoint( wxPoint& aPosition, TRACK* aSegment, PICKED_ITEMS
    // Calculation coordinate of intermediate point relative to the start point of aSegment
     wxPoint delta = aSegment->m_End - aSegment->m_Start;

    // Not yet in use:
#if 0
    int ox, oy, fx, fy;

    if( aRefSegm )
    {
        ox = aRefSegm->m_Start.x - aSegment->m_Start.x;
        oy = aRefSegm->m_Start.y - aSegment->m_Start.y;
        fx = aRefSegm->m_End.x - aSegment->m_Start.x;
        fy = aRefSegm->m_End.y - aSegment->m_Start.y;
    }
#endif

    // calculate coordinates of aPosition relative to aSegment->m_Start
    wxPoint newPoint = aPosition - aSegment->m_Start;
    wxPoint lockPoint = aPosition - aSegment->m_Start;

    // newPoint must be on aSegment:
    // Ensure newPoint.y/newPoint.y = delta.y/delta.x
    // lockPoint must be on aSegment:
    // Ensure lockPoint.y/lockPoint.y = delta.y/delta.x
    if( delta.x == 0 )
        newPoint.x = 0;         /* horizontal segment*/
        lockPoint.x = 0;         /* horizontal segment*/
    else
        newPoint.y = wxRound( ( (double)newPoint.x * delta.y ) / delta.x );
        lockPoint.y = wxRound( ( (double)lockPoint.x * delta.y ) / delta.x );

    /* Create the intermediate point (that is to say creation of a new
     * segment, beginning at the intermediate point.
     */
    newPoint.x += aSegment->m_Start.x;
    newPoint.y += aSegment->m_Start.y;
    lockPoint += aSegment->m_Start;

    TRACK* newTrack = (TRACK*)aSegment->Clone();

    if( aList )
    {
        ITEM_PICKER picker( newTrack, UR_NEW );
        aList->PushItem( picker );
    }

    // The new segment begins at the new point,
    newTrack->m_Start = lockPoint;
    newTrack->start = aSegment;
    newTrack->SetState( BEGIN_ONPAD, OFF );

    DLIST<TRACK>* list = (DLIST<TRACK>*)aSegment->GetList();
    wxASSERT( list );
@@ -2131,28 +2119,22 @@ TRACK* BOARD::CreateLockPoint( wxPoint& aPosition, TRACK* aSegment, PICKED_ITEMS

    if( aList )
    {
        ITEM_PICKER picker( aSegment, UR_CHANGED );
        picker.m_Link = aSegment->Clone();
        // Prepare the undo command for the now track segment
        ITEM_PICKER picker( newTrack, UR_NEW );
        aList->PushItem( picker );
        // Prepare the undo command for the old track segment
        // before modifications
        picker.SetItem( aSegment );
        picker.SetStatus( UR_CHANGED );
        picker.SetLink( aSegment->Clone() );
        aList->PushItem( picker );
    }

    /* Correct pointer at the end of the new segment. */
    newTrack->end = aSegment->end;
    newTrack->SetState( END_ONPAD, aSegment->GetState( END_ONPAD ) );

    /* Set connections info relative to the new point
    */

    /* Old segment now ends at new point. */
    aSegment->m_End = newPoint;
    // Old track segment now ends at new point.
    aSegment->m_End = lockPoint;
    aSegment->end = newTrack;
    aSegment->SetState( END_ONPAD, OFF );

    /* The new segment begins at the new point. */
    newTrack->m_Start = newPoint;
    newTrack->start = aSegment;
    newTrack->SetState( BEGIN_ONPAD, OFF );

    D_PAD * pad = GetPad( newTrack, START );

    if ( pad )
@@ -2163,7 +2145,7 @@ TRACK* BOARD::CreateLockPoint( wxPoint& aPosition, TRACK* aSegment, PICKED_ITEMS
        aSegment->SetState( END_ONPAD, ON );
    }

    aPosition = newPoint;
    aPosition = lockPoint;
    return newTrack;
}

+2 −2
Original line number Diff line number Diff line
@@ -1308,10 +1308,10 @@ public:
    /**
     * Function CreateLockPoint
     * creates an intermediate point on \a aSegment and break it into two segments
     * at \a aPoition.
     * at \a aPosition.
     * <p>
     * The new segment starts from \a aPosition and ends at the end point of \a
     * aSegement.  The original segment now ends at \a aPosition.
     * aSegment.  The original segment now ends at \a aPosition.
     * </p>
     *
     * @param aPosition A wxPoint object containing the position to test and the new
+0 −3
Original line number Diff line number Diff line
@@ -215,9 +215,6 @@ void PCB_EDIT_FRAME::Remove_One_Track( wxDC* DC, TRACK* pt_segm )
        next_track = tracksegment->Next();
        tracksegment->SetState( BUSY, OFF );

        //D( printf( "%s: track %p status=\"%s\"\n", __func__, tracksegment,
        //           TO_UTF8( TRACK::ShowState( tracksegment->GetState( -1 ) ) )
        //          ); )
        D( std::cout << __func__ << ": track " << tracksegment << " status=" \
                     << TO_UTF8( TRACK::ShowState( tracksegment->GetState( -1 ) ) ) \
                     << std::endl; )
Loading