Commit 4b846e1f authored by charras's avatar charras
Browse files

pcbnew: work on undo/redo in progress

parent 61550f1a
Loading
Loading
Loading
Loading
+30 −22
Original line number Diff line number Diff line
@@ -181,7 +181,7 @@ void SwapData( EDA_BaseStruct* aItem, EDA_BaseStruct* aImage )


/***********************************************************************/
void WinEDA_SchematicFrame::SaveCopyInUndoList( SCH_ITEM*      aItemToCopy,
void WinEDA_SchematicFrame::SaveCopyInUndoList( SCH_ITEM*      aItem,
                                                UndoRedoOpType aCommandType,
                                                const wxPoint& aTransformPoint )
/***********************************************************************/
@@ -194,6 +194,7 @@ void WinEDA_SchematicFrame::SaveCopyInUndoList( SCH_ITEM* aItemToCopy,
 *      UR_NEW
 *      UR_DELETED
 *      UR_WIRE_IMAGE
 *      UR_MOVED
 *
 *  If it is a delete command, items are put on list with the .Flags member set to UR_DELETED.
 *  When it will be really deleted, the EEDrawList and the subhierarchy will be deleted.
@@ -211,15 +212,14 @@ void WinEDA_SchematicFrame::SaveCopyInUndoList( SCH_ITEM* aItemToCopy,
    PICKED_ITEMS_LIST* commandToUndo = new PICKED_ITEMS_LIST();
    commandToUndo->m_TransformPoint = aTransformPoint;

    ITEM_PICKER        itemWrapper( aItemToCopy, aCommandType );
    itemWrapper.m_PickedItemType = aItemToCopy->Type();
    ITEM_PICKER        itemWrapper( aItem, aCommandType );
    itemWrapper.m_PickedItemType = aItem->Type();

    switch( aCommandType )
    {
    case UR_CHANGED:            /* Create a copy of schematic */
        CopyOfItem = DuplicateStruct( aItemToCopy );
        itemWrapper.m_PickedItem = CopyOfItem;
        itemWrapper.m_Link = aItemToCopy;
    case UR_CHANGED:            /* Create a copy of item */
        CopyOfItem = DuplicateStruct( aItem );
        itemWrapper.m_Link = CopyOfItem;
        if ( CopyOfItem )
            commandToUndo->PushItem( itemWrapper );
        break;
@@ -269,21 +269,20 @@ void WinEDA_SchematicFrame::SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList,

    for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
    {
        SCH_ITEM*      ItemToCopy = (SCH_ITEM*) aItemsList.GetPickedItem( ii );
        SCH_ITEM*      item = (SCH_ITEM*) aItemsList.GetPickedItem( ii );
        UndoRedoOpType command    = aItemsList.GetPickedItemStatus( ii );
        if( command == UR_UNSPECIFIED )
        {
            command = aTypeCommand;
        }
        itemWrapper.m_PickedItem = ItemToCopy;
        itemWrapper.m_PickedItemType = ItemToCopy->Type();
        itemWrapper.m_PickedItem = item;
        itemWrapper.m_PickedItemType = item->Type();
        itemWrapper.m_UndoRedoStatus = command;
        switch( command )
        {
        case UR_CHANGED:        /* Create a copy of schematic */
            CopyOfItem = DuplicateStruct( ItemToCopy );
            itemWrapper.m_PickedItem = CopyOfItem;
            itemWrapper.m_Link = ItemToCopy;
        case UR_CHANGED:        /* Create a copy of item */
            CopyOfItem = DuplicateStruct( item );
            itemWrapper.m_Link = CopyOfItem;
            if ( CopyOfItem )
                commandToUndo->PushItem( itemWrapper );
            break;
@@ -291,11 +290,7 @@ void WinEDA_SchematicFrame::SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList,
        case UR_MOVED:
        case UR_MIRRORED_Y:
        case UR_NEW:
            commandToUndo->PushItem( itemWrapper );
            break;

        case UR_DELETED:
            ItemToCopy->m_Flags = UR_DELETED;
            commandToUndo->PushItem( itemWrapper );
            break;

@@ -338,6 +333,7 @@ void WinEDA_SchematicFrame::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bo
        ITEM_PICKER itemWrapper = aList->GetItemWrapper( ii );
        item = (SCH_ITEM*) itemWrapper.m_PickedItem;
        wxASSERT( item  );
        item->m_Flags = 0;
        SCH_ITEM*   image = (SCH_ITEM*) itemWrapper.m_Link;
        switch( itemWrapper.m_UndoRedoStatus )
        {
@@ -348,14 +344,12 @@ void WinEDA_SchematicFrame::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bo
        case UR_NEW:        /* new items are deleted */
            aList->SetPickedItemStatus( UR_DELETED, ii );
            GetScreen()->RemoveFromDrawList( item );
            item->m_Flags = UR_DELETED;
            break;

        case UR_DELETED:    /* deleted items are put in EEdrawList, as new items */
            aList->SetPickedItemStatus( UR_NEW, ii );
            item->SetNext( GetScreen()->EEDrawList );
            GetScreen()->EEDrawList = item;
            item->m_Flags = 0;
            break;

        case UR_MOVED:
@@ -500,7 +494,7 @@ void SCH_SCREEN::ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount
            {
            case UR_WIRE_IMAGE:
                while( item )
                {
                {   // Delete old copy of wires
                    EDA_BaseStruct* nextitem = item->Next();
                    delete          item;
                    item = nextitem;
@@ -515,11 +509,25 @@ void SCH_SCREEN::ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount
            case UR_NEW:        // Do nothing, items are in use
                break;

            case UR_DELETED:
                delete item;    // Delete the picked item, because it was deleted from schematic
                break;

            case UR_CHANGED:
                delete wrapper.m_Link;  // Delete the copy of item (the item is itself in use)
                break;

            default:
                delete item;
            {
                wxString msg;
                msg.Printf(
                    wxT("ClearUndoORRedoList() error: unexpected undo/redo type %d"),
                    wrapper.m_UndoRedoStatus );
                wxMessageBox( msg );
                break;
            }
            }
        }

        delete curr_cmd;    // Delete command
    }
+3 −1
Original line number Diff line number Diff line
@@ -87,8 +87,10 @@ public:
     * Function SetLayer
     * sets the layer this item is on.
     * @param aLayer The layer number.
     * is virtual because some items (in fact: class COTATION)
     * have a slightly different initialisation
     */
    void  SetLayer( int aLayer )  { m_Layer = aLayer; }
    virtual void  SetLayer( int aLayer )  { m_Layer = aLayer; }


    /**
+118 −20
Original line number Diff line number Diff line
@@ -104,12 +104,16 @@ static bool TestForExistingItem( BOARD* aPcb, BOARD_ITEM* aItem )


/**************************************************************/
void SwapData( EDA_BaseStruct* aItem, EDA_BaseStruct* aImage )
void SwapData( BOARD_ITEM* aItem, BOARD_ITEM* aImage )
/***************************************************************/

/* Used if undo / redo command:
 *  swap data between Item and its copy, pointed by its .m_Image member
 * swapped data is data modified by edition, so not all values are swapped
/** Function SwapData
 * Used in undo / redo command:
 *  swap data between Item and a copy
 *  swapped data is data modified by edition, mainly sizes and texts
 * so ONLY FEW values are swapped
 * @param aItem = the item
 * @param aImage = a copy of the item
 */
{
    if( aItem == NULL || aImage == NULL )
@@ -118,8 +122,64 @@ void SwapData( EDA_BaseStruct* aItem, EDA_BaseStruct* aImage )
        return;
    }

    int layer, layerimg;
    layer = aItem->GetLayer();
    layerimg = aImage->GetLayer();
    aItem->SetLayer(layerimg);
    aImage->SetLayer(layer);

    switch( aItem->Type() )
    {
    case TYPE_MODULE:
        wxMessageBox( wxT( "SwapData(): TYPE_MODULE not handled" ) );
        break;

    case TYPE_ZONE_CONTAINER:
        wxMessageBox( wxT( "SwapData(): TYPE_ZONE_CONTAINER not handled" ) );
        break;

    case TYPE_DRAWSEGMENT:
        EXCHG( ((TRACK*)aItem)->m_Start, ((TRACK*)aImage)->m_Start);
        EXCHG( ((TRACK*)aItem)->m_End, ((TRACK*)aImage)->m_End);
        EXCHG( ((TRACK*)aItem)->m_Width,  ((TRACK*)aImage)->m_Width);
        EXCHG( ((TRACK*)aItem)->m_Shape,  ((TRACK*)aImage)->m_Shape);
        break;

    case TYPE_TRACK:
    case TYPE_VIA:
    case TYPE_ZONE:
        EXCHG( ((TRACK*)aItem)->m_Start, ((TRACK*)aImage)->m_Start);
        EXCHG( ((TRACK*)aItem)->m_End, ((TRACK*)aImage)->m_End);
        EXCHG( ((TRACK*)aItem)->m_Width,  ((TRACK*)aImage)->m_Width);
        EXCHG( ((TRACK*)aItem)->m_Shape,  ((TRACK*)aImage)->m_Shape);
    break;

    case TYPE_TEXTE:
        EXCHG( ((TEXTE_PCB*)aItem)->m_Mirror, ((TEXTE_PCB*)aImage)->m_Mirror);
        EXCHG( ((TEXTE_PCB*)aItem)->m_Size, ((TEXTE_PCB*)aImage)->m_Size);
        EXCHG( ((TEXTE_PCB*)aItem)->m_Pos, ((TEXTE_PCB*)aImage)->m_Pos);
        EXCHG( ((TEXTE_PCB*)aItem)->m_Width, ((TEXTE_PCB*)aImage)->m_Width);
        EXCHG( ((TEXTE_PCB*)aItem)->m_Orient, ((TEXTE_PCB*)aImage)->m_Orient);
        EXCHG( ((TEXTE_PCB*)aItem)->m_Text, ((TEXTE_PCB*)aImage)->m_Text);
        EXCHG( ((TEXTE_PCB*)aItem)->m_Italic, ((TEXTE_PCB*)aImage)->m_Italic);
        EXCHG( ((TEXTE_PCB*)aItem)->m_Bold, ((TEXTE_PCB*)aImage)->m_Bold);
        EXCHG( ((TEXTE_PCB*)aItem)->m_HJustify, ((TEXTE_PCB*)aImage)->m_HJustify);
        EXCHG( ((TEXTE_PCB*)aItem)->m_VJustify, ((TEXTE_PCB*)aImage)->m_VJustify);
       break;

    case TYPE_MIRE:
        EXCHG(((MIREPCB*)aItem)->m_Pos,((MIREPCB*)aImage)->m_Pos);
        EXCHG(((MIREPCB*)aItem)->m_Width, ((MIREPCB*)aImage)->m_Width);
        EXCHG(((MIREPCB*)aItem)->m_Size, ((MIREPCB*)aImage)->m_Size);
        EXCHG(((MIREPCB*)aItem)->m_Shape, ((MIREPCB*)aImage)->m_Shape);
    break;

    case TYPE_COTATION:
        EXCHG(((COTATION*)aItem)->m_Text->m_Size, ((COTATION*)aImage)->m_Text->m_Size);
        EXCHG(((COTATION*)aItem)->m_Text->m_Width, ((COTATION*)aImage)->m_Text->m_Width);
        EXCHG(((COTATION*)aItem)->m_Text->m_Mirror, ((COTATION*)aImage)->m_Text->m_Mirror);
        break;

    default:
        wxMessageBox( wxT( "SwapData() error: unexpected type" ) );
        break;
@@ -223,7 +283,7 @@ BOARD_ITEM* DuplicateStruct( BOARD_ITEM* aItem )


/***********************************************************************/
void WinEDA_PcbFrame::SaveCopyInUndoList( BOARD_ITEM*    aItemToCopy,
void WinEDA_PcbFrame::SaveCopyInUndoList( BOARD_ITEM*    aItem,
                                          UndoRedoOpType aCommandType,
                                          const wxPoint& aTransformPoint )
/***********************************************************************/
@@ -250,15 +310,14 @@ void WinEDA_PcbFrame::SaveCopyInUndoList( BOARD_ITEM* aItemToCopy,

    commandToUndo->m_TransformPoint = aTransformPoint;

    ITEM_PICKER itemWrapper( aItemToCopy, aCommandType );
    itemWrapper.m_PickedItemType = aItemToCopy->Type();
    ITEM_PICKER itemWrapper( aItem, aCommandType );
    itemWrapper.m_PickedItemType = aItem->Type();

    switch( aCommandType )
    {
    case UR_CHANGED:            /* Create a copy of schematic */
        CopyOfItem = NULL;//DuplicateStruct( aItemToCopy );
        itemWrapper.m_PickedItem = CopyOfItem;
        itemWrapper.m_Link = aItemToCopy;
        CopyOfItem = DuplicateStruct( aItem );
        itemWrapper.m_Link = CopyOfItem;
        if( CopyOfItem )
            commandToUndo->PushItem( itemWrapper );
        break;
@@ -324,8 +383,8 @@ void WinEDA_PcbFrame::SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList,
        {
        case UR_CHANGED:        /* Create a copy of schematic */
            CopyOfItem = DuplicateStruct( item );
            itemWrapper.m_PickedItem = CopyOfItem;
            itemWrapper.m_Link = item;
            itemWrapper.m_PickedItem = item;
            itemWrapper.m_Link = CopyOfItem;
            if( CopyOfItem )
                commandToUndo->PushItem( itemWrapper );
            break;
@@ -371,6 +430,7 @@ void WinEDA_PcbFrame::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRe
{
    BOARD_ITEM* item;
    bool        not_found = false;
    bool        reBuild_ratsnest = false;

    for( unsigned ii = 0; ii < aList->GetCount(); ii++  )
    {
@@ -388,25 +448,58 @@ void WinEDA_PcbFrame::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRe
                continue;
            }
        }
        item->m_Flags = 0;
        // see if one must rebuild ratsnets and pointers lists
        switch( item->Type() )
        {
            case TYPE_MODULE:
            case TYPE_ZONE_CONTAINER:
            case TYPE_TRACK:
            case TYPE_VIA:
                reBuild_ratsnest = true;
                break;
            default:
                break;
        }

        switch( aList->GetPickedItemStatus(ii) )
        {
        case UR_CHANGED:    /* Exchange old and new data for each item */
        {
            BOARD_ITEM* image = (BOARD_ITEM*) aList->GetPickedItemLink(ii);
            // Note modules and zones containers have a lot of data
            // so items and thier copy are swapped, not just edited data
            // The main drawback is pointers on these items must be rebuilt
            // but often, this is needed by connectivity change,
            // so this is not really an important drawback in this function
            // Could change later
            switch( item->Type() )
            {
                case TYPE_MODULE:
                case TYPE_ZONE_CONTAINER:
                    // Swap the item and its copy
                    GetBoard()->Remove(item);
                    GetBoard()->Add(image);
                    aList->SetPickedItem(image, ii);
                    aList->SetPickedItemLink(item, ii);
                    break;

                default:
                    // For other items: swap editable data only
                    SwapData( item, image );
                    break;
            }
        }
            break;

        case UR_NEW:        /* new items are deleted */
            aList->SetPickedItemStatus( UR_DELETED, ii );
            GetBoard()->Remove( item );
            item->m_Flags = UR_DELETED;
            break;

        case UR_DELETED:    /* deleted items are put in List, as new items */
            aList->SetPickedItemStatus( UR_NEW, ii );
            GetBoard()->Add( item );
            item->m_Flags = 0;
            break;

        case UR_MOVED:
@@ -436,6 +529,8 @@ void WinEDA_PcbFrame::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRe
    if( not_found )
        wxMessageBox( wxT( "Incomplete undo/redo command: item not found" ) );

    // Rebuild pointers and rastnest
    if( reBuild_ratsnest )
        Compile_Ratsnest( NULL, true );
}

@@ -527,8 +622,7 @@ void PCB_SCREEN::ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount
        while( 1 )
        {
            ITEM_PICKER     wrapper = curr_cmd->PopItem();
            EDA_BaseStruct* item    = wrapper.m_PickedItem;
            if( item == NULL ) // No more item in list.
            if( wrapper.m_PickedItem == NULL ) // No more item in list.
                break;
            switch( wrapper.m_UndoRedoStatus )
            {
@@ -545,8 +639,12 @@ void PCB_SCREEN::ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount
            case UR_NEW:        // Do nothing, items are in use, the picker is not owner of items
                break;

            case UR_CHANGED:
                delete wrapper.m_Link;      //  the picker is owner of this item
                break;

             default:
                delete item;    //  the picker is owner of this item
                delete wrapper.m_PickedItem;    //  the picker is owner of this item
                break;
            }
        }
+11 −1
Original line number Diff line number Diff line
@@ -47,6 +47,16 @@ wxString COTATION:: GetText( void )
    return m_Text->m_Text;
}

/**
 * Function SetLayer
 * sets the layer this item is on.
 * @param aLayer The layer number.
 */
void  COTATION::SetLayer( int aLayer )
{
    m_Layer = aLayer;
    m_Text->SetLayer( aLayer);
}

/*************************************/
void COTATION::Copy( COTATION* source )
+7 −0
Original line number Diff line number Diff line
@@ -37,6 +37,13 @@ public:
    }


    /**
     * Function SetLayer
     * sets the layer this item is on.
     * @param aLayer The layer number.
     */
    void  SetLayer( int aLayer );

    bool    ReadCotationDescr( FILE* File, int* LineNum );

    /**
Loading