Commit 148a574e authored by charras's avatar charras
Browse files

More about undo/redo in pcbnew

parent 42b1020d
Loading
Loading
Loading
Loading
+21 −0
Original line number Original line Diff line number Diff line
@@ -314,6 +314,25 @@ void PICKED_ITEMS_LIST::CopyList( const PICKED_ITEMS_LIST& aSource )
    m_ItemsList = aSource.m_ItemsList;  // Vector's copy
    m_ItemsList = aSource.m_ItemsList;  // Vector's copy
}
}


/** function ReversePickersListOrder()
 * reverses the order of pickers stored in this list
 * Useful when pop a list from Undo to Redo (and vice-versa)
 * because sometimes undo (or redo) a command needs to keep the
 * order of successive changes.
 * and obviously, undo and redo are in reverse order
 */
void PICKED_ITEMS_LIST::ReversePickersListOrder()
{
    std::vector <ITEM_PICKER> tmp;
    while( !m_ItemsList.empty() )
    {
        tmp.push_back( m_ItemsList.back() );
        m_ItemsList.pop_back();
    }

    m_ItemsList.swap( tmp );
}



/**********************************************/
/**********************************************/
/********** UNDO_REDO_CONTAINER ***************/
/********** UNDO_REDO_CONTAINER ***************/
@@ -355,3 +374,5 @@ PICKED_ITEMS_LIST* UNDO_REDO_CONTAINER::PopCommand()
    }
    }
    return NULL;
    return NULL;
}
}

+9 −0
Original line number Original line Diff line number Diff line
@@ -137,6 +137,15 @@ public:
        return m_ItemsList.size();
        return m_ItemsList.size();
    }
    }


    /** function ReversePickersListOrder()
     * reverses the order of pickers stored in this list
     * Useful when pop a list from Undo to Redo (and vice-versa)
     * because sometimes undo (or redo) a command needs to keep the
     * order of successive changes.
     * and obviously, undo and redo are in reverse order
     */
    void        ReversePickersListOrder();



    /** function GetItemWrapper
    /** function GetItemWrapper
     * @return the picker of a picked item
     * @return the picker of a picked item
+37 −2
Original line number Original line Diff line number Diff line
@@ -386,8 +386,21 @@ public:
    void             Remove_One_Track( wxDC* DC, TRACK* pt_segm );
    void             Remove_One_Track( wxDC* DC, TRACK* pt_segm );
    bool             Resize_Pistes_Vias( wxDC* DC, bool Track, bool Via );
    bool             Resize_Pistes_Vias( wxDC* DC, bool Track, bool Via );
    void             Edit_Net_Width( wxDC* DC, int Netcode );
    void             Edit_Net_Width( wxDC* DC, int Netcode );

    /** Function Edit_Track_Width
     * Modify a full track width (using DRC control).
     * a full track is the set of track segments between 2 ends: pads or a point that has more than 2 segments ends connected
     * @param  DC = the curred device context (can be NULL)
     * @param aTrackSegment = a segment or via on the track to change
     */
    void             Edit_Track_Width( wxDC* DC, TRACK* Track );
    void             Edit_Track_Width( wxDC* DC, TRACK* Track );
    int              Edit_TrackSegm_Width( wxDC* DC, TRACK* segm );

    /** Function Edit_TrackSegm_Width
     *  Modify one track segment width or one via diameter (using DRC control).
     * @param  DC = the curred device context (can be NULL)
     * @param aTrackItem = the track segment or via to modify
     */
    void             Edit_TrackSegm_Width( wxDC* DC, TRACK* segm );
    TRACK*           Begin_Route( TRACK* track, wxDC* DC );
    TRACK*           Begin_Route( TRACK* track, wxDC* DC );
    void             End_Route( TRACK* track, wxDC* DC );
    void             End_Route( TRACK* track, wxDC* DC );
    void             ExChange_Track_Layer( TRACK* pt_segm, wxDC* DC );
    void             ExChange_Track_Layer( TRACK* pt_segm, wxDC* DC );
@@ -395,13 +408,35 @@ public:
    void             Attribut_Track( TRACK* track, wxDC* DC, bool Flag_On );
    void             Attribut_Track( TRACK* track, wxDC* DC, bool Flag_On );
    void             Attribut_net( wxDC* DC, int net_code, bool Flag_On );
    void             Attribut_net( wxDC* DC, int net_code, bool Flag_On );
    void             Start_MoveOneNodeOrSegment( TRACK* track, wxDC* DC, int command );
    void             Start_MoveOneNodeOrSegment( TRACK* track, wxDC* DC, int command );
    bool             PlaceDraggedTrackSegment( TRACK* Track, wxDC* DC );
    bool             PlaceDraggedOrMovedTrackSegment( TRACK* Track, wxDC* DC );
    bool             MergeCollinearTracks( TRACK* track, wxDC* DC, int end );
    bool             MergeCollinearTracks( TRACK* track, wxDC* DC, int end );
    void             Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC );
    void             Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC );
    void             SwitchLayer( wxDC* DC, int layer );
    void             SwitchLayer( wxDC* DC, int layer );
    bool             Add_45_degrees_Segment( wxDC* DC );
    bool             Add_45_degrees_Segment( wxDC* DC );
    bool             Genere_Pad_Connexion( wxDC* DC, int layer );
    bool             Genere_Pad_Connexion( wxDC* DC, int layer );


    /** function EraseRedundantTrack
     * Called after creating a track
     * Remove (if exists) the old track that have the same starting and the same ending point as the new created track
     * (this is the redunding track)
     * @param aDC = the current device context (can be NULL)
     * @param aNewTrack = the new created track (a pointer to a segment of the track list)
     * @param aNewTrackSegmentsCount = number of segments in this new track
 * @param aItemsListPicker = the list picker to use for an undo command (can be NULL)
 */
    int             EraseRedundantTrack( wxDC* aDC, TRACK* aNewTrack, int aNewTrackSegmentsCount,
                                        PICKED_ITEMS_LIST*  aItemsListPicker );

    /** Function SetTrackSegmentWidth
     *  Modify one track segment width or one via diameter (using DRC control).
     *  Basic routine used by other routines when editing tracks or vias
     * @param aTrackItem = the track segment or via to modify
     * @param aItemsListPicker = the list picker to use for an undo command (can be NULL)
     * @return  true if done, false if no not change (because DRC error)
     */
    bool             SetTrackSegmentWidth( TRACK* aTrackItem, PICKED_ITEMS_LIST* aItemsListPicker );


    // zone handling
    // zone handling


    /** Function Delete_Zone_Fill
    /** Function Delete_Zone_Fill
+7 −11
Original line number Original line Diff line number Diff line
@@ -641,7 +641,7 @@ void WinEDA_PcbFrame::Block_Delete()


        // These items are deleted, but not put in undo list
        // These items are deleted, but not put in undo list
        case TYPE_MARKER_PCB:               // a marker used to show something
        case TYPE_MARKER_PCB:               // a marker used to show something
        case TYPE_ZONE:                     // a segment used to fill a zome area (segment on a copper layer)
        case TYPE_ZONE:                     // SEG_ZONE items are now deprecated
            item->UnLink();
            item->UnLink();
            itemsList->RemovePicker( ii );
            itemsList->RemovePicker( ii );
            ii--;
            ii--;
@@ -715,7 +715,7 @@ void WinEDA_PcbFrame::Block_Rotate()
            break;
            break;


        // This item is not put in undo list
        // This item is not put in undo list
        case TYPE_ZONE:                     // a segment used to fill a zome area (segment on a copper layer)
        case TYPE_ZONE:                     // SEG_ZONE items are now deprecated
            itemsList->RemovePicker( ii );
            itemsList->RemovePicker( ii );
            ii--;
            ii--;
            break;
            break;
@@ -786,7 +786,7 @@ void WinEDA_PcbFrame::Block_Flip()
            break;
            break;


        // This item is not put in undo list
        // This item is not put in undo list
        case TYPE_ZONE:                     // a segment used to fill a zome area (segment on a copper layer)
        case TYPE_ZONE:                     // SEG_ZONE items are now deprecated
            itemsList->RemovePicker( ii );
            itemsList->RemovePicker( ii );
            ii--;
            ii--;
            break;
            break;
@@ -853,7 +853,7 @@ void WinEDA_PcbFrame::Block_Move()
            break;
            break;


        // This item is not put in undo list
        // This item is not put in undo list
        case TYPE_ZONE:                     // a segment used to fill a zome area (segment on a copper layer)
        case TYPE_ZONE:                     // SEG_ZONE items are now deprecated
            itemsList->RemovePicker( ii );
            itemsList->RemovePicker( ii );
            ii--;
            ii--;
            break;
            break;
@@ -928,11 +928,7 @@ void WinEDA_PcbFrame::Block_Duplicate()
        }
        }
        break;
        break;


        case TYPE_ZONE:                  // a segment used to fill a zome area (segment on a copper layer)
        case TYPE_ZONE:                  // SEG_ZONE items are now deprecated
        {
            // SEG_ZONE items are not copied or put in undo list
            // they must be recreated by zone filling
        }
            break;
            break;


        case TYPE_ZONE_CONTAINER:
        case TYPE_ZONE_CONTAINER:
+33 −18
Original line number Original line Diff line number Diff line
@@ -126,7 +126,7 @@ void SwapData( BOARD_ITEM* aItem, BOARD_ITEM* aImage )
    }
    }


    // Swap layers:
    // Swap layers:
    if( aItem->Type() != TYPE_MODULE )     // Modules have a global swap function
    if( aItem->Type() != TYPE_MODULE && aItem->Type() != TYPE_ZONE_CONTAINER )     // these items have a global swap function
    {
    {
        int layer, layerimg;
        int layer, layerimg;
        layer    = aItem->GetLayer();
        layer    = aItem->GetLayer();
@@ -139,15 +139,20 @@ void SwapData( BOARD_ITEM* aItem, BOARD_ITEM* aImage )
    {
    {
    case TYPE_MODULE:
    case TYPE_MODULE:
    {
    {
        MODULE* m_tmp = (MODULE*) DuplicateStruct( aImage );
        MODULE* tmp = (MODULE*) DuplicateStruct( aImage );
        ( (MODULE*) aImage )->Copy( (MODULE*) aItem );
        ( (MODULE*) aImage )->Copy( (MODULE*) aItem );
        ( (MODULE*) aItem )->Copy( m_tmp );
        ( (MODULE*) aItem )->Copy( tmp );
        delete m_tmp;
        delete tmp;
    }
    }
    break;
    break;


    case TYPE_ZONE_CONTAINER:
    case TYPE_ZONE_CONTAINER:
        wxMessageBox( wxT( "SwapData(): TYPE_ZONE_CONTAINER not handled" ) );
    {
        ZONE_CONTAINER* tmp = (ZONE_CONTAINER*) DuplicateStruct( aImage );
        ( (ZONE_CONTAINER*) aImage )->Copy( (ZONE_CONTAINER*) aItem );
        ( (ZONE_CONTAINER*) aItem )->Copy( tmp );
        delete tmp;
    }
    break;
    break;


    case TYPE_DRAWSEGMENT:
    case TYPE_DRAWSEGMENT:
@@ -383,6 +388,7 @@ void WinEDA_PcbFrame::SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList,
    PICKED_ITEMS_LIST* commandToUndo = new PICKED_ITEMS_LIST();
    PICKED_ITEMS_LIST* commandToUndo = new PICKED_ITEMS_LIST();


    commandToUndo->m_TransformPoint = aTransformPoint;
    commandToUndo->m_TransformPoint = aTransformPoint;

    // Copy picker list:
    // Copy picker list:
    commandToUndo->CopyList( aItemsList );
    commandToUndo->CopyList( aItemsList );


@@ -401,6 +407,7 @@ void WinEDA_PcbFrame::SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList,
        switch( command )
        switch( command )
        {
        {
        case UR_CHANGED:
        case UR_CHANGED:

            /* If needed, create a copy of item, and put in undo list
            /* If needed, create a copy of item, and put in undo list
             * in the picker, as link
             * in the picker, as link
             * If this link is not null, the copy is already done
             * If this link is not null, the copy is already done
@@ -453,7 +460,9 @@ void WinEDA_PcbFrame::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRe
    bool        not_found = false;
    bool        not_found = false;
    bool        reBuild_ratsnest = false;
    bool        reBuild_ratsnest = false;


    for( unsigned ii = 0; ii < aList->GetCount(); ii++  )
    // 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
    for( int ii = aList->GetCount()-1; ii >= 0 ; ii--  )
    {
    {
        item = (BOARD_ITEM*) aList->GetPickedItem( ii );
        item = (BOARD_ITEM*) aList->GetPickedItem( ii );
        wxASSERT( item );
        wxASSERT( item );
@@ -464,7 +473,7 @@ void WinEDA_PcbFrame::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRe
            {
            {
                // Remove this non existant item
                // Remove this non existant item
                aList->RemovePicker( ii );
                aList->RemovePicker( ii );
                ii--;       // the current item was removed, ii points now the next item
                ii++;       // the current item was removed, ii points now the next item
                            // whe must decrement it because it will be incremented
                            // whe must decrement it because it will be incremented
                not_found = true;
                not_found = true;
                continue;
                continue;
@@ -557,12 +566,15 @@ void WinEDA_PcbFrame::GetBoardFromUndoList( wxCommandEvent& event )
    if( GetScreen()->GetUndoCommandCount() <= 0 )
    if( GetScreen()->GetUndoCommandCount() <= 0 )
        return;
        return;


    /* Get the old wrapper and put it in RedoList */
    /* Get the old list */
    PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromUndoList();
    PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromUndoList();
    GetScreen()->PushCommandToRedoList( List );
    /* Undo the command */
    /* Undo the command */
    PutDataInPreviousState( List, false );
    PutDataInPreviousState( List, false );


    /* Pu the old list in RedoList */
     List->ReversePickersListOrder();
    GetScreen()->PushCommandToRedoList( List );

    GetScreen()->SetModify();
    GetScreen()->SetModify();
    ReCreateHToolbar();
    ReCreateHToolbar();
    SetToolbars();
    SetToolbars();
@@ -583,13 +595,16 @@ void WinEDA_PcbFrame::GetBoardFromRedoList( wxCommandEvent& event )
        return;
        return;




    /* Get the old wrapper and put it in UndoList */
    /* Get the old list */
    PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromRedoList();
    PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromRedoList();
    GetScreen()->PushCommandToUndoList( List );


    /* Redo the command: */
    /* Redo the command: */
    PutDataInPreviousState( List, true );
    PutDataInPreviousState( List, true );


    /* Put the old list in UndoList */
    List->ReversePickersListOrder();
    GetScreen()->PushCommandToUndoList( List );

    GetScreen()->SetModify();
    GetScreen()->SetModify();
    ReCreateHToolbar();
    ReCreateHToolbar();
    SetToolbars();
    SetToolbars();
Loading