pcbnew: work on undo/redo in progress Only delete commands are stored in undo/redo stack

This commit is contained in:
charras 2009-07-31 05:33:11 +00:00
parent 42022adb3f
commit f9be70f26d
17 changed files with 391 additions and 157 deletions

View File

@ -30,6 +30,16 @@
#include "base_struct.h"
#include "class_undoredo_container.h"
ITEM_PICKER::ITEM_PICKER( EDA_BaseStruct* aItem, UndoRedoOpType aUndoRedoStatus )
{
m_UndoRedoStatus = aUndoRedoStatus;
m_PickedItem = aItem;
m_PickedItemType = TYPE_NOT_INIT;
m_Link = NULL;
}
PICKED_ITEMS_LIST::PICKED_ITEMS_LIST()
{
m_Status = UR_UNSPECIFIED;
@ -70,11 +80,17 @@ void PICKED_ITEMS_LIST::PICKED_ITEMS_LIST::ClearItemsList()
void PICKED_ITEMS_LIST::ClearListAndDeleteItems()
{
for(unsigned ii = 0; ii < m_ItemsList.size(); ii++ )
delete m_ItemsList[ii].m_Item;
delete m_ItemsList[ii].m_PickedItem;
m_ItemsList.clear();
}
/** function GetItemWrapper
* @return the picker of a picked item
* @param aIdx = index of the picker in the picked list
* if this picker does not exist, a picker is returned,
* with its members set to 0 or NULL
*/
ITEM_PICKER PICKED_ITEMS_LIST::GetItemWrapper( unsigned int aIdx )
{
ITEM_PICKER picker;
@ -84,16 +100,24 @@ ITEM_PICKER PICKED_ITEMS_LIST::GetItemWrapper( unsigned int aIdx )
return picker;
}
EDA_BaseStruct* PICKED_ITEMS_LIST::GetItemData( unsigned int aIdx )
/** function GetPickedItem
* @return a pointer to the picked item, or null if does not exist
* @param aIdx = index of the picked item in the picked list
*/
EDA_BaseStruct* PICKED_ITEMS_LIST::GetPickedItem( unsigned int aIdx )
{
if( aIdx < m_ItemsList.size() )
return m_ItemsList[aIdx].m_Item;
return m_ItemsList[aIdx].m_PickedItem;
else
return NULL;
}
EDA_BaseStruct* PICKED_ITEMS_LIST::GetImage( unsigned int aIdx )
/** function GetLink
* @return link of the picked item, or null if does not exist
* @param aIdx = index of the picked item in the picked list
*/
EDA_BaseStruct* PICKED_ITEMS_LIST::GetLink( unsigned int aIdx )
{
if( aIdx < m_ItemsList.size() )
return m_ItemsList[aIdx].m_Link;
@ -102,7 +126,12 @@ EDA_BaseStruct* PICKED_ITEMS_LIST::GetImage( unsigned int aIdx )
}
UndoRedoOpType PICKED_ITEMS_LIST::GetItemStatus( unsigned int aIdx )
/** function GetPickedItemStatus
* @return the type of undo/redo opertaion associated to the picked item,
* or UR_UNSPECIFIED if does not exist
* @param aIdx = index of the picked item in the picked list
*/
UndoRedoOpType PICKED_ITEMS_LIST::GetPickedItemStatus( unsigned int aIdx )
{
if( aIdx < m_ItemsList.size() )
return m_ItemsList[aIdx].m_UndoRedoStatus;
@ -111,11 +140,16 @@ UndoRedoOpType PICKED_ITEMS_LIST::GetItemStatus( unsigned int aIdx )
}
bool PICKED_ITEMS_LIST::SetItem( EDA_BaseStruct* aItem, unsigned aIdx )
/** function SetPickedItem
* @param aItem = a pointer to the item to pick
* @param aIdx = index of the picker in the picked list
* @return true if the picker exists, or false if does not exist
*/
bool PICKED_ITEMS_LIST::SetPickedItem( EDA_BaseStruct* aItem, unsigned aIdx )
{
if( aIdx < m_ItemsList.size() )
{
m_ItemsList[aIdx].m_Item = aItem;
m_ItemsList[aIdx].m_PickedItem = aItem;
return true;
}
else
@ -123,11 +157,17 @@ bool PICKED_ITEMS_LIST::SetItem( EDA_BaseStruct* aItem, unsigned aIdx )
}
bool PICKED_ITEMS_LIST::SetLink( EDA_BaseStruct* aItem, unsigned aIdx )
/** function SetLink
* Set the link associated to a given picked item
* @param aLink = the link to the item associated to the picked item
* @param aIdx = index of the picker in the picked list
* @return true if the picker exists, or false if does not exist
*/
bool PICKED_ITEMS_LIST::SetLink( EDA_BaseStruct* aLink, unsigned aIdx )
{
if( aIdx < m_ItemsList.size() )
{
m_ItemsList[aIdx].m_Link = aItem;
m_ItemsList[aIdx].m_Link = aLink;
return true;
}
else
@ -135,11 +175,17 @@ bool PICKED_ITEMS_LIST::SetLink( EDA_BaseStruct* aItem, unsigned aIdx )
}
bool PICKED_ITEMS_LIST::SetItem( EDA_BaseStruct* aItem, UndoRedoOpType aStatus, unsigned aIdx )
/** function SetPickedItem
* @param aItem = a pointer to the item to pick
* @param aStatus = the type of undo/redo operation associated to the item to pick
* @param aIdx = index of the picker in the picked list
* @return true if the picker exists, or false if does not exist
*/
bool PICKED_ITEMS_LIST::SetPickedItem( EDA_BaseStruct* aItem, UndoRedoOpType aStatus, unsigned aIdx )
{
if( aIdx < m_ItemsList.size() )
{
m_ItemsList[aIdx].m_Item = aItem;
m_ItemsList[aIdx].m_PickedItem = aItem;
m_ItemsList[aIdx].m_UndoRedoStatus = aStatus;
return true;
}
@ -148,7 +194,13 @@ bool PICKED_ITEMS_LIST::SetItem( EDA_BaseStruct* aItem, UndoRedoOpType aStatus,
}
bool PICKED_ITEMS_LIST::SetItemStatus( UndoRedoOpType aStatus, unsigned aIdx )
/** function SetPickedItemStatus
* Set the the type of undo/redo operation for a given picked item
* @param aStatus = the type of undo/redo operation associated to the picked item
* @param aIdx = index of the picker in the picked list
* @return true if the picker exists, or false if does not exist
*/
bool PICKED_ITEMS_LIST::SetPickedItemStatus( UndoRedoOpType aStatus, unsigned aIdx )
{
if( aIdx < m_ItemsList.size() )
{
@ -160,7 +212,12 @@ bool PICKED_ITEMS_LIST::SetItemStatus( UndoRedoOpType aStatus, unsigned aIdx )
}
bool PICKED_ITEMS_LIST::RemoveItem( unsigned aIdx )
/** function RemovePickedItem
* remùove one entry (one picker) from the list of picked items
* @param aIdx = index of the picker in the picked list
* @return true if ok, or false if did not exist
*/
bool PICKED_ITEMS_LIST::RemovePickedItem( unsigned aIdx )
{
if( aIdx >= m_ItemsList.size() )
return false;

View File

@ -479,7 +479,7 @@ static void DrawMovingBlockOutlines( WinEDA_DrawPanel* panel, wxDC* DC,
block->Draw( panel, DC, block->m_MoveVector, g_XorMode, block->m_Color );
for( unsigned ii = 0; ii < block->GetCount(); ii++ )
{
schitem = (SCH_ITEM*) block->m_ItemsSelection.GetItemData( ii );
schitem = (SCH_ITEM*) block->m_ItemsSelection.GetPickedItem( ii );
DrawStructsInGhost( panel, DC, schitem, block->m_MoveVector );
}
}
@ -492,7 +492,7 @@ static void DrawMovingBlockOutlines( WinEDA_DrawPanel* panel, wxDC* DC,
for( unsigned ii = 0; ii < block->GetCount(); ii++ )
{
schitem = (SCH_ITEM*) block->m_ItemsSelection.GetItemData( ii );
schitem = (SCH_ITEM*) block->m_ItemsSelection.GetPickedItem( ii );
DrawStructsInGhost( panel, DC, schitem, block->m_MoveVector );
}
}
@ -515,9 +515,9 @@ void SaveStructListForPaste( PICKED_ITEMS_LIST& aItemsList )
for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
{
/* Make a copy of the original picked item. */
SCH_ITEM* DrawStructCopy = DuplicateStruct( (SCH_ITEM*) aItemsList.GetItemData( ii ) );
SCH_ITEM* DrawStructCopy = DuplicateStruct( (SCH_ITEM*) aItemsList.GetPickedItem( ii ) );
DrawStructCopy->SetParent( NULL );
item.m_Item = DrawStructCopy;
item.m_PickedItem = DrawStructCopy;
g_BlockSaveDataList.PushItem( item );
}
}
@ -543,8 +543,8 @@ void WinEDA_SchematicFrame::PasteListOfItems( wxDC* DC )
ITEM_PICKER picker( NULL, UR_NEW );
for( unsigned ii = 0; ii < g_BlockSaveDataList.GetCount(); ii++ )
{
Struct = DuplicateStruct( (SCH_ITEM*) g_BlockSaveDataList.m_ItemsSelection.GetItemData( ii ) );
picker.m_Item = Struct;
Struct = DuplicateStruct( (SCH_ITEM*) g_BlockSaveDataList.m_ItemsSelection.GetPickedItem( ii ) );
picker.m_PickedItem = Struct;
picklist.PushItem( picker );
// Clear annotation and init new time stamp for the new components:
@ -600,7 +600,7 @@ static void CollectStructsToDrag( SCH_SCREEN* screen )
// Sel .m_Flags to selected for a wire or bus in selected area if there is only one item:
if( pickedlist->GetCount() == 1 )
{
Struct = (SCH_ITEM*) pickedlist->GetItemData( 0 );
Struct = (SCH_ITEM*) pickedlist->GetPickedItem( 0 );
if( Struct->Type() == DRAW_SEGMENT_STRUCT_TYPE )
Struct->m_Flags = SELECTED;
}
@ -609,7 +609,7 @@ static void CollectStructsToDrag( SCH_SCREEN* screen )
{
for( unsigned ii = 0; ii < pickedlist->GetCount(); ii++ )
{
Struct = (SCH_ITEM*)(SCH_ITEM*) pickedlist->GetItemData( ii );
Struct = (SCH_ITEM*)(SCH_ITEM*) pickedlist->GetPickedItem( ii );
Struct->m_Flags = SELECTED;
}
}
@ -632,7 +632,7 @@ static void CollectStructsToDrag( SCH_SCREEN* screen )
* de selection */
for( unsigned ii = 0; ii < pickedlist->GetCount(); ii++ )
{
Struct = (SCH_ITEM*)(SCH_ITEM*) pickedlist->GetItemData( ii );
Struct = (SCH_ITEM*)(SCH_ITEM*) pickedlist->GetPickedItem( ii );
if( Struct->Type() == DRAW_SEGMENT_STRUCT_TYPE )
{
SegmStruct = (EDA_DrawLineStruct*) Struct;
@ -651,7 +651,7 @@ static void CollectStructsToDrag( SCH_SCREEN* screen )
for( unsigned ii = 0; ii < pickedlist->GetCount(); ii++ )
{
Struct = (SCH_ITEM*)(SCH_ITEM*) pickedlist->GetItemData( ii );
Struct = (SCH_ITEM*)(SCH_ITEM*) pickedlist->GetPickedItem( ii );
if( Struct->Type() == TYPE_SCH_COMPONENT )
{
// Add all pins of the selected component to list
@ -712,7 +712,7 @@ static void AddPickedItem( SCH_SCREEN* screen, wxPoint position )
for( unsigned ii = 0; ii < pickedlist->GetCount(); ii++ )
{
Struct = (SCH_ITEM*) pickedlist->GetItemData( ii );
Struct = (SCH_ITEM*) pickedlist->GetPickedItem( ii );
switch( Struct->Type() )
{
@ -737,6 +737,8 @@ static void AddPickedItem( SCH_SCREEN* screen, wxPoint position )
Struct = screen->EEDrawList;
while( Struct )
{
picker.m_PickedItem = Struct;
picker.m_PickedItemType = Struct->Type();
switch( Struct->Type() )
{
case TYPE_NOT_INIT:
@ -754,7 +756,6 @@ static void AddPickedItem( SCH_SCREEN* screen, wxPoint position )
break; /* Deja en liste */
if( STRUCT->m_Pos != position )
break;
picker.m_Item = Struct;
pickedlist->PushItem( picker );
break;
@ -767,14 +768,12 @@ static void AddPickedItem( SCH_SCREEN* screen, wxPoint position )
{
Struct->m_Flags = SELECTED | ENDPOINT | STARTPOINT;
Struct->m_Flags &= ~STARTPOINT;
picker.m_Item = Struct;
pickedlist->PushItem( picker );
}
else if( STRUCT->m_End == position )
{
Struct->m_Flags = SELECTED | ENDPOINT | STARTPOINT;
Struct->m_Flags &= ~ENDPOINT;
picker.m_Item = Struct;
pickedlist->PushItem( picker );
}
break;
@ -793,7 +792,6 @@ static void AddPickedItem( SCH_SCREEN* screen, wxPoint position )
if( STRUCT->m_Pos != position )
break;
Struct->m_Flags |= SELECTED;
picker.m_Item = Struct;
pickedlist->PushItem( picker );
break;
@ -806,7 +804,6 @@ static void AddPickedItem( SCH_SCREEN* screen, wxPoint position )
if( STRUCT->m_Pos != position )
break;
Struct->m_Flags |= SELECTED;
picker.m_Item = Struct;
pickedlist->PushItem( picker );
break;
@ -823,7 +820,6 @@ static void AddPickedItem( SCH_SCREEN* screen, wxPoint position )
if( STRUCT->m_Pos != position )
break;
Struct->m_Flags |= SELECTED;
picker.m_Item = Struct;
pickedlist->PushItem( picker );
break;
@ -835,7 +831,6 @@ static void AddPickedItem( SCH_SCREEN* screen, wxPoint position )
if( STRUCT->m_Pos != position )
break;
Struct->m_Flags |= SELECTED;
picker.m_Item = Struct;
pickedlist->PushItem( picker );
break;

View File

@ -149,7 +149,8 @@ void WinEDA_SchematicFrame::DeleteConnection( bool DeleteFullConnection )
DelStruct->m_Flags = SELECTEDNODE | STRUCT_DELETED;
/* Put this structure in the picked list: */
picker.m_Item = DelStruct;
picker.m_PickedItem = DelStruct;
picker.m_PickedItemType = DelStruct->Type();
pickList.PushItem(picker);
DelStruct = DelStruct->Next();
@ -237,7 +238,8 @@ void WinEDA_SchematicFrame::DeleteConnection( bool DeleteFullConnection )
{
DelStruct->m_Flags |= STRUCT_DELETED;
/* Put this structure in the picked list: */
picker.m_Item = DelStruct;
picker.m_PickedItem = DelStruct;
picker.m_PickedItemType = DelStruct->Type();
pickList.PushItem(picker);
DelStruct = GetScreen()->EEDrawList;
@ -264,7 +266,8 @@ void WinEDA_SchematicFrame::DeleteConnection( bool DeleteFullConnection )
DelStruct->m_Flags |= STRUCT_DELETED;
/* Put this structure in the picked list: */
picker.m_Item = DelStruct;
picker.m_PickedItem = DelStruct;
picker.m_PickedItemType = DelStruct->Type();
pickList.PushItem(picker);
}
#undef JUNCTION
@ -290,7 +293,8 @@ void WinEDA_SchematicFrame::DeleteConnection( bool DeleteFullConnection )
DelStruct->m_Flags |= STRUCT_DELETED;
/* Put this structure in the picked list: */
picker.m_Item = DelStruct;
picker.m_PickedItem = DelStruct;
picker.m_PickedItemType = DelStruct->Type();
pickList.PushItem(picker);
}
}

View File

@ -39,9 +39,9 @@ void WinEDA_LibeditFrame::SaveCopyInUndoList( EDA_BaseStruct* ItemToCopy,
while ( 1 )
{
wrapper = lastcmd->PopItem();
if ( wrapper.m_Item == NULL )
if ( wrapper.m_PickedItem == NULL )
break; // All items are removed
delete wrapper.m_Item;
delete wrapper.m_PickedItem;
}
delete lastcmd;
}
@ -69,7 +69,7 @@ void WinEDA_LibeditFrame::GetComponentFromRedoList(wxCommandEvent& event)
lastcmd = GetScreen()->PopCommandFromRedoList( );
wrapper = lastcmd->PopItem();
CurrentLibEntry = (EDA_LibComponentStruct*) wrapper.m_Item;
CurrentLibEntry = (EDA_LibComponentStruct*) wrapper.m_PickedItem;
if( CurrentLibEntry )
CurrentLibEntry->SetNext( NULL );
CurrentDrawItem = NULL;
@ -102,7 +102,7 @@ void WinEDA_LibeditFrame::GetComponentFromUndoList(wxCommandEvent& event)
lastcmd = GetScreen()->PopCommandFromUndoList( );
wrapper = lastcmd->PopItem();
CurrentLibEntry = (EDA_LibComponentStruct*) wrapper.m_Item;
CurrentLibEntry = (EDA_LibComponentStruct*) wrapper.m_PickedItem;
if( CurrentLibEntry )
CurrentLibEntry->SetNext( NULL );

View File

@ -149,7 +149,8 @@ int PickItemsInBlock( BLOCK_SELECTOR& aBlock, BASE_SCREEN* aScreen )
if( DrawStructInBox( OrigX, OrigY, x, y, DrawStruct ) )
{
/* Put this structure in the picked list: */
picker.m_Item = DrawStruct;
picker.m_PickedItem = DrawStruct;
picker.m_PickedItemType = DrawStruct->Type();
aBlock.PushItem(picker);
itemcount++;
}

View File

@ -29,7 +29,7 @@ void MirrorListOfItems( PICKED_ITEMS_LIST& aItemsList, wxPoint& aMirrorPoint )
{
for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
{
SCH_ITEM* item = (SCH_ITEM*) aItemsList.GetItemData( ii );
SCH_ITEM* item = (SCH_ITEM*) aItemsList.GetPickedItem( ii );
item->Mirror_Y( aMirrorPoint.x ); // Place it in its new position.
item->m_Flags = 0;
}
@ -46,7 +46,7 @@ void MoveItemsInList( PICKED_ITEMS_LIST& aItemsList, const wxPoint aMoveVector )
{
for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
{
SCH_ITEM* item = (SCH_ITEM*) aItemsList.GetItemData( ii );
SCH_ITEM* item = (SCH_ITEM*) aItemsList.GetPickedItem( ii );
item->Move( aMoveVector );
}
}
@ -66,8 +66,8 @@ void DeleteItemsInList( WinEDA_DrawPanel* panel, PICKED_ITEMS_LIST& aItemsList )
for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
{
SCH_ITEM* item = (SCH_ITEM*) aItemsList.GetItemData( ii );
itemWrapper.m_Item = item;
SCH_ITEM* item = (SCH_ITEM*) aItemsList.GetPickedItem( ii );
itemWrapper.m_PickedItem = item;
itemWrapper.m_UndoRedoStatus = UR_DELETED;
if( item->Type() == DRAW_HIERARCHICAL_PIN_SHEET_STRUCT_TYPE )
{
@ -77,7 +77,7 @@ void DeleteItemsInList( WinEDA_DrawPanel* panel, PICKED_ITEMS_LIST& aItemsList )
#if 0
Hierarchical_PIN_Sheet_Struct* pinlabel = (Hierarchical_PIN_Sheet_Struct*) item;
frame->DeleteSheetLabel( false, pinlabel->m_Parent );
itemWrapper.m_Item = pinlabel->m_Parent;
itemWrapper.m_PickedItem = pinlabel->m_Parent;
itemWrapper.m_UndoRedoStatus = UR_CHANGED;
itemsList.PushItem( itemWrapper );
#endif
@ -154,9 +154,9 @@ void DuplicateItemsInList( SCH_SCREEN* screen, PICKED_ITEMS_LIST& aItemsList, co
for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
{
newitem = DuplicateStruct( (SCH_ITEM*) aItemsList.GetItemData( ii ) );
aItemsList.SetItem( newitem, ii );
aItemsList.SetItemStatus( UR_NEW, ii );
newitem = DuplicateStruct( (SCH_ITEM*) aItemsList.GetPickedItem( ii ) );
aItemsList.SetPickedItem( newitem, ii );
aItemsList.SetPickedItemStatus( UR_NEW, ii );
{
switch( newitem->Type() )
{

View File

@ -212,12 +212,13 @@ void WinEDA_SchematicFrame::SaveCopyInUndoList( SCH_ITEM* aItemToCopy,
commandToUndo->m_TransformPoint = aTransformPoint;
ITEM_PICKER itemWrapper( aItemToCopy, aCommandType );
itemWrapper.m_PickedItemType = aItemToCopy->Type();
switch( aCommandType )
{
case UR_CHANGED: /* Create a copy of schematic */
CopyOfItem = DuplicateStruct( aItemToCopy );
itemWrapper.m_Item = CopyOfItem;
itemWrapper.m_PickedItem = CopyOfItem;
itemWrapper.m_Link = aItemToCopy;
if ( CopyOfItem )
commandToUndo->PushItem( itemWrapper );
@ -268,19 +269,20 @@ void WinEDA_SchematicFrame::SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList,
for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
{
SCH_ITEM* ItemToCopy = (SCH_ITEM*) aItemsList.GetItemData( ii );
UndoRedoOpType command = aItemsList.GetItemStatus( ii );
SCH_ITEM* ItemToCopy = (SCH_ITEM*) aItemsList.GetPickedItem( ii );
UndoRedoOpType command = aItemsList.GetPickedItemStatus( ii );
if( command == UR_UNSPECIFIED )
{
command = aTypeCommand;
}
itemWrapper.m_Item = ItemToCopy;
itemWrapper.m_PickedItem = ItemToCopy;
itemWrapper.m_PickedItemType = ItemToCopy->Type();
itemWrapper.m_UndoRedoStatus = command;
switch( command )
{
case UR_CHANGED: /* Create a copy of schematic */
CopyOfItem = DuplicateStruct( ItemToCopy );
itemWrapper.m_Item = CopyOfItem;
itemWrapper.m_PickedItem = CopyOfItem;
itemWrapper.m_Link = ItemToCopy;
if ( CopyOfItem )
commandToUndo->PushItem( itemWrapper );
@ -335,7 +337,7 @@ void WinEDA_SchematicFrame::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
for( unsigned ii = 0; ii < aList->GetCount(); ii++ )
{
ITEM_PICKER itemWrapper = aList->GetItemWrapper( ii );
item = (SCH_ITEM*) itemWrapper.m_Item;
item = (SCH_ITEM*) itemWrapper.m_PickedItem;
wxASSERT( item );
SCH_ITEM* image = (SCH_ITEM*) itemWrapper.m_Link;
switch( itemWrapper.m_UndoRedoStatus )
@ -345,13 +347,13 @@ void WinEDA_SchematicFrame::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
break;
case UR_NEW: /* new items are deleted */
aList->SetItemStatus( UR_DELETED, ii );
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->SetItemStatus( UR_NEW, ii );
aList->SetPickedItemStatus( UR_NEW, ii );
item->SetNext( GetScreen()->EEDrawList );
GetScreen()->EEDrawList = item;
item->m_Flags = 0;
@ -372,7 +374,7 @@ void WinEDA_SchematicFrame::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
case UR_WIRE_IMAGE:
/* Exchange the current wires and the old wires */
alt_item = GetScreen()->ExtractWires( false );
aList->SetItem( alt_item, ii );
aList->SetPickedItem( alt_item, ii );
while( item )
{
SCH_ITEM* nextitem = item->Next();
@ -496,7 +498,7 @@ void SCH_SCREEN::ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount
while( 1 )
{
ITEM_PICKER wrapper = curr_cmd->PopItem();
EDA_BaseStruct* item = wrapper.m_Item;
EDA_BaseStruct* item = wrapper.m_PickedItem;
if( item == NULL ) // No more item in list.
break;
switch( wrapper.m_UndoRedoStatus )

View File

@ -257,7 +257,7 @@ static void DrawMovingBlockOutlines( WinEDA_DrawPanel* panel, wxDC* DC, bool era
/************************************************/
void WinEDA_BasePcbFrame::Block_Delete( wxDC* DC )
void WinEDA_GerberFrame::Block_Delete( wxDC* DC )
/************************************************/
/*
@ -302,7 +302,7 @@ void WinEDA_BasePcbFrame::Block_Delete( wxDC* DC )
/************************************************/
void WinEDA_BasePcbFrame::Block_Move( wxDC* DC )
void WinEDA_GerberFrame::Block_Move( wxDC* DC )
/************************************************/
/*
@ -366,7 +366,7 @@ void WinEDA_BasePcbFrame::Block_Move( wxDC* DC )
/************************************************/
void WinEDA_BasePcbFrame::Block_Mirror_X( wxDC* DC )
void WinEDA_GerberFrame::Block_Mirror_X( wxDC* DC )
/************************************************/
/*
@ -426,7 +426,7 @@ void WinEDA_BasePcbFrame::Block_Mirror_X( wxDC* DC )
/**************************************************/
void WinEDA_BasePcbFrame::Block_Duplicate( wxDC* DC )
void WinEDA_GerberFrame::Block_Duplicate( wxDC* DC )
/**************************************************/
/*

View File

@ -53,6 +53,43 @@ public:
virtual void HandleBlockPlace( wxDC* DC );
virtual int HandleBlockEnd( wxDC* DC );
/* Block operations: */
/**
* Function Block_Delete
* deletes all tracks and segments within the selected block.
* Defined separately in pcbnew and gerbview
*
* @param DC A device context to draw on.
*/
void Block_Delete( wxDC* DC );
void Block_Rotate( wxDC* DC );
void Block_Invert( wxDC* DC );
/**
* Function Block_Move
* moves all tracks and segments within the selected block.
* New location is determined by the current offset from the selected block's original location.
* Defined separately in pcbnew and gerbview
*
* @param DC A device context to draw on.
*/
void Block_Move( wxDC* DC );
/**
* Function Block_Mirror_X
* mirrors all tracks and segments within the currently selected block in the X axis.
*
* @param DC A device context to draw on.
*/
void Block_Mirror_X( wxDC* DC );
/**
* Function Block_Duplicate
* copies-and-moves all tracks and segments within the selected block.
* New location is determined by the current offset from the selected block's original location.
* Defined separately in pcbnew and gerbview
*
* @param DC A device context to draw on.
*/
void Block_Duplicate( wxDC* DC );
void InstallDrillFrame( wxCommandEvent& event );
void ToPostProcess( wxCommandEvent& event );
void Genere_HPGL( const wxString& FullFileName, int Layers );

View File

@ -26,6 +26,8 @@
#define _CLASS_UNDOREDO_CONTAINER_H
#include <vector>
#include "base_struct.h"
/**
* @info Undo Redo considerations:
* Basically we have 3 cases
@ -65,9 +67,11 @@ class ITEM_PICKER
{
public:
UndoRedoOpType m_UndoRedoStatus; /* type of operation to undo/redo for this item */
EDA_BaseStruct* m_Item; /* Pointer on the schematic or board item that is concerned,
EDA_BaseStruct* m_PickedItem; /* Pointer on the schematic or board item that is concerned (picked),
* or in undo redo commands, the copy of an edited item.
*/
KICAD_T m_PickedItemType; /* type of schematic or board item that is concerned
*/
EDA_BaseStruct* m_Link; /* Pointer on an other item. Used in undo redo command
* used when a duplicate exists i.e. when an item is modified,
* and the copy of initial item exists (the duplicate)
@ -76,12 +80,8 @@ public:
*/
public:
ITEM_PICKER( EDA_BaseStruct* aItem = NULL, UndoRedoOpType aUndoRedoStatus = UR_UNSPECIFIED )
{
m_UndoRedoStatus = aUndoRedoStatus;
m_Item = aItem;
m_Link = NULL;
}
ITEM_PICKER( EDA_BaseStruct* aItem = NULL,
UndoRedoOpType aUndoRedoStatus = UR_UNSPECIFIED );
};
/* Class PICKED_ITEMS_LIST
@ -121,15 +121,70 @@ public:
}
/** function GetItemWrapper
* @return the picker of a picked item
* @param aIdx = index of the picker in the picked list
* if this picker does not exist, a picker is returned,
* with its members set to 0 or NULL
*/
ITEM_PICKER GetItemWrapper( unsigned int aIdx );
EDA_BaseStruct* GetItemData( unsigned int aIdx );
EDA_BaseStruct* GetImage( unsigned int aIdx );
UndoRedoOpType GetItemStatus( unsigned int aIdx );
bool SetItem( EDA_BaseStruct* aItem, unsigned aIdx );
bool SetItem( EDA_BaseStruct* aItem, UndoRedoOpType aStatus, unsigned aIdx );
bool SetLink( EDA_BaseStruct* aItem, unsigned aIdx );
bool SetItemStatus( UndoRedoOpType aStatus, unsigned aIdx );
bool RemoveItem( unsigned aIdx );
/** function GetPickedItem
* @return a pointer to the picked item
* @param aIdx = index of the picked item in the picked list
*/
EDA_BaseStruct* GetPickedItem( unsigned int aIdx );
/** function GetLink
* @return link of the picked item, or null if does not exist
* @param aIdx = index of the picked item in the picked list
*/
EDA_BaseStruct* GetLink( unsigned int aIdx );
/** function GetPickedItemStatus
* @return the type of undo/redo opertaion associated to the picked item,
* or UR_UNSPECIFIED if does not exist
* @param aIdx = index of the picked item in the picked list
*/
UndoRedoOpType GetPickedItemStatus( unsigned int aIdx );
/** function SetPickedItem
* @param aItem = a pointer to the item to pick
* @param aIdx = index of the picker in the picked list
* @return true if the pixker exists, or false if does not exist
*/
bool SetPickedItem( EDA_BaseStruct* aItem, unsigned aIdx );
/** function SetPickedItem
* @param aItem = a pointer to the item to pick
* @param aStatus = the type of undo/redo operation associated to the item to pick
* @param aIdx = index of the picker in the picked list
* @return true if the pixker exists, or false if does not exist
*/
bool SetPickedItem( EDA_BaseStruct* aItem, UndoRedoOpType aStatus, unsigned aIdx );
/** function SetLink
* Set the link associated to a given picked item
* @param aLink = the link to the item associated to the picked item
* @param aIdx = index of the picker in the picked list
* @return true if the pixker exists, or false if does not exist
*/
bool SetLink( EDA_BaseStruct* aLink, unsigned aIdx );
/** function SetPickedItemStatus
* Set the the type of undo/redo operation for a given picked item
* @param aStatus = the type of undo/redo operation associated to the picked item
* @param aIdx = index of the picker in the picked list
* @return true if the picker exists, or false if does not exist
*/
bool SetPickedItemStatus( UndoRedoOpType aStatus, unsigned aIdx );
/** function RemovePickedItem
* remùove one entry (one picker) from the list of picked items
* @param aIdx = index of the picker in the picked list
* @return true if ok, or false if did not exist
*/
bool RemovePickedItem( unsigned aIdx );
/** Function CopyList
* copy all data from aSource

View File

@ -310,43 +310,6 @@ public:
virtual void SaveCopyInUndoList( BOARD_ITEM* aItemToCopy, UndoRedoOpType aTypeCommand,
const wxPoint& aTransformPoint = wxPoint(0,0) ) = 0;
/* Block operations: */
/**
* Function Block_Delete
* deletes all tracks and segments within the selected block.
* Defined separately in pcbnew and gerbview
*
* @param DC A device context to draw on.
*/
void Block_Delete( wxDC* DC );
void Block_Rotate( wxDC* DC );
void Block_Invert( wxDC* DC );
/**
* Function Block_Move
* moves all tracks and segments within the selected block.
* New location is determined by the current offset from the selected block's original location.
* Defined separately in pcbnew and gerbview
*
* @param DC A device context to draw on.
*/
void Block_Move( wxDC* DC );
/**
* Function Block_Mirror_X
* mirrors all tracks and segments within the currently selected block in the X axis.
*
* @param DC A device context to draw on.
*/
void Block_Mirror_X( wxDC* DC );
/**
* Function Block_Duplicate
* copies-and-moves all tracks and segments within the selected block.
* New location is determined by the current offset from the selected block's original location.
* Defined separately in pcbnew and gerbview
*
* @param DC A device context to draw on.
*/
void Block_Duplicate( wxDC* DC );
// layerhandling:
// (See pcbnew/sel_layer.cpp for description of why null_layer parameter is provided)

View File

@ -165,6 +165,44 @@ public:
void HandleBlockPlace( wxDC* DC );
int HandleBlockEnd( wxDC* DC );
/* Block operations: */
/**
* Function Block_Delete
* deletes all tracks and segments within the selected block.
* Defined separately in pcbnew and gerbview
*
* @param DC A device context to draw on.
*/
void Block_Delete( wxDC* DC );
void Block_Rotate( wxDC* DC );
void Block_Invert( wxDC* DC );
/**
* Function Block_Move
* moves all tracks and segments within the selected block.
* New location is determined by the current offset from the selected block's original location.
* Defined separately in pcbnew and gerbview
*
* @param DC A device context to draw on.
*/
void Block_Move( wxDC* DC );
/**
* Function Block_Mirror_X
* mirrors all tracks and segments within the currently selected block in the X axis.
*
* @param DC A device context to draw on.
*/
void Block_Mirror_X( wxDC* DC );
/**
* Function Block_Duplicate
* copies-and-moves all tracks and segments within the selected block.
* New location is determined by the current offset from the selected block's original location.
* Defined separately in pcbnew and gerbview
*
* @param DC A device context to draw on.
*/
void Block_Duplicate( wxDC* DC );
void SetToolbars();
void Process_Settings( wxCommandEvent& event );
void InstallPcbOptionsFrame( const wxPoint& pos, wxDC* DC, int id );

View File

@ -432,9 +432,8 @@ static void DrawMovingBlockOutlines( WinEDA_DrawPanel* panel, wxDC* DC, bool era
/************************************************/
void WinEDA_BasePcbFrame::Block_Delete( wxDC* DC )
void WinEDA_PcbFrame::Block_Delete( wxDC* DC )
/************************************************/
/*
* routine d'effacement du block deja selectionne
*/
@ -449,6 +448,9 @@ void WinEDA_BasePcbFrame::Block_Delete( wxDC* DC )
GetScreen()->m_BlockLocate.Normalize();
SetCurItem( NULL );
PICKED_ITEMS_LIST itemsList;
ITEM_PICKER picker(NULL,UR_DELETED);
/* Effacement des modules */
if( Block_Include_Modules )
{
@ -460,13 +462,16 @@ void WinEDA_BasePcbFrame::Block_Delete( wxDC* DC )
if( module->HitTest( GetScreen()->m_BlockLocate ) )
{
module->m_Flags = 0;
module->DeleteStructure();
module->UnLink();
m_Pcb->m_Status_Pcb = 0;
picker.m_PickedItem = module;
picker.m_PickedItemType = module->Type();
itemsList.PushItem(picker);
}
}
}
/* Effacement des Pistes */
/* Remove tracks and vias */
if( Block_Include_Tracks )
{
TRACK* pt_segm;
@ -476,13 +481,16 @@ void WinEDA_BasePcbFrame::Block_Delete( wxDC* DC )
NextS = pt_segm->Next();
if( pt_segm->HitTest( GetScreen()->m_BlockLocate ) )
{
/* la piste est ici bonne a etre efface */
pt_segm->DeleteStructure();
/* This track is in bloc: remove it */
pt_segm->UnLink();
picker.m_PickedItem = pt_segm;
picker.m_PickedItemType = pt_segm->Type();
itemsList.PushItem(picker);
}
}
}
/* Effacement des Elements De Dessin */
/* Remove graphic items */
masque_layer = EDGE_LAYER;
if( Block_Include_Draw_Items )
masque_layer = ALL_LAYERS;
@ -494,7 +502,7 @@ void WinEDA_BasePcbFrame::Block_Delete( wxDC* DC )
for( ; PtStruct != NULL; PtStruct = NextS )
{
NextS = PtStruct->Next();
bool remove_me = false;
switch( PtStruct->Type() )
{
case TYPE_DRAWSEGMENT:
@ -502,10 +510,7 @@ void WinEDA_BasePcbFrame::Block_Delete( wxDC* DC )
break;
if( ! PtStruct->HitTest( GetScreen()->m_BlockLocate ) )
break;
/* l'element est ici bon a etre efface */
PtStruct->Draw( DrawPanel, DC, GR_XOR );
PtStruct->DeleteStructure();
remove_me = true; // This item is in bloc: remove it
break;
case TYPE_TEXTE:
@ -513,10 +518,7 @@ void WinEDA_BasePcbFrame::Block_Delete( wxDC* DC )
break;
if( ! PtStruct->HitTest( GetScreen()->m_BlockLocate ) )
break;
/* le texte est ici bon a etre efface */
PtStruct->Draw( DrawPanel, DC, GR_XOR );
/* Suppression du texte en Memoire*/
PtStruct->DeleteStructure();
remove_me = true; // This item is in bloc: remove it
break;
case TYPE_MIRE:
@ -524,8 +526,7 @@ void WinEDA_BasePcbFrame::Block_Delete( wxDC* DC )
break;
if( ! PtStruct->HitTest( GetScreen()->m_BlockLocate ) )
break;
/* l'element est ici bon a etre efface */
PtStruct->DeleteStructure();
remove_me = true; // This item is in bloc: remove it
break;
case TYPE_COTATION:
@ -533,12 +534,20 @@ void WinEDA_BasePcbFrame::Block_Delete( wxDC* DC )
break;
if( ! PtStruct->HitTest( GetScreen()->m_BlockLocate ) )
break;
PtStruct->DeleteStructure();
remove_me = true; // This item is in bloc: remove it
break;
default:
break;
}
if ( remove_me )
{
PtStruct->UnLink();
picker.m_PickedItem = PtStruct;
picker.m_PickedItemType = PtStruct->Type();
itemsList.PushItem(picker);
}
}
/* Effacement des Zones */
@ -552,7 +561,10 @@ void WinEDA_BasePcbFrame::Block_Delete( wxDC* DC )
NextSegZ = pt_segm->Next();
if( pt_segm->HitTest( GetScreen()->m_BlockLocate ) )
{
pt_segm->DeleteStructure();
pt_segm->UnLink();
picker.m_PickedItem = PtStruct;
picker.m_PickedItemType = PtStruct->Type();
itemsList.PushItem(picker);
}
}
@ -560,19 +572,25 @@ void WinEDA_BasePcbFrame::Block_Delete( wxDC* DC )
{
if( m_Pcb->GetArea(ii)->HitTest( GetScreen()->m_BlockLocate ) )
{
m_Pcb->Delete(m_Pcb->GetArea(ii));
BOARD_ITEM* zone_c = m_Pcb->Remove(m_Pcb->GetArea(ii));
ii--; // because the current data was removed, ii points actually the next data
picker.m_PickedItem = zone_c;
picker.m_PickedItemType = zone_c->Type();
itemsList.PushItem(picker);
}
}
}
if ( itemsList.GetCount() )
SaveCopyInUndoList( itemsList, UR_DELETED );
DrawPanel->Refresh( TRUE );
Compile_Ratsnest( DC, TRUE );
}
/****************************************************/
void WinEDA_BasePcbFrame::Block_Rotate( wxDC* DC )
void WinEDA_PcbFrame::Block_Rotate( wxDC* DC )
/****************************************************/
/**
@ -732,7 +750,7 @@ void WinEDA_BasePcbFrame::Block_Rotate( wxDC* DC )
/*****************************************************/
void WinEDA_BasePcbFrame::Block_Invert( wxDC* DC )
void WinEDA_PcbFrame::Block_Invert( wxDC* DC )
/*****************************************************/
/*
@ -919,7 +937,7 @@ void WinEDA_BasePcbFrame::Block_Invert( wxDC* DC )
/************************************************/
void WinEDA_BasePcbFrame::Block_Move( wxDC* DC )
void WinEDA_PcbFrame::Block_Move( wxDC* DC )
/************************************************/
/*
@ -1064,7 +1082,7 @@ void WinEDA_BasePcbFrame::Block_Move( wxDC* DC )
/**************************************************/
void WinEDA_BasePcbFrame::Block_Duplicate( wxDC* DC )
void WinEDA_PcbFrame::Block_Duplicate( wxDC* DC )
/**************************************************/
/*

View File

@ -59,6 +59,47 @@
*
*/
/** function TestForExistingItem
* test if aItem exists somewhere in lists of items
* This is a function unsed by PutDataInPreviousState to be sure an item was not deleted
* since an undo or redo.
* This could be possible:
* - 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 function avoids a pcbnew crash
* @param aBoard = board to test
* @param aItem = item to find
*/
static bool TestForExistingItem( BOARD * aPcb, BOARD_ITEM * aItem )
{
BOARD_ITEM *item;
// search in tracks:
for( item = aPcb->m_Track; item != NULL; item = item->Next() )
if (item == aItem )
return true;
// search in modules:
for( item = aPcb->m_Modules; item != NULL; item = item->Next() )
if (item == aItem )
return true;
// Search in drawings
for( item = aPcb->m_Drawings; item != NULL; item = item->Next() )
if (item == aItem )
return true;
// Search in zones outlines
for ( int ii = 0; ii < aPcb->GetAreaCount(); ii++ )
if( aPcb->GetArea(ii) == aItem )
return true;
// search in zones segm:
for( item = aPcb->m_Zone; item != NULL; item = item->Next() )
if (item == aItem )
return true;
return false;
}
/**************************************************************/
void SwapData( EDA_BaseStruct* aItem, EDA_BaseStruct* aImage )
@ -148,12 +189,13 @@ void WinEDA_PcbFrame::SaveCopyInUndoList( BOARD_ITEM* aItemToCopy,
commandToUndo->m_TransformPoint = aTransformPoint;
ITEM_PICKER itemWrapper( aItemToCopy, aCommandType );
itemWrapper.m_PickedItemType = aItemToCopy->Type();
switch( aCommandType )
{
case UR_CHANGED: /* Create a copy of schematic */
CopyOfItem = DuplicateStruct( aItemToCopy );
itemWrapper.m_Item = CopyOfItem;
itemWrapper.m_PickedItem = CopyOfItem;
itemWrapper.m_Link = aItemToCopy;
if( CopyOfItem )
commandToUndo->PushItem( itemWrapper );
@ -204,20 +246,21 @@ void WinEDA_PcbFrame::SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList,
for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
{
BOARD_ITEM* ItemToCopy = (BOARD_ITEM*) aItemsList.GetItemData( ii );
UndoRedoOpType command = aItemsList.GetItemStatus( ii );
BOARD_ITEM* ItemToCopy = (BOARD_ITEM*) aItemsList.GetPickedItem( ii );
UndoRedoOpType command = aItemsList.GetPickedItemStatus( ii );
if( command == UR_UNSPECIFIED )
{
command = aTypeCommand;
}
wxASSERT( ItemToCopy );
itemWrapper.m_Item = ItemToCopy;
itemWrapper.m_PickedItem = ItemToCopy;
itemWrapper.m_PickedItemType = ItemToCopy->Type();
itemWrapper.m_UndoRedoStatus = command;
switch( command )
{
case UR_CHANGED: /* Create a copy of schematic */
CopyOfItem = DuplicateStruct( ItemToCopy );
itemWrapper.m_Item = CopyOfItem;
itemWrapper.m_PickedItem = CopyOfItem;
itemWrapper.m_Link = ItemToCopy;
if( CopyOfItem )
commandToUndo->PushItem( itemWrapper );
@ -267,13 +310,26 @@ void WinEDA_PcbFrame::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
{
BOARD_ITEM* item;
bool as_moved = false;
bool not_found = false;
for( unsigned ii = 0; ii < aList->GetCount(); ii++ )
{
ITEM_PICKER itemWrapper = aList->GetItemWrapper( ii );
item = (BOARD_ITEM*) itemWrapper.m_Item;
item = (BOARD_ITEM*) itemWrapper.m_PickedItem;
wxASSERT( item );
BOARD_ITEM* image = (BOARD_ITEM*) itemWrapper.m_Link;
if( itemWrapper.m_UndoRedoStatus != UR_DELETED )
{
if( ! TestForExistingItem( GetBoard(), item ) )
{
// Remove this non existant item
aList->RemovePickedItem( ii );
ii--; // the current item was removed, ii points now the next item
// whe must decrement it because it will be incremented
not_found = true;
continue;
}
}
switch( itemWrapper.m_UndoRedoStatus )
{
case UR_CHANGED: /* Exchange old and new data for each item */
@ -281,13 +337,13 @@ void WinEDA_PcbFrame::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
break;
case UR_NEW: /* new items are deleted */
aList->SetItemStatus( UR_DELETED, ii );
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->SetItemStatus( UR_NEW, ii );
aList->SetPickedItemStatus( UR_NEW, ii );
GetBoard()->Add( item );
item->m_Flags = 0;
break;
@ -315,6 +371,9 @@ void WinEDA_PcbFrame::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
}
}
if( not_found )
wxMessageBox(wxT("Incomplete undo/redo command: item not found" ) );
// Undo for move transform needs to change the general move vector:
if( as_moved )
aList->m_TransformPoint = -aList->m_TransformPoint;
@ -412,7 +471,7 @@ void PCB_SCREEN::ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount
while( 1 )
{
ITEM_PICKER wrapper = curr_cmd->PopItem();
EDA_BaseStruct* item = wrapper.m_Item;
EDA_BaseStruct* item = wrapper.m_PickedItem;
if( item == NULL ) // No more item in list.
break;
switch( wrapper.m_UndoRedoStatus )

View File

@ -165,7 +165,8 @@ void WinEDA_PcbFrame::Delete_net( wxDC* DC, TRACK* aTrack )
GetBoard()->m_Track.Remove( segm );
// redraw the area where the track was
DrawPanel->PostDirtyRect( segm->GetBoundingBox() );
picker.m_Item = segm;
picker.m_PickedItem = segm;
picker.m_PickedItemType = segm->Type();
itemsList.PushItem(picker);
}
@ -214,7 +215,8 @@ void WinEDA_PcbFrame::Remove_One_Track( wxDC* DC, TRACK* pt_segm )
GetBoard()->m_Track.Remove( tracksegment );
// redraw the area where the track was
DrawPanel->PostDirtyRect( tracksegment->GetBoundingBox() );
picker.m_Item = tracksegment;
picker.m_PickedItem = tracksegment;
picker.m_PickedItemType = tracksegment->Type();
itemsList.PushItem(picker);
}

View File

@ -41,9 +41,9 @@ void WinEDA_ModuleEditFrame::SaveCopyInUndoList( BOARD_ITEM* ItemToCopy,
while ( 1 )
{
wrapper = lastcmd->PopItem();
if ( wrapper.m_Item == NULL )
if ( wrapper.m_PickedItem == NULL )
break; // All items are removed
delete wrapper.m_Item;
delete wrapper.m_PickedItem;
}
delete lastcmd;
}
@ -71,7 +71,7 @@ void WinEDA_ModuleEditFrame::GetComponentFromRedoList(wxCommandEvent& event)
wrapper = lastcmd->PopItem();
GetBoard()->Add( (MODULE*) wrapper.m_Item );
GetBoard()->Add( (MODULE*) wrapper.m_PickedItem );
SetCurItem( NULL );;
GetScreen()->SetModify();
@ -102,8 +102,8 @@ void WinEDA_ModuleEditFrame::GetComponentFromUndoList(wxCommandEvent& event)
wrapper = lastcmd->PopItem();
if( wrapper.m_Item )
GetBoard()->Add( (MODULE*) wrapper.m_Item, ADD_APPEND );
if( wrapper.m_PickedItem )
GetBoard()->Add( (MODULE*) wrapper.m_PickedItem, ADD_APPEND );
GetScreen()->SetModify();

View File

@ -830,7 +830,10 @@ void WinEDA_PcbFrame::Delete_Zone_Contour( wxDC* DC, ZONE_CONTAINER* zone_contai
Delete_Zone_Fill( DC, NULL, zone_container->m_TimeStamp ); // Remove fill segments
if( ncont == 0 ) // This is the main outline: remove all
GetBoard()->Delete( zone_container );
{
SaveCopyInUndoList( zone_container, UR_DELETED );
GetBoard()->Remove( zone_container );
}
else
{