pcbnew: Starting work on undo/redo in pcbnew. Only some delete item commands are stored in undo/redo stack

This commit is contained in:
charras 2009-07-29 13:10:36 +00:00
parent 2a7ac9d3c4
commit d535a0fc97
55 changed files with 966 additions and 717 deletions

View File

@ -4,6 +4,13 @@ KiCad ChangeLog 2009
Please add newer entries at the top, list the date and your name with Please add newer entries at the top, list the date and your name with
email address. email address.
2009-july-29 UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
================================================================================
++pcbnew
Starting work on undo/redo in pcbnew.
Currently, undo redo commands are only delete one item (and only for some items)
2009-july-25 UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr> 2009-july-25 UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
================================================================================ ================================================================================
++all ++all

View File

@ -8,7 +8,7 @@
#include "appl_wxstruct.h" #include "appl_wxstruct.h"
#define BUILD_VERSION "(20090723-unstable)" #define BUILD_VERSION "(20090729-unstable)"
#ifdef HAVE_SVN_VERSION #ifdef HAVE_SVN_VERSION

View File

@ -28,7 +28,7 @@ BASE_SCREEN* ActiveScreen = NULL;
BASE_SCREEN::BASE_SCREEN( KICAD_T aType ) : EDA_BaseStruct( aType ) BASE_SCREEN::BASE_SCREEN( KICAD_T aType ) : EDA_BaseStruct( aType )
{ {
EEDrawList = NULL; /* Schematic items list */ EEDrawList = NULL; /* Schematic items list */
m_UndoRedoCountMax = 1; /* undo/Redo command Max depth */ m_UndoRedoCountMax = 10; /* undo/Redo command Max depth, 10 is a reasonnable value */
m_FirstRedraw = TRUE; m_FirstRedraw = TRUE;
m_ScreenNumber = 1; m_ScreenNumber = 1;
m_NumberOfScreen = 1; /* Hierarchy: Root: ScreenNumber = 1 */ m_NumberOfScreen = 1; /* Hierarchy: Root: ScreenNumber = 1 */
@ -48,7 +48,6 @@ BASE_SCREEN::BASE_SCREEN( KICAD_T aType ) : EDA_BaseStruct( aType )
BASE_SCREEN::~BASE_SCREEN() BASE_SCREEN::~BASE_SCREEN()
/******************************/ /******************************/
{ {
ClearUndoRedoList();
} }
@ -484,8 +483,8 @@ void BASE_SCREEN::ClearUndoRedoList()
/* free the undo and the redo lists /* free the undo and the redo lists
*/ */
{ {
m_UndoList.ClearCommandList(); ClearUndoORRedoList( m_UndoList );
m_RedoList.ClearCommandList(); ClearUndoORRedoList( m_RedoList );
} }
@ -497,14 +496,12 @@ void BASE_SCREEN::PushCommandToUndoList( PICKED_ITEMS_LIST* aNewitem )
* Deletes olds items if > count max. * Deletes olds items if > count max.
*/ */
{ {
m_UndoList.PushCommand(aNewitem); m_UndoList.PushCommand( aNewitem );
while( m_UndoList.m_CommandsList.size() > 0 &&
m_UndoList.m_CommandsList.size() >= m_UndoRedoCountMax )
{
delete m_UndoList.m_CommandsList[0];
m_UndoList.m_CommandsList.erase( m_UndoList.m_CommandsList.begin() );
}
/* Delete the extra items, if count max reached */
int extraitems = GetUndoCommandCount() - m_UndoRedoCountMax;
if( extraitems > 0 ) // Delete the extra items
ClearUndoORRedoList( m_UndoList, extraitems );
} }
@ -512,13 +509,12 @@ void BASE_SCREEN::PushCommandToUndoList( PICKED_ITEMS_LIST* aNewitem )
void BASE_SCREEN::PushCommandToRedoList( PICKED_ITEMS_LIST* aNewitem ) void BASE_SCREEN::PushCommandToRedoList( PICKED_ITEMS_LIST* aNewitem )
/***********************************************************/ /***********************************************************/
{ {
m_RedoList.PushCommand(aNewitem); m_RedoList.PushCommand( aNewitem );
while( m_RedoList.m_CommandsList.size() > 0 &&
m_RedoList.m_CommandsList.size() >= m_UndoRedoCountMax ) /* Delete the extra items, if count max reached */
{ int extraitems = GetRedoCommandCount() - m_UndoRedoCountMax;
delete m_RedoList.m_CommandsList[0]; if( extraitems > 0 ) // Delete the extra items
m_RedoList.m_CommandsList.erase( m_RedoList.m_CommandsList.begin() ); ClearUndoORRedoList( m_RedoList, extraitems );
}
} }

View File

@ -67,9 +67,6 @@ wxString g_ViaType_Name[4] = {
wxArrayString g_LibName_List; // library list to load wxArrayString g_LibName_List; // library list to load
BOARD_ITEM* g_UnDeleteStack[UNDELETE_STACK_SIZE]; // Linked list of deleted items
int g_UnDeleteStackPtr;
DISPLAY_OPTIONS DisplayOpt; /* Display options for board items */ DISPLAY_OPTIONS DisplayOpt; /* Display options for board items */
/* PCB file name extension definitions. */ /* PCB file name extension definitions. */

View File

@ -219,6 +219,16 @@ public:
void Process_Settings( wxCommandEvent& event ); void Process_Settings( wxCommandEvent& event );
void Show3D_Frame( wxCommandEvent& event ); void Show3D_Frame( wxCommandEvent& event );
/* SaveCopyInUndoList() virtual
* currently: do nothing in cvpcb.
* but but be defined because it is a pure virtual in WinEDA_BasePcbFrame
*/
virtual void SaveCopyInUndoList( BOARD_ITEM* aItemToCopy,
UndoRedoOpType aTypeCommand = UR_UNSPECIFIED,
const wxPoint& aTransformPoint = wxPoint(0,0) )
{
}
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
}; };

View File

@ -308,3 +308,12 @@ void WinEDA_DisplayFrame::Show3D_Frame( wxCommandEvent& event )
wxFRAME_FLOAT_ON_PARENT ); wxFRAME_FLOAT_ON_PARENT );
m_Draw3DFrame->Show( TRUE ); m_Draw3DFrame->Show( TRUE );
} }
/* Virtual fonction needed by the PCB_SCREEN class derived from BASE_SCREEN
* this is a virtaul pure function in BASE_SCREEN
* do nothing in cvpcb
* could be removed later
*/
void PCB_SCREEN::ClearUndoORRedoList(UNDO_REDO_CONTAINER&, int )
{
}

View File

@ -84,7 +84,6 @@ SCH_SCREEN::SCH_SCREEN( KICAD_T type ) : BASE_SCREEN( type )
AddGrid( SchematicGridList[i] ); AddGrid( SchematicGridList[i] );
SetGrid( wxRealPoint( 50, 50 ) ); /* usual grid size */ SetGrid( wxRealPoint( 50, 50 ) ); /* usual grid size */
m_UndoRedoCountMax = 10; // Undo/redo levels count. 10 is a reasonnable value
m_RefCount = 0; m_RefCount = 0;
m_Center = false; // Suitable for schematic only. for libedit and viewlib, must be set to true m_Center = false; // Suitable for schematic only. for libedit and viewlib, must be set to true
InitDatas(); InitDatas();

View File

@ -127,6 +127,7 @@ bool WinEDA_LibeditFrame::LoadOneLibraryPart()
return FALSE; return FALSE;
} }
GetScreen()->ClearUndoRedoList();
LoadOneLibraryPartAux( LibEntry, CurrentLib ); LoadOneLibraryPartAux( LibEntry, CurrentLib );
ReCreateHToolbar(); ReCreateHToolbar();
Zoom_Automatique( FALSE ); Zoom_Automatique( FALSE );

View File

@ -3,13 +3,13 @@
/********************************************/ /********************************************/
#include "fctsys.h" #include "fctsys.h"
#include "gr_basic.h" #include "class_drawpanel.h"
#include "common.h" #include "common.h"
#include "program.h" #include "program.h"
#include "libcmp.h" #include "libcmp.h"
#include "general.h" #include "general.h"
#include "id.h" //#include "id.h"
#include "protos.h" #include "protos.h"
@ -49,7 +49,7 @@ void WinEDA_LibeditFrame::SaveCopyInUndoList( EDA_BaseStruct* ItemToCopy,
/******************************************************/ /******************************************************/
bool WinEDA_LibeditFrame::GetComponentFromRedoList() void WinEDA_LibeditFrame::GetComponentFromRedoList(wxCommandEvent& event)
/******************************************************/ /******************************************************/
/* Redo the last edition: /* Redo the last edition:
@ -59,7 +59,7 @@ bool WinEDA_LibeditFrame::GetComponentFromRedoList()
*/ */
{ {
if ( GetScreen()->GetRedoCommandCount() <= 0 ) if ( GetScreen()->GetRedoCommandCount() <= 0 )
return false; return;
PICKED_ITEMS_LIST* lastcmd = new PICKED_ITEMS_LIST(); PICKED_ITEMS_LIST* lastcmd = new PICKED_ITEMS_LIST();
ITEM_PICKER wrapper(CurrentLibEntry); ITEM_PICKER wrapper(CurrentLibEntry);
@ -77,12 +77,12 @@ bool WinEDA_LibeditFrame::GetComponentFromRedoList()
ReCreateHToolbar(); ReCreateHToolbar();
SetToolbars(); SetToolbars();
return true; DrawPanel->Refresh();
} }
/******************************************************/ /******************************************************/
bool WinEDA_LibeditFrame::GetComponentFromUndoList() void WinEDA_LibeditFrame::GetComponentFromUndoList(wxCommandEvent& event)
/******************************************************/ /******************************************************/
/* Undo the last edition: /* Undo the last edition:
@ -92,7 +92,7 @@ bool WinEDA_LibeditFrame::GetComponentFromUndoList()
*/ */
{ {
if ( GetScreen()->GetUndoCommandCount() <= 0 ) if ( GetScreen()->GetUndoCommandCount() <= 0 )
return false; return;
PICKED_ITEMS_LIST* lastcmd = new PICKED_ITEMS_LIST(); PICKED_ITEMS_LIST* lastcmd = new PICKED_ITEMS_LIST();
ITEM_PICKER wrapper(CurrentLibEntry); ITEM_PICKER wrapper(CurrentLibEntry);
@ -111,5 +111,5 @@ bool WinEDA_LibeditFrame::GetComponentFromUndoList()
ReCreateHToolbar(); ReCreateHToolbar();
SetToolbars(); SetToolbars();
return true; DrawPanel->Refresh();
} }

View File

@ -44,8 +44,37 @@ BEGIN_EVENT_TABLE( WinEDA_LibeditFrame, WinEDA_DrawFrame )
// Tools et boutons de Libedit: // Tools et boutons de Libedit:
/* Main horizontal toolbar */ /* Main horizontal toolbar */
EVT_TOOL_RANGE( ID_LIBEDIT_START_H_TOOL, ID_LIBEDIT_END_H_TOOL, EVT_TOOL( ID_LIBEDIT_SAVE_CURRENT_LIB,
WinEDA_LibeditFrame::Process_Special_Functions ) WinEDA_LibeditFrame::Process_Special_Functions )
EVT_TOOL( ID_LIBEDIT_SELECT_CURRENT_LIB,
WinEDA_LibeditFrame::Process_Special_Functions )
EVT_TOOL( ID_LIBEDIT_DELETE_PART,
WinEDA_LibeditFrame::Process_Special_Functions )
EVT_TOOL( ID_LIBEDIT_NEW_PART,
WinEDA_LibeditFrame::Process_Special_Functions )
EVT_TOOL( ID_LIBEDIT_SELECT_PART,
WinEDA_LibeditFrame::Process_Special_Functions )
EVT_TOOL( ID_LIBEDIT_SAVE_CURRENT_PART,
WinEDA_LibeditFrame::Process_Special_Functions )
EVT_TOOL( ID_LIBEDIT_UNDO,
WinEDA_LibeditFrame::GetComponentFromUndoList )
EVT_TOOL( ID_LIBEDIT_REDO,
WinEDA_LibeditFrame::GetComponentFromRedoList )
EVT_TOOL( ID_LIBEDIT_GET_FRAME_EDIT_PART,
WinEDA_LibeditFrame::Process_Special_Functions )
EVT_TOOL( ID_LIBEDIT_GET_FRAME_EDIT_FIELDS,
WinEDA_LibeditFrame::Process_Special_Functions )
EVT_TOOL( ID_LIBEDIT_CHECK_PART,
WinEDA_LibeditFrame::Process_Special_Functions )
EVT_TOOL( ID_DE_MORGAN_NORMAL_BUTT,
WinEDA_LibeditFrame::Process_Special_Functions )
EVT_TOOL( ID_DE_MORGAN_CONVERT_BUTT,
WinEDA_LibeditFrame::Process_Special_Functions )
EVT_TOOL( ID_LIBEDIT_VIEW_DOC,
WinEDA_LibeditFrame::Process_Special_Functions )
EVT_TOOL( ID_LIBEDIT_EDIT_PIN_BY_PIN,
WinEDA_LibeditFrame::Process_Special_Functions )
EVT_KICAD_CHOICEBOX( ID_LIBEDIT_SELECT_PART_NUMBER, EVT_KICAD_CHOICEBOX( ID_LIBEDIT_SELECT_PART_NUMBER,
WinEDA_LibeditFrame::Process_Special_Functions ) WinEDA_LibeditFrame::Process_Special_Functions )
EVT_KICAD_CHOICEBOX( ID_LIBEDIT_SELECT_ALIAS, EVT_KICAD_CHOICEBOX( ID_LIBEDIT_SELECT_ALIAS,
@ -60,7 +89,6 @@ BEGIN_EVENT_TABLE( WinEDA_LibeditFrame, WinEDA_DrawFrame )
EVT_MENU_RANGE( ID_POPUP_START_RANGE, ID_POPUP_END_RANGE, EVT_MENU_RANGE( ID_POPUP_START_RANGE, ID_POPUP_END_RANGE,
WinEDA_LibeditFrame::Process_Special_Functions ) WinEDA_LibeditFrame::Process_Special_Functions )
// Annulation de commande en cours
EVT_MENU_RANGE( ID_POPUP_GENERAL_START_RANGE, ID_POPUP_GENERAL_END_RANGE, EVT_MENU_RANGE( ID_POPUP_GENERAL_START_RANGE, ID_POPUP_GENERAL_END_RANGE,
WinEDA_LibeditFrame::Process_Special_Functions ) WinEDA_LibeditFrame::Process_Special_Functions )
@ -768,16 +796,6 @@ void WinEDA_LibeditFrame::Process_Special_Functions( wxCommandEvent& event )
HandleBlockPlace( &dc ); HandleBlockPlace( &dc );
break; break;
case ID_LIBEDIT_UNDO:
if( GetComponentFromUndoList() )
DrawPanel->Refresh( true );
break;
case ID_LIBEDIT_REDO:
if( GetComponentFromRedoList() )
DrawPanel->Refresh( true );
break;
default: default:
DisplayError( this, wxT( "WinEDA_LibeditFrame::Process_Special_Functions error" ) ); DisplayError( this, wxT( "WinEDA_LibeditFrame::Process_Special_Functions error" ) );
break; break;

View File

@ -256,7 +256,7 @@ void WinEDA_SchematicFrame::ReCreateMenuBar()
item->SetBitmap( add_hierarchical_subsheet_xpm ); item->SetBitmap( add_hierarchical_subsheet_xpm );
placeMenu->Append( item ); placeMenu->Append( item );
item = new wxMenuItem( placeMenu, ID_IMPORT_GLABEL_BUTT, item = new wxMenuItem( placeMenu, ID_IMPORT_HLABEL_BUTT,
_( "Import Hierarchical Label" ), _( "Import Hierarchical Label" ),
_( "Place a pin sheet created by importing a hierarchical label from sheet" ), _( "Place a pin sheet created by importing a hierarchical label from sheet" ),
wxITEM_NORMAL ); wxITEM_NORMAL );

View File

@ -248,7 +248,7 @@ void WinEDA_SchematicFrame::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
} }
break; break;
case ID_IMPORT_GLABEL_BUTT: case ID_IMPORT_HLABEL_BUTT:
case ID_SHEET_LABEL_BUTT: case ID_SHEET_LABEL_BUTT:
if( (DrawStruct == NULL) || (DrawStruct->m_Flags == 0) ) if( (DrawStruct == NULL) || (DrawStruct->m_Flags == 0) )
DrawStruct = SchematicGeneralLocateAndDisplay(); DrawStruct = SchematicGeneralLocateAndDisplay();
@ -259,7 +259,7 @@ void WinEDA_SchematicFrame::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
if( (DrawStruct->Type() == DRAW_SHEET_STRUCT_TYPE) if( (DrawStruct->Type() == DRAW_SHEET_STRUCT_TYPE)
&& (DrawStruct->m_Flags == 0) ) && (DrawStruct->m_Flags == 0) )
{ {
if( m_ID_current_state == ID_IMPORT_GLABEL_BUTT ) if( m_ID_current_state == ID_IMPORT_HLABEL_BUTT )
GetScreen()->SetCurItem( GetScreen()->SetCurItem(
Import_PinSheet( (DrawSheetStruct*) DrawStruct, DC ) ); Import_PinSheet( (DrawSheetStruct*) DrawStruct, DC ) );
else else

View File

@ -240,7 +240,7 @@ void WinEDA_SchematicFrame::Process_Special_Functions( wxCommandEvent& event )
SetToolID( id, wxCURSOR_PENCIL, _( "Add PinSheet" ) ); SetToolID( id, wxCURSOR_PENCIL, _( "Add PinSheet" ) );
break; break;
case ID_IMPORT_GLABEL_BUTT: case ID_IMPORT_HLABEL_BUTT:
SetToolID( id, wxCURSOR_PENCIL, _( "Import PinSheet" ) ); SetToolID( id, wxCURSOR_PENCIL, _( "Import PinSheet" ) );
break; break;
@ -718,22 +718,6 @@ void WinEDA_SchematicFrame::Process_Special_Functions( wxCommandEvent& event )
((MARKER_SCH*)screen->GetCurItem())->DisplayMarkerInfo( this ); ((MARKER_SCH*)screen->GetCurItem())->DisplayMarkerInfo( this );
break; break;
case ID_SCHEMATIC_UNDO:
if( GetSchematicFromUndoList() )
{
TestDanglingEnds( screen->EEDrawList, NULL );
DrawPanel->Refresh( TRUE );
}
break;
case ID_SCHEMATIC_REDO:
if( GetSchematicFromRedoList() )
{
TestDanglingEnds( screen->EEDrawList, NULL );
DrawPanel->Refresh( TRUE );
}
break;
default: // Log error: default: // Log error:
DisplayError( this, DisplayError( this,
wxT( "WinEDA_SchematicFrame::Process_Special_Functions error" ) ); wxT( "WinEDA_SchematicFrame::Process_Special_Functions error" ) );

View File

@ -1,10 +1,10 @@
/*************************************************************/ /************************************************************/
/* eeschema: undo and redo functions for schemùatic editor */ /* eeschema: undo and redo functions for schematic editor */
/*************************************************************/ /************************************************************/
#include "fctsys.h" #include "fctsys.h"
#include "common.h" #include "common.h"
#include "confirm.h" #include "class_drawpanel.h"
#include "program.h" #include "program.h"
#include "libcmp.h" #include "libcmp.h"
@ -29,6 +29,9 @@
* - delete item(s) command * - delete item(s) command
* - change item(s) command * - change item(s) command
* - add item(s) command * - add item(s) command
* and 2 cases for block:
* - move list of items
* - mirror (Y) list of items
* *
* Undo command * Undo command
* - delete item(s) command: * - delete item(s) command:
@ -52,6 +55,11 @@
* - add item(s) command * - add item(s) command
* => The list of item(s) is used to create a deleted list in undo list(same as a delete command) * => The list of item(s) is used to create a deleted list in undo list(same as a delete command)
* *
* Some block operations that change items can be undoed without memorise items, just the coordiantes of the transform:
* move list of items (undo/redo is made by moving with the opposite move vector)
* mirror (Y) and flip list of items (undo/redo is made by mirror or flip items)
* so they are handled specifically.
*
* A problem is the hierarchical sheet handling. * A problem is the hierarchical sheet handling.
* the data associated (subhierarchy, uno/redo list) is deleted only * the data associated (subhierarchy, uno/redo list) is deleted only
* when the sheet is really deleted (i.e. when deleted from undo or redo list) * when the sheet is really deleted (i.e. when deleted from undo or redo list)
@ -166,7 +174,7 @@ void SwapData( EDA_BaseStruct* aItem, EDA_BaseStruct* aImage )
// not directly used in schematic: // not directly used in schematic:
default: default:
DisplayInfoMessage( NULL, wxT( "SwapData() error: unexpected type" ) ); wxMessageBox(wxT( "SwapData() error: unexpected type" ) );
break; break;
} }
} }
@ -211,7 +219,8 @@ void WinEDA_SchematicFrame::SaveCopyInUndoList( SCH_ITEM* aItemToCopy,
CopyOfItem = DuplicateStruct( aItemToCopy ); CopyOfItem = DuplicateStruct( aItemToCopy );
itemWrapper.m_Item = CopyOfItem; itemWrapper.m_Item = CopyOfItem;
itemWrapper.m_Link = aItemToCopy; itemWrapper.m_Link = aItemToCopy;
commandToUndo->PushItem( itemWrapper ); if ( CopyOfItem )
commandToUndo->PushItem( itemWrapper );
break; break;
case UR_NEW: case UR_NEW:
@ -225,16 +234,21 @@ void WinEDA_SchematicFrame::SaveCopyInUndoList( SCH_ITEM* aItemToCopy,
{ {
wxString msg; wxString msg;
msg.Printf( wxT( "SaveCopyInUndoList() error (unknown code %X)" ), aCommandType ); msg.Printf( wxT( "SaveCopyInUndoList() error (unknown code %X)" ), aCommandType );
DisplayError( this, msg ); wxMessageBox( msg );
} }
break; break;
} }
/* Save the copy in undo list */ if( commandToUndo->GetCount() )
GetScreen()->PushCommandToUndoList( commandToUndo ); {
/* Save the copy in undo list */
GetScreen()->PushCommandToUndoList( commandToUndo );
/* Clear redo list, because after new save there is no redo to do */ /* Clear redo list, because after new save there is no redo to do */
GetScreen()->ClearUndoORRedoList( GetScreen()->m_RedoList ); GetScreen()->ClearUndoORRedoList( GetScreen()->m_RedoList );
}
else
delete commandToUndo;
} }
@ -268,7 +282,8 @@ void WinEDA_SchematicFrame::SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList,
CopyOfItem = DuplicateStruct( ItemToCopy ); CopyOfItem = DuplicateStruct( ItemToCopy );
itemWrapper.m_Item = CopyOfItem; itemWrapper.m_Item = CopyOfItem;
itemWrapper.m_Link = ItemToCopy; itemWrapper.m_Link = ItemToCopy;
commandToUndo->PushItem( itemWrapper ); if ( CopyOfItem )
commandToUndo->PushItem( itemWrapper );
break; break;
case UR_MOVED: case UR_MOVED:
@ -286,48 +301,22 @@ void WinEDA_SchematicFrame::SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList,
{ {
wxString msg; wxString msg;
msg.Printf( wxT( "SaveCopyInUndoList() error (unknown code %X)" ), command ); msg.Printf( wxT( "SaveCopyInUndoList() error (unknown code %X)" ), command );
DisplayError( this, msg ); wxMessageBox( msg );
} }
break; break;
} }
} }
/* Save the copy in undo list */ if( commandToUndo->GetCount() )
GetScreen()->PushCommandToUndoList( commandToUndo ); {
/* Save the copy in undo list */
GetScreen()->PushCommandToUndoList( commandToUndo );
/* Clear redo list, because after new save there is no redo to do */ /* Clear redo list, because after new save there is no redo to do */
GetScreen()->ClearUndoORRedoList( GetScreen()->m_RedoList ); GetScreen()->ClearUndoORRedoList( GetScreen()->m_RedoList );
} }
else
delete commandToUndo;
/**********************************************************/
bool WinEDA_SchematicFrame::GetSchematicFromRedoList()
/**********************************************************/
/* Redo the last edition:
* - Save the current schematic in undo list
* - Get the old version
* @return false if nothing done, else true
*/
{
if( GetScreen()->GetRedoCommandCount() == 0 )
return false;
/* Get the old wrapper and put it in UndoList */
PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromRedoList();
GetScreen()->PushCommandToUndoList( List );
/* Redo the command: */
PutDataInPreviousState( List );
CurrentDrawItem = NULL;
GetScreen()->SetModify();
SetSheetNumberAndCount();
ReCreateHToolbar();
SetToolbars();
return true;
} }
@ -401,7 +390,7 @@ void WinEDA_SchematicFrame::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
msg.Printf( wxT( msg.Printf( wxT(
"PutDataInPreviousState() error (unknown code %X)" ), "PutDataInPreviousState() error (unknown code %X)" ),
itemWrapper.m_UndoRedoStatus ); itemWrapper.m_UndoRedoStatus );
DisplayError( this, msg ); wxMessageBox( msg );
} }
break; break;
} }
@ -414,7 +403,7 @@ void WinEDA_SchematicFrame::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
/**********************************************************/ /**********************************************************/
bool WinEDA_SchematicFrame::GetSchematicFromUndoList() void WinEDA_SchematicFrame::GetSchematicFromUndoList(wxCommandEvent& event)
/**********************************************************/ /**********************************************************/
/** Function GetSchematicFromUndoList /** Function GetSchematicFromUndoList
@ -425,7 +414,7 @@ bool WinEDA_SchematicFrame::GetSchematicFromUndoList()
*/ */
{ {
if( GetScreen()->GetUndoCommandCount() <= 0 ) if( GetScreen()->GetUndoCommandCount() <= 0 )
return false; return;
/* Get the old wrapper and put it in RedoList */ /* Get the old wrapper and put it in RedoList */
PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromUndoList(); PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromUndoList();
@ -439,7 +428,39 @@ bool WinEDA_SchematicFrame::GetSchematicFromUndoList()
ReCreateHToolbar(); ReCreateHToolbar();
SetToolbars(); SetToolbars();
return true; TestDanglingEnds( GetScreen()->EEDrawList, NULL );
DrawPanel->Refresh( );
}
/**********************************************************/
void WinEDA_SchematicFrame::GetSchematicFromRedoList(wxCommandEvent& event)
/**********************************************************/
/* Redo the last edition:
* - Save the current schematic in undo list
* - Get the old version
* @return false if nothing done, else true
*/
{
if( GetScreen()->GetRedoCommandCount() == 0 )
return;
/* Get the old wrapper and put it in UndoList */
PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromRedoList();
GetScreen()->PushCommandToUndoList( List );
/* Redo the command: */
PutDataInPreviousState( List );
CurrentDrawItem = NULL;
GetScreen()->SetModify();
SetSheetNumberAndCount();
ReCreateHToolbar();
SetToolbars();
TestDanglingEnds( GetScreen()->EEDrawList, NULL );
DrawPanel->Refresh( );
} }
@ -450,11 +471,11 @@ void SCH_SCREEN::ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount
/** Function ClearUndoORRedoList /** Function ClearUndoORRedoList
* free the undo or redo list from List element * free the undo or redo list from List element
* Wrappers are deleted. * Wrappers are deleted.
* datas pointed by wrappers are deleted if not flagged UR_NEW * datas pointed by wrappers are deleted if not in use in schematic
* because they are copy of used data or they are not in use (DELETED) * i.e. when they are copy of a schematic item or they are no more in use (DELETED)
* @param aList = the UNDO_REDO_CONTAINER to clear * @param aList = the UNDO_REDO_CONTAINER to clear
* @param aItemCount = the count of items to remove. < 0 for all items * @param aItemCount = the count of items to remove. < 0 for all items
* items are removed from the beginning of the list. * items (commands stored in list) are removed from the beginning of the list.
* So this function can be called to remove old commands * So this function can be called to remove old commands
*/ */
{ {
@ -506,45 +527,3 @@ void SCH_SCREEN::ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount
delete curr_cmd; // Delete command delete curr_cmd; // Delete command
} }
} }
/*****************************************/
void SCH_SCREEN::ClearUndoRedoList()
/*****************************************/
/* free the undo and the redo lists
*/
{
ClearUndoORRedoList( m_UndoList );
ClearUndoORRedoList( m_RedoList );
}
/***********************************************************/
void SCH_SCREEN::PushCommandToUndoList( PICKED_ITEMS_LIST* aItem )
/************************************************************/
/* Put newitem in head of undo list
* Deletes olds items if > count max.
*/
{
m_UndoList.PushCommand( aItem );
/* Delete the extra items, if count max reached */
int extraitems = GetUndoCommandCount() - m_UndoRedoCountMax;
if( extraitems > 0 ) // Delete the extra items
ClearUndoORRedoList( m_UndoList, extraitems );
}
/***********************************************************/
void SCH_SCREEN::PushCommandToRedoList( PICKED_ITEMS_LIST* aItem )
/***********************************************************/
{
m_RedoList.PushCommand( aItem );
/* Delete the extra items, if count max reached */
int extraitems = GetRedoCommandCount() - m_UndoRedoCountMax;
if( extraitems > 0 ) // Delete the extra items
ClearUndoORRedoList( m_RedoList, extraitems );
}

View File

@ -48,10 +48,6 @@ BEGIN_EVENT_TABLE( WinEDA_SchematicFrame, WinEDA_DrawFrame )
EVT_TOOL( ID_NEW_PROJECT, WinEDA_SchematicFrame::OnNewProject ) EVT_TOOL( ID_NEW_PROJECT, WinEDA_SchematicFrame::OnNewProject )
EVT_TOOL( ID_LOAD_PROJECT, WinEDA_SchematicFrame::OnLoadProject ) EVT_TOOL( ID_LOAD_PROJECT, WinEDA_SchematicFrame::OnLoadProject )
EVT_TOOL_RANGE( ID_SCHEMATIC_MAIN_TOOLBAR_START,
ID_SCHEMATIC_MAIN_TOOLBAR_END,
WinEDA_SchematicFrame::Process_Special_Functions )
EVT_MENU( ID_SAVE_PROJECT, WinEDA_SchematicFrame::Save_File ) EVT_MENU( ID_SAVE_PROJECT, WinEDA_SchematicFrame::Save_File )
EVT_MENU( ID_SAVE_ONE_SHEET, WinEDA_SchematicFrame::Save_File ) EVT_MENU( ID_SAVE_ONE_SHEET, WinEDA_SchematicFrame::Save_File )
EVT_MENU( ID_SAVE_ONE_SHEET_AS, WinEDA_SchematicFrame::Save_File ) EVT_MENU( ID_SAVE_ONE_SHEET_AS, WinEDA_SchematicFrame::Save_File )
@ -87,7 +83,8 @@ BEGIN_EVENT_TABLE( WinEDA_SchematicFrame, WinEDA_DrawFrame )
EVT_TOOL( wxID_CUT, WinEDA_SchematicFrame::Process_Special_Functions ) EVT_TOOL( wxID_CUT, WinEDA_SchematicFrame::Process_Special_Functions )
EVT_TOOL( wxID_COPY, WinEDA_SchematicFrame::Process_Special_Functions ) EVT_TOOL( wxID_COPY, WinEDA_SchematicFrame::Process_Special_Functions )
EVT_TOOL( wxID_PASTE, WinEDA_SchematicFrame::Process_Special_Functions ) EVT_TOOL( wxID_PASTE, WinEDA_SchematicFrame::Process_Special_Functions )
EVT_TOOL( ID_UNDO_BUTT, WinEDA_SchematicFrame::Process_Special_Functions ) EVT_TOOL( ID_SCHEMATIC_UNDO, WinEDA_SchematicFrame::GetSchematicFromUndoList )
EVT_TOOL( ID_SCHEMATIC_REDO, WinEDA_SchematicFrame::GetSchematicFromRedoList )
EVT_TOOL( ID_GET_ANNOTATE, WinEDA_SchematicFrame::OnAnnotate ) EVT_TOOL( ID_GET_ANNOTATE, WinEDA_SchematicFrame::OnAnnotate )
EVT_TOOL( ID_GEN_PRINT, WinEDA_SchematicFrame::ToPrinter ) EVT_TOOL( ID_GEN_PRINT, WinEDA_SchematicFrame::ToPrinter )
EVT_TOOL( ID_GET_ERC, WinEDA_SchematicFrame::OnErc ) EVT_TOOL( ID_GET_ERC, WinEDA_SchematicFrame::OnErc )

View File

@ -201,7 +201,7 @@ void WinEDA_SchematicFrame::ReCreateVToolbar()
wxBitmap( add_hierarchical_subsheet_xpm ), wxBitmap( add_hierarchical_subsheet_xpm ),
_( "Place hierarchical sheet" ), wxITEM_CHECK ); _( "Place hierarchical sheet" ), wxITEM_CHECK );
m_VToolBar->AddTool( ID_POPUP_IMPORT_GLABEL, wxEmptyString, m_VToolBar->AddTool( ID_IMPORT_HLABEL_BUTT, wxEmptyString,
wxBitmap( import_hierarchical_label_xpm ), wxBitmap( import_hierarchical_label_xpm ),
_( "Place a pin sheet , imported from the corresponding hierarchical label in sheet" ), _( "Place a pin sheet , imported from the corresponding hierarchical label in sheet" ),
wxITEM_CHECK ); wxITEM_CHECK );

View File

@ -38,7 +38,7 @@ set(GERBVIEW_SRCS
set(GERBVIEW_EXTRA_SRCS set(GERBVIEW_EXTRA_SRCS
# ../pcbnew/class_board_item.cpp # ../pcbnew/class_board_item.cpp
# ../pcbnew/class_drawsegment.cpp # ../pcbnew/class_drawsegment.cpp
../pcbnew/undelete.cpp # ../pcbnew/undelete.cpp
../share/setpage.cpp ../share/setpage.cpp
../pcbnew/dialog_print_using_printer.cpp ../pcbnew/dialog_print_using_printer.cpp

View File

@ -90,7 +90,10 @@ TRACK* WinEDA_GerberFrame::Delete_Segment( wxDC* DC, TRACK* Track )
Trace_Segment( DrawPanel, DC, Track, GR_XOR ); Trace_Segment( DrawPanel, DC, Track, GR_XOR );
SaveItemEfface( Track, 1 ); DLIST<TRACK>* container = (DLIST<TRACK>*) Track->GetList();
wxASSERT( container );
container->Remove( Track );
GetScreen()->SetModify(); GetScreen()->SetModify();
return NULL; return NULL;
} }

View File

@ -144,22 +144,6 @@ void WinEDA_GerberFrame::Process_Special_Functions( wxCommandEvent& event )
case ID_PCB_GLOBAL_DELETE: case ID_PCB_GLOBAL_DELETE:
Erase_Current_Layer( TRUE ); Erase_Current_Layer( TRUE );
break; break;
case wxID_CUT:
break;
case wxID_COPY:
break;
case wxID_PASTE:
// HandleBlockBegin(&dc, BLOCK_PASTE);
break;
case ID_UNDO_BUTT:
UnDeleteItem( &dc );
break;
case ID_GET_TOOLS: case ID_GET_TOOLS:
// InstallToolsFrame(this, wxPoint(-1,-1) ); // InstallToolsFrame(this, wxPoint(-1,-1) );

View File

@ -225,18 +225,6 @@ void WinEDA_GerberFrame::SetToolbars()
m_HToolBar->EnableTool( wxID_COPY, FALSE ); m_HToolBar->EnableTool( wxID_COPY, FALSE );
} }
if( g_UnDeleteStackPtr )
{
m_HToolBar->EnableTool( wxID_PASTE, TRUE );
m_HToolBar->EnableTool( ID_UNDO_BUTT, TRUE );
}
else
{
m_HToolBar->EnableTool( wxID_PASTE, FALSE );
m_HToolBar->EnableTool( ID_UNDO_BUTT, FALSE );
}
if( m_SelLayerBox->GetSelection() != if( m_SelLayerBox->GetSelection() !=
( (PCB_SCREEN*) GetScreen() )->m_Active_Layer ) ( (PCB_SCREEN*) GetScreen() )->m_Active_Layer )
{ {

View File

@ -10,6 +10,7 @@
#include "gestfich.h" #include "gestfich.h"
#include "gerbview.h" #include "gerbview.h"
#include "wxGerberFrame.h"
#include "pcbplot.h" #include "pcbplot.h"
#include "bitmaps.h" #include "bitmaps.h"
#include "protos.h" #include "protos.h"

View File

@ -441,5 +441,6 @@ extern GERBER* g_GERBER_List[32];
extern int g_DisplayPolygonsModeSketch; extern int g_DisplayPolygonsModeSketch;
#include "pcbcommon.h" #include "pcbcommon.h"
#include "wxGerberFrame.h"
#endif // ifndef GERBVIEW_H #endif // ifndef GERBVIEW_H

View File

@ -3,11 +3,8 @@
/***************/ /***************/
#include "fctsys.h" #include "fctsys.h"
#include "gr_basic.h"
#include "common.h" #include "common.h"
#include "pcbnew.h" #include "gerbview.h"
#include "id.h" #include "id.h"
#include "hotkeys.h" #include "hotkeys.h"

View File

@ -43,12 +43,6 @@ bool WinEDA_GerberFrame::Clear_Pcb( bool query )
GetBoard()->m_Zone.DeleteAll(); GetBoard()->m_Zone.DeleteAll();
for( ; g_UnDeleteStackPtr != 0; )
{
g_UnDeleteStackPtr--;
delete g_UnDeleteStack[ g_UnDeleteStackPtr];
}
/* init pointeurs et variables */ /* init pointeurs et variables */
for( layer = 0; layer < 32; layer++ ) for( layer = 0; layer < 32; layer++ )
{ {

View File

@ -186,3 +186,13 @@ void WinEDA_GerberFrame::Trace_Gerber( wxDC* DC, int draw_mode, int printmasklay
GetScreen()->ClrRefreshReq(); GetScreen()->ClrRefreshReq();
} }
/* Virtual fonction needed by the PCB_SCREEN class derived from BASE_SCREEN
* this is a virtaul pure function in BASE_SCREEN
* do nothing in gerbview
* could be removed later
*/
void PCB_SCREEN::ClearUndoORRedoList(UNDO_REDO_CONTAINER&, int )
{
}

146
gerbview/wxGerberFrame.h Normal file
View File

@ -0,0 +1,146 @@
/***********************************************************/
/* wxGerberStruct.h: */
/***********************************************************/
#ifndef WX_GERBER_STRUCT_H
#define WX_GERBER_STRUCT_H
/******************************************************************
class WinEDA_GerberFrame: this is the main window used in gerbview
******************************************************************/
class WinEDA_GerberFrame : public WinEDA_BasePcbFrame
{
public:
WinEDAChoiceBox* m_SelLayerBox;
WinEDAChoiceBox* m_SelLayerTool;
public:
WinEDA_GerberFrame( wxWindow* father, const wxString& title,
const wxPoint& pos, const wxSize& size,
long style = KICAD_DEFAULT_DRAWFRAME_STYLE );
~WinEDA_GerberFrame();
void Update_config();
void OnCloseWindow( wxCloseEvent& Event );
void Process_Special_Functions( wxCommandEvent& event );
void RedrawActiveWindow( wxDC* DC, bool EraseBg );
void ReCreateHToolbar();
void ReCreateVToolbar();
void ReCreateOptToolbar();
void ReCreateMenuBar();
void OnLeftClick( wxDC* DC, const wxPoint& MousePos );
void OnLeftDClick( wxDC* DC, const wxPoint& MousePos );
bool OnRightClick( const wxPoint& MousePos, wxMenu* PopMenu );
int BestZoom(); // Retourne le meilleur zoom
void OnSelectOptionToolbar( wxCommandEvent& event );
void OnHotKey( wxDC* DC, int hotkey, EDA_BaseStruct* DrawStruct );
BOARD_ITEM* GerberGeneralLocateAndDisplay();
BOARD_ITEM* Locate( int typeloc );
void SetToolbars();
void Process_Settings( wxCommandEvent& event );
void Process_Config( wxCommandEvent& event );
void InstallConfigFrame( const wxPoint& pos );
void InstallPcbOptionsFrame( const wxPoint& pos, int id );
void InstallPcbGlobalDeleteFrame( const wxPoint& pos );
/* handlers for block commands */
int ReturnBlockCommand( int key );
virtual void HandleBlockPlace( wxDC* DC );
virtual int HandleBlockEnd( wxDC* DC );
void InstallDrillFrame( wxCommandEvent& event );
void ToPostProcess( wxCommandEvent& event );
void Genere_HPGL( const wxString& FullFileName, int Layers );
void Genere_GERBER( const wxString& FullFileName, int Layers );
void Genere_PS( const wxString& FullFileName, int Layers );
void Plot_Layer_HPGL( FILE* File, int masque_layer,
int garde, bool trace_via, GRTraceMode trace_mode );
void Plot_Layer_GERBER( FILE* File, int masque_layer,
int garde, bool trace_via, GRTraceMode trace_mode );
int Gen_D_CODE_File( const wxString& Name_File );
void Plot_Layer_PS( FILE* File, int masque_layer,
int garde, bool trace_via, GRTraceMode trace_mode );
void Files_io( wxCommandEvent& event );
void OnFileHistory( wxCommandEvent& event );
bool LoadOneGerberFile( const wxString& FileName, wxDC* DC, int mode );
int ReadGerberFile( wxDC* DC, FILE* File, bool Append );
bool Read_GERBER_File( wxDC* DC,
const wxString& GERBER_FullFileName,
const wxString& D_Code_FullFileName );
bool SaveGerberFile( const wxString& FileName, wxDC* DC );
void GeneralControle( wxDC* DC, wxPoint Mouse );
/**
* Function Read_D_Code_File
* reads in a dcode file assuming ALSPCB file format with ';' indicating comments.
* <p>
* Format is like CSV but with optional ';' delineated comments:<br>
* tool, Horiz, Vert, drill, vitesse, acc. ,Type ; [DCODE (commentaire)]<br>
* ex: 1, 12, 12, 0, 0, 0, 3 ; D10
* <p>
* Format:<br>
* Ver, Hor, Type, Tool [,Drill]<br>
* example: 0.012, 0.012, L , D10<br>
*
* Categorize all found dcodes into a table of D_CODE instantiations.
* @param D_CodeFullFileName The name of the file to read from.
* @return int - <br>
* -1 = file not found<br>
* -2 = parsing problem<br>
* 0 = the \a D_Code_FullFileName is empty, no reading is done but an empty GERBER is put into g_GERBER_List[]<br>
* 1 = read OK<br>
*/
int Read_D_Code_File( const wxString& D_Code_FullFileName );
void CopyDCodesSizeToItems();
void Liste_D_Codes( wxDC* DC );
/* Fonctions specifiques */
void Trace_Gerber( wxDC* DC, int draw_mode, int printmasklayer );
// Copper texts
void Rotate_Texte_Pcb( TEXTE_PCB* TextePcb, wxDC* DC );
TEXTE_PCB* Create_Texte_Pcb( wxDC* DC );
void Delete_Texte_Pcb( TEXTE_PCB* TextePcb, wxDC* DC );
void StartMoveTextePcb( TEXTE_PCB* TextePcb, wxDC* DC );
void Place_Texte_Pcb( TEXTE_PCB* TextePcb, wxDC* DC );
// PCB handling
bool Clear_Pcb( bool query );
void Erase_Current_Layer( bool query );
void Erase_Zones( bool query );
void Erase_Segments_Pcb( bool is_edges, bool query );
void Erase_Pistes( int masque_type, bool query );
void Erase_Textes_Pcb( bool query );
void Delete_DCode_Items( wxDC* DC, int dcode_value, int layer_number );
TRACK* Begin_Route( TRACK* track, wxDC* DC );
void End_Route( TRACK* track, wxDC* DC );
TRACK* Delete_Segment( wxDC* DC, TRACK* Track );
int Edit_TrackSegm_Width( wxDC* DC, TRACK* segm );
// Conversion function
void ExportDataInPcbnewFormat( wxCommandEvent& event );
/* SaveCopyInUndoList() virtual
* currently: do nothing in gerbview.
* but but be defined because it is a pure virtual in WinEDA_BasePcbFrame
*/
virtual void SaveCopyInUndoList( BOARD_ITEM* aItemToCopy,
UndoRedoOpType aTypeCommand = UR_UNSPECIFIED,
const wxPoint& aTransformPoint = wxPoint(0,0) )
{
}
DECLARE_EVENT_TABLE()
};
#endif /* WX_GERBER_STRUCT_H */

View File

@ -134,10 +134,49 @@ public:
wxPoint CursorRealPosition( const wxPoint& ScreenPos ); wxPoint CursorRealPosition( const wxPoint& ScreenPos );
/* general Undo/Redo command control */ /* general Undo/Redo command control */
/** function ClearUndoORRedoList (virtual).
* this function must remove the aItemCount old commands from aList
* and delete commmands, pickers and picked items if needed
* Because picked items must be deleted only if they are not in use, this is a virtual pure
* function that must be created for SCH_SCREEN and PCB_SCREEN
* @param aList = the UNDO_REDO_CONTAINER of commands
* @param aItemCount = number of old commands to delete. -1 to remove all old commands
* this will empty the list of commands.
* Commands are deleted from the older to the last.
*/
virtual void ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount = -1) = 0;
/** Function ClearUndoRedoList
* clear undo and redo list, using ClearUndoORRedoList()
* picked items are deleted by ClearUndoORRedoList() according to their status
*/
virtual void ClearUndoRedoList(); virtual void ClearUndoRedoList();
/** function PushCommandToUndoList
* add a command to undo in undo list
* delete the very old commands when the max count of undo commands is reached
* ( using ClearUndoORRedoList)
*/
virtual void PushCommandToUndoList( PICKED_ITEMS_LIST* aItem ); virtual void PushCommandToUndoList( PICKED_ITEMS_LIST* aItem );
/** function PushCommandToRedoList
* add a command to redo in redo list
* delete the very old commands when the max count of redo commands is reached
* ( using ClearUndoORRedoList)
*/
virtual void PushCommandToRedoList( PICKED_ITEMS_LIST* aItem ); virtual void PushCommandToRedoList( PICKED_ITEMS_LIST* aItem );
/** PopCommandFromUndoList
* return the last command to undo and remove it from list
* nothing is deleted.
*/
virtual PICKED_ITEMS_LIST* PopCommandFromUndoList(); virtual PICKED_ITEMS_LIST* PopCommandFromUndoList();
/** PopCommandFromRedoList
* return the last command to undo and remove it from list
* nothing is deleted.
*/
virtual PICKED_ITEMS_LIST* PopCommandFromRedoList(); virtual PICKED_ITEMS_LIST* PopCommandFromRedoList();
int GetUndoCommandCount() int GetUndoCommandCount()

View File

@ -56,21 +56,20 @@ public:
SCH_ITEM* ExtractWires( bool CreateCopy ); SCH_ITEM* ExtractWires( bool CreateCopy );
/* full undo redo management : */ /* full undo redo management : */
virtual void ClearUndoRedoList(); // use BASE_SCREEN::PushCommandToUndoList( PICKED_ITEMS_LIST* aItem )
virtual void PushCommandToUndoList( PICKED_ITEMS_LIST* aItem ); // use BASE_SCREEN::PushCommandToRedoList( PICKED_ITEMS_LIST* aItem )
virtual void PushCommandToRedoList( PICKED_ITEMS_LIST* aItem );
/** Function ClearUndoORRedoList /** Function ClearUndoORRedoList
* free the undo or redo list from List element * free the undo or redo list from List element
* Wrappers are deleted. * Wrappers are deleted.
* datas pointed by wrappers are deleted if not flagged IS_NEW * datas pointed by wrappers are deleted if not in use in schematic
* because they are copy of used data or they are not in use (DELETED) * i.e. when they are copy of a schematic item or they are no more in use (DELETED)
* @param aList = the UNDO_REDO_CONTAINER to clear * @param aList = the UNDO_REDO_CONTAINER to clear
* @param aItemCount = the count of items to remove. < 0 for all items * @param aItemCount = the count of items to remove. < 0 for all items
* items are removed from the beginning of the list. * items are removed from the beginning of the list.
* So this function can be called to remove old commands * So this function can be called to remove old commands
*/ */
void ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount = -1 ); virtual void ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount = -1 );
/** /**
* Function Save * Function Save

View File

@ -137,10 +137,8 @@ enum main_id {
// ID du Main Toolbar de Schematique // ID du Main Toolbar de Schematique
ID_SCHEMATIC_MAIN_TOOLBAR_START,
ID_SCHEMATIC_UNDO, ID_SCHEMATIC_UNDO,
ID_SCHEMATIC_REDO, ID_SCHEMATIC_REDO,
ID_SCHEMATIC_MAIN_TOOLBAR_END,
// ID du Vertical Toolbar de Schematique // ID du Vertical Toolbar de Schematique
ID_SCHEMATIC_VERTICAL_TOOLBAR_START, ID_SCHEMATIC_VERTICAL_TOOLBAR_START,
@ -155,7 +153,7 @@ enum main_id {
ID_LABEL_BUTT, ID_LABEL_BUTT,
ID_GLABEL_BUTT, ID_GLABEL_BUTT,
ID_HIERLABEL_BUTT, ID_HIERLABEL_BUTT,
ID_IMPORT_GLABEL_BUTT, ID_IMPORT_HLABEL_BUTT,
ID_SHEET_LABEL_BUTT, ID_SHEET_LABEL_BUTT,
ID_NOCONN_BUTT, ID_NOCONN_BUTT,
ID_JUNCTION_BUTT, ID_JUNCTION_BUTT,

View File

@ -5,7 +5,6 @@
#include "pcbstruct.h" #include "pcbstruct.h"
#include "dlist.h" #include "dlist.h"
#define UNDELETE_STACK_SIZE 10
#define L_MIN_DESSIN 1 /* Min width segments to allow draws with tickness */ #define L_MIN_DESSIN 1 /* Min width segments to allow draws with tickness */
class DPAD; class DPAD;
@ -23,8 +22,6 @@ extern int g_TabAllCopperLayerMask[NB_COPPER_LAYERS];
extern wxArrayString g_LibName_List; // library list to load extern wxArrayString g_LibName_List; // library list to load
extern BOARD_ITEM* g_UnDeleteStack[UNDELETE_STACK_SIZE];
extern int g_UnDeleteStackPtr;
extern DISPLAY_OPTIONS DisplayOpt; extern DISPLAY_OPTIONS DisplayOpt;
extern wxString PcbExtBuffer; extern wxString PcbExtBuffer;

View File

@ -127,9 +127,6 @@ class NETINFO_ITEM;
class MARKER; class MARKER;
class RATSNEST_ITEM; class RATSNEST_ITEM;
//class Ki_PageDescr;
//class DrawBlockStruct;
/* main window classes : */ /* main window classes : */
#include "wxPcbStruct.h" #include "wxPcbStruct.h"
@ -204,48 +201,7 @@ enum DisplayViaMode {
}; };
/* Handle info to display a board */ /* Handle info to display a board */
class PCB_SCREEN : public BASE_SCREEN #include "class_pcb_screen.h"
{
public:
int m_Active_Layer; /* ref couche active */
int m_Route_Layer_TOP; /* ref couches actives */
int m_Route_Layer_BOTTOM; /* pour placement vias et routage 2 couches */
public:
PCB_SCREEN();
~PCB_SCREEN();
PCB_SCREEN* Next() { return (PCB_SCREEN*) Pnext; }
void Init();
void SetNextZoom();
void SetPreviousZoom();
void SetLastZoom();
virtual int GetInternalUnits( void );
/**
* Function GetCurItem
* returns the currently selected BOARD_ITEM, overriding BASE_SCREEN::GetCurItem().
* @return BOARD_ITEM* - the one selected, or NULL.
*/
BOARD_ITEM* GetCurItem() const { return (BOARD_ITEM*) BASE_SCREEN::GetCurItem(); }
/**
* Function SetCurItem
* sets the currently selected object, m_CurrentItem.
* @param aItem Any object derived from BOARD_ITEM
*/
void SetCurItem( BOARD_ITEM* aItem ) { BASE_SCREEN::SetCurItem( aItem ); }
/* Return true if a microvia can be put on board
* A microvia ia a small via restricted to 2 near neighbour layers
* because its is hole is made by laser which can penetrate only one layer
* It is mainly used to connect BGA to the first inner layer
* And it is allowed from an external layer to the first inner layer
*/
bool IsMicroViaAcceptable( void );
};
/**********************************/ /**********************************/
/* Module (Footprint) description */ /* Module (Footprint) description */

View File

@ -392,8 +392,8 @@ public:
private: private:
void PutDataInPreviousState( PICKED_ITEMS_LIST* aList ); void PutDataInPreviousState( PICKED_ITEMS_LIST* aList );
bool GetSchematicFromRedoList(); void GetSchematicFromRedoList(wxCommandEvent& event);
bool GetSchematicFromUndoList(); void GetSchematicFromUndoList(wxCommandEvent& event);
public: public:
@ -502,8 +502,8 @@ public:
void InstallFieldsEditorDialog( void ); void InstallFieldsEditorDialog( void );
private: private:
bool GetComponentFromUndoList(); void GetComponentFromUndoList(wxCommandEvent& event);
bool GetComponentFromRedoList(); void GetComponentFromRedoList(wxCommandEvent& event);
// Edition des Pins: // Edition des Pins:
void CreatePin( wxDC* DC ); void CreatePin( wxDC* DC );

View File

@ -19,9 +19,7 @@
/* Forward declarations of classes. */ /* Forward declarations of classes. */
class PCB_SCREEN; class PCB_SCREEN;
class WinEDA_GerberFrame; // GERBER viewer main frame
class WinEDA_Toolbar; class WinEDA_Toolbar;
class WinEDA_CvpcbFrame;
class WinEDA_PcbFrame; class WinEDA_PcbFrame;
class WinEDA_ModuleEditFrame; class WinEDA_ModuleEditFrame;
class BOARD; class BOARD;
@ -111,14 +109,6 @@ public:
virtual void Show3D_Frame( wxCommandEvent& event ); virtual void Show3D_Frame( wxCommandEvent& event );
virtual void SaveCopyInUndoList( EDA_BaseStruct* ItemToCopy,
int flag_type_command = 0 );
private:
virtual void GetComponentFromUndoList();
virtual void GetComponentFromRedoList();
public: public:
// Read/write fonctions: // Read/write fonctions:
@ -133,9 +123,6 @@ public:
// PCB handling // PCB handling
bool Clear_Pcb( bool query ); bool Clear_Pcb( bool query );
void UnDeleteItem( wxDC* DC );
BOARD_ITEM* SaveItemEfface( BOARD_ITEM* aItem, int nbitems );
/** /**
* Function PcbGeneralLocateAndDisplay * Function PcbGeneralLocateAndDisplay
@ -312,6 +299,16 @@ public:
GRTraceMode trace_mode); GRTraceMode trace_mode);
void PlotDrillMark(Plotter *plotter, GRTraceMode trace_mode ); void PlotDrillMark(Plotter *plotter, GRTraceMode trace_mode );
/** Function SaveCopyInUndoList (virtual pure)
* Creates a new entry in undo list of commands.
* add a picker to handle aItemToCopy
* @param aItemToCopy = the board item modified by the command to undo
* @param aTypeCommand = command type (see enum UndoRedoOpType)
* @param aTransformPoint = the reference point of the transformation, for commands like move
*/
virtual void SaveCopyInUndoList( BOARD_ITEM* aItemToCopy, UndoRedoOpType aTypeCommand,
const wxPoint& aTransformPoint = wxPoint(0,0) ) = 0;
/* Block operations: */ /* Block operations: */
/** /**
* Function Block_Delete * Function Block_Delete
@ -459,6 +456,30 @@ public:
void OnSelectOptionToolbar( wxCommandEvent& event ); void OnSelectOptionToolbar( wxCommandEvent& event );
void ToolOnRightClick( wxCommandEvent& event ); void ToolOnRightClick( wxCommandEvent& event );
/** Function SaveCopyInUndoList.
* Creates a new entry in undo list of commands.
* add a picker to handle aItemToCopy
* @param aItemToCopy = the board item modified by the command to undo
* @param aTypeCommand = command type (see enum UndoRedoOpType)
* @param aTransformPoint = the reference point of the transformation, for commands like move
*/
void SaveCopyInUndoList( BOARD_ITEM* aItemToCopy, UndoRedoOpType aTypeCommand,
const wxPoint& aTransformPoint = wxPoint(0,0) );
/** Function SaveCopyInUndoList (overloaded).
* Creates a new entry in undo list of commands.
* add a list of pickers to handle a list of items
* @param aItemsList = the list of items modified by the command to undo
* @param aTypeCommand = command type (see enum UndoRedoOpType)
* @param aTransformPoint = the reference point of the transformation, for commands like move
*/
void SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList, UndoRedoOpType aTypeCommand,
const wxPoint& aTransformPoint = wxPoint(0,0) );
void PutDataInPreviousState( PICKED_ITEMS_LIST* aList );
void GetBoardFromRedoList(wxCommandEvent& event);
void GetBoardFromUndoList(wxCommandEvent& event);
/* Gestion generale des operations sur block */ /* Gestion generale des operations sur block */
int ReturnBlockCommand( int key ); int ReturnBlockCommand( int key );
void HandleBlockPlace( wxDC* DC ); void HandleBlockPlace( wxDC* DC );
@ -829,134 +850,6 @@ public:
}; };
/****************************************************/
/* class WinEDA_GerberFrame: public WinEDA_PcbFrame */
/****************************************************/
class WinEDA_GerberFrame : public WinEDA_BasePcbFrame
{
public:
WinEDAChoiceBox* m_SelLayerBox;
WinEDAChoiceBox* m_SelLayerTool;
public:
WinEDA_GerberFrame( wxWindow* father, const wxString& title,
const wxPoint& pos, const wxSize& size,
long style = KICAD_DEFAULT_DRAWFRAME_STYLE );
~WinEDA_GerberFrame();
void Update_config();
void OnCloseWindow( wxCloseEvent& Event );
void Process_Special_Functions( wxCommandEvent& event );
void RedrawActiveWindow( wxDC* DC, bool EraseBg );
void ReCreateHToolbar();
void ReCreateVToolbar();
void ReCreateOptToolbar();
void ReCreateMenuBar();
void OnLeftClick( wxDC* DC, const wxPoint& MousePos );
void OnLeftDClick( wxDC* DC, const wxPoint& MousePos );
bool OnRightClick( const wxPoint& MousePos, wxMenu* PopMenu );
int BestZoom(); // Retourne le meilleur zoom
void OnSelectOptionToolbar( wxCommandEvent& event );
void OnHotKey( wxDC* DC, int hotkey, EDA_BaseStruct* DrawStruct );
BOARD_ITEM* GerberGeneralLocateAndDisplay();
BOARD_ITEM* Locate( int typeloc );
void SetToolbars();
void Process_Settings( wxCommandEvent& event );
void Process_Config( wxCommandEvent& event );
void InstallConfigFrame( const wxPoint& pos );
void InstallPcbOptionsFrame( const wxPoint& pos, int id );
void InstallPcbGlobalDeleteFrame( const wxPoint& pos );
/* handlers for block commands */
int ReturnBlockCommand( int key );
virtual void HandleBlockPlace( wxDC* DC );
virtual int HandleBlockEnd( wxDC* DC );
void InstallDrillFrame( wxCommandEvent& event );
void ToPostProcess( wxCommandEvent& event );
void Genere_HPGL( const wxString& FullFileName, int Layers );
void Genere_GERBER( const wxString& FullFileName, int Layers );
void Genere_PS( const wxString& FullFileName, int Layers );
void Plot_Layer_HPGL( FILE* File, int masque_layer,
int garde, bool trace_via, GRTraceMode trace_mode );
void Plot_Layer_GERBER( FILE* File, int masque_layer,
int garde, bool trace_via, GRTraceMode trace_mode );
int Gen_D_CODE_File( const wxString& Name_File );
void Plot_Layer_PS( FILE* File, int masque_layer,
int garde, bool trace_via, GRTraceMode trace_mode );
void Files_io( wxCommandEvent& event );
void OnFileHistory( wxCommandEvent& event );
bool LoadOneGerberFile( const wxString& FileName, wxDC* DC, int mode );
int ReadGerberFile( wxDC* DC, FILE* File, bool Append );
bool Read_GERBER_File( wxDC* DC,
const wxString& GERBER_FullFileName,
const wxString& D_Code_FullFileName );
bool SaveGerberFile( const wxString& FileName, wxDC* DC );
void GeneralControle( wxDC* DC, wxPoint Mouse );
/**
* Function Read_D_Code_File
* reads in a dcode file assuming ALSPCB file format with ';' indicating comments.
* <p>
* Format is like CSV but with optional ';' delineated comments:<br>
* tool, Horiz, Vert, drill, vitesse, acc. ,Type ; [DCODE (commentaire)]<br>
* ex: 1, 12, 12, 0, 0, 0, 3 ; D10
* <p>
* Format:<br>
* Ver, Hor, Type, Tool [,Drill]<br>
* example: 0.012, 0.012, L , D10<br>
*
* Categorize all found dcodes into a table of D_CODE instantiations.
* @param D_CodeFullFileName The name of the file to read from.
* @return int - <br>
* -1 = file not found<br>
* -2 = parsing problem<br>
* 0 = the \a D_Code_FullFileName is empty, no reading is done but an empty GERBER is put into g_GERBER_List[]<br>
* 1 = read OK<br>
*/
int Read_D_Code_File( const wxString& D_Code_FullFileName );
void CopyDCodesSizeToItems();
void Liste_D_Codes( wxDC* DC );
/* Fonctions specifiques */
void Trace_Gerber( wxDC* DC, int draw_mode, int printmasklayer );
// Copper texts
void Rotate_Texte_Pcb( TEXTE_PCB* TextePcb, wxDC* DC );
TEXTE_PCB* Create_Texte_Pcb( wxDC* DC );
void Delete_Texte_Pcb( TEXTE_PCB* TextePcb, wxDC* DC );
void StartMoveTextePcb( TEXTE_PCB* TextePcb, wxDC* DC );
void Place_Texte_Pcb( TEXTE_PCB* TextePcb, wxDC* DC );
// PCB handling
bool Clear_Pcb( bool query );
void Erase_Current_Layer( bool query );
void Erase_Zones( bool query );
void Erase_Segments_Pcb( bool is_edges, bool query );
void Erase_Pistes( int masque_type, bool query );
void Erase_Textes_Pcb( bool query );
void Delete_DCode_Items( wxDC* DC, int dcode_value, int layer_number );
TRACK* Begin_Route( TRACK* track, wxDC* DC );
void End_Route( TRACK* track, wxDC* DC );
TRACK* Delete_Segment( wxDC* DC, TRACK* Track );
int Edit_TrackSegm_Width( wxDC* DC, TRACK* segm );
// Conversion function
void ExportDataInPcbnewFormat( wxCommandEvent& event );
DECLARE_EVENT_TABLE()
};
/*********************************************************/ /*********************************************************/
/* class WinEDA_ModuleEditFrame: public WinEDA_DrawFrame */ /* class WinEDA_ModuleEditFrame: public WinEDA_DrawFrame */
/* Class for the footprint editor */ /* Class for the footprint editor */
@ -1007,11 +900,12 @@ public:
/* Undo and redo functions */ /* Undo and redo functions */
public: public:
void SaveCopyInUndoList( EDA_BaseStruct* ItemToCopy, int flag_type_command = 0 ); virtual void SaveCopyInUndoList( BOARD_ITEM* ItemToCopy,
UndoRedoOpType aTypeCommand = UR_UNSPECIFIED,
const wxPoint& aTransformPoint = wxPoint(0,0) );
private: private:
void GetComponentFromUndoList(); void GetComponentFromUndoList(wxCommandEvent& event);
void GetComponentFromRedoList(); void GetComponentFromRedoList(wxCommandEvent& event);
public: public:

View File

@ -14,6 +14,7 @@ set(PCBNEW_SRCS
block.cpp block.cpp
block_module_editor.cpp block_module_editor.cpp
board.cpp board.cpp
board_undo_redo.cpp
build_BOM_from_board.cpp build_BOM_from_board.cpp
# class_board_item.cpp # class_board_item.cpp
# class_drawsegment.cpp # class_drawsegment.cpp
@ -141,7 +142,6 @@ set(PCBNEW_SRCS
track.cpp track.cpp
tr_modif.cpp tr_modif.cpp
trpiste.cpp trpiste.cpp
undelete.cpp
via_edit.cpp via_edit.cpp
work.cpp work.cpp
xchgmod.cpp xchgmod.cpp

View File

@ -164,21 +164,6 @@ void WinEDA_BasePcbFrame::Show3D_Frame( wxCommandEvent& event )
} }
void WinEDA_BasePcbFrame::SaveCopyInUndoList( EDA_BaseStruct* ItemToCopy,
int flag )
{
}
void WinEDA_BasePcbFrame::GetComponentFromUndoList( void )
{
}
void WinEDA_BasePcbFrame::GetComponentFromRedoList( void )
{
}
/****************************************************************/ /****************************************************************/
void WinEDA_BasePcbFrame::SwitchLayer( wxDC* DC, int layer ) void WinEDA_BasePcbFrame::SwitchLayer( wxDC* DC, int layer )

434
pcbnew/board_undo_redo.cpp Normal file
View File

@ -0,0 +1,434 @@
/*************************************************************/
/* board editor: undo and redo functions for board editor */
/*************************************************************/
#include "fctsys.h"
#include "common.h"
#include "class_drawpanel.h"
#include "pcbnew.h"
/* Functions to undo and redo edit commands.
* commmands to undo are stored in CurrentScreen->m_UndoList
* commmands to redo are stored in CurrentScreen->m_RedoList
*
* m_UndoList and m_RedoList handle a std::vector of PICKED_ITEMS_LIST
* Each PICKED_ITEMS_LIST handle a std::vector of pickers (class ITEM_PICKER),
* that store the list of schematic items that are concerned by the command to undo or redo
* and is created for each command to undo (handle also a command to redo).
* each picker has a pointer pointing to an item to undo or redo (in fact: deleted, added or modified),
* and has a pointer to a copy of this item, when this item has been modified
* (the old values of parameters are therefore saved)
*
* there are 3 cases:
* - delete item(s) command
* - change item(s) command
* - add item(s) command
* and 3 cases for block:
* - move list of items
* - mirror (Y) list of items
* - Flip list of items
*
* Undo command
* - delete item(s) command:
* => deleted items are moved in undo list
*
* - change item(s) command
* => A copy of item(s) is made (a DrawPickedStruct list of wrappers)
* the .m_Link member of each wrapper points the modified item.
* the .m_Item member of each wrapper points the old copy of this item.
*
* - add item(s) command
* =>A list of item(s) is made. The .m_Item member of each wrapper points the new item.
*
* Redo command
* - delete item(s) old command:
* => deleted items are moved in EEDrawList list, and in
*
* - change item(s) command
* => the copy of item(s) is moved in Undo list
*
* - add item(s) command
* => The list of item(s) is used to create a deleted list in undo list(same as a delete command)
*
* Some block operations that change items can be undoed without memorise items, just the coordiantes of the transform:
* move list of items (undo/redo is made by moving with the opposite move vector)
* mirror (Y) and flip list of items (undo/redo is made by mirror or flip items)
* so they are handled specifically.
*
*/
/**************************************************************/
void SwapData( EDA_BaseStruct* aItem, EDA_BaseStruct* 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
*/
{
if( aItem == NULL || aImage == NULL )
{
wxMessageBox( wxT( "SwapData error: NULL pointer" ) );
return;
}
switch( aItem->Type() )
{
default:
wxMessageBox( wxT( "SwapData() error: unexpected type" ) );
break;
}
}
/************************************************************/
BOARD_ITEM* DuplicateStruct( BOARD_ITEM* aItem )
/************************************************************/
/* Routine to create a new copy of given struct.
* The new object is not put in list (not linked)
*/
{
BOARD_ITEM* newItem = NULL;
if( aItem == NULL )
{
wxMessageBox( wxT( "DuplicateStruct error: NULL struct" ) );
return NULL;
}
switch( aItem->Type() )
{
default:
{
wxString msg;
msg << wxT( "DuplicateStruct error: unexpected StructType " ) <<
aItem->Type() << wxT( " " ) << aItem->GetClass();
// wxMessageBox( msg );
}
break;
}
return newItem;
}
/***********************************************************************/
void WinEDA_PcbFrame::SaveCopyInUndoList( BOARD_ITEM* aItemToCopy,
UndoRedoOpType aCommandType,
const wxPoint& aTransformPoint )
/***********************************************************************/
/** function SaveCopyInUndoList
* Create a copy of the current schematic item, and put it in the undo list.
*
* flag_type_command =
* UR_CHANGED
* UR_NEW
* UR_DELETED
*
* 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.
* If it is only a copy, the EEDrawList and the subhierarchy must NOT be deleted.
*
* Note:
* Edit wires and busses is a bit complex.
* because when a new wire is added, modifications in wire list
* (wire concatenation) there are modified items, deleted items and new items
* so flag_type_command is UR_WIRE_IMAGE: the struct ItemToCopy is a list of wires
* saved in Undo List (for Undo or Redo commands, saved wires will be exchanged with current wire list
*/
{
BOARD_ITEM* CopyOfItem;
PICKED_ITEMS_LIST* commandToUndo = new PICKED_ITEMS_LIST();
commandToUndo->m_TransformPoint = aTransformPoint;
ITEM_PICKER itemWrapper( aItemToCopy, aCommandType );
switch( aCommandType )
{
case UR_CHANGED: /* Create a copy of schematic */
CopyOfItem = DuplicateStruct( aItemToCopy );
itemWrapper.m_Item = CopyOfItem;
itemWrapper.m_Link = aItemToCopy;
if( CopyOfItem )
commandToUndo->PushItem( itemWrapper );
break;
case UR_NEW:
case UR_WIRE_IMAGE:
case UR_DELETED:
commandToUndo->PushItem( itemWrapper );
break;
default:
{
wxString msg;
msg.Printf( wxT( "SaveCopyInUndoList() error (unknown code %X)" ), aCommandType );
wxMessageBox( msg );
}
break;
}
if( commandToUndo->GetCount() )
{
/* Save the copy in undo list */
GetScreen()->PushCommandToUndoList( commandToUndo );
/* Clear redo list, because after new save there is no redo to do */
GetScreen()->ClearUndoORRedoList( GetScreen()->m_RedoList );
}
else
delete commandToUndo;
}
/** function SaveCopyInUndoList
* @param aItemsList = a PICKED_ITEMS_LIST of items to save
* @param aTypeCommand = type of comand ( UR_CHANGED, UR_NEW, UR_DELETED ...
*/
void WinEDA_PcbFrame::SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList,
UndoRedoOpType aTypeCommand,
const wxPoint& aTransformPoint )
{
BOARD_ITEM* CopyOfItem;
PICKED_ITEMS_LIST* commandToUndo = new PICKED_ITEMS_LIST();
commandToUndo->m_TransformPoint = aTransformPoint;
ITEM_PICKER itemWrapper;
for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
{
BOARD_ITEM* ItemToCopy = (BOARD_ITEM*) aItemsList.GetItemData( ii );
UndoRedoOpType command = aItemsList.GetItemStatus( ii );
if( command == UR_UNSPECIFIED )
{
command = aTypeCommand;
}
wxASSERT( ItemToCopy );
itemWrapper.m_Item = ItemToCopy;
itemWrapper.m_UndoRedoStatus = command;
switch( command )
{
case UR_CHANGED: /* Create a copy of schematic */
CopyOfItem = DuplicateStruct( ItemToCopy );
itemWrapper.m_Item = CopyOfItem;
itemWrapper.m_Link = ItemToCopy;
if( CopyOfItem )
commandToUndo->PushItem( itemWrapper );
break;
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;
default:
{
wxString msg;
msg.Printf( wxT( "SaveCopyInUndoList() error (unknown code %X)" ), command );
wxMessageBox( msg );
}
break;
}
}
if( commandToUndo->GetCount() )
{
/* Save the copy in undo list */
GetScreen()->PushCommandToUndoList( commandToUndo );
/* Clear redo list, because after new save there is no redo to do */
GetScreen()->ClearUndoORRedoList( GetScreen()->m_RedoList );
}
else
delete commandToUndo;
}
/***************************************************************************/
void WinEDA_PcbFrame::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
/***************************************************************************/
/* Used in undo or redo command.
* Put data pointed by List in the previous state, i.e. the state memorised by List
*/
{
BOARD_ITEM* item;
bool as_moved = false;
for( unsigned ii = 0; ii < aList->GetCount(); ii++ )
{
ITEM_PICKER itemWrapper = aList->GetItemWrapper( ii );
item = (BOARD_ITEM*) itemWrapper.m_Item;
wxASSERT( item );
BOARD_ITEM* image = (BOARD_ITEM*) itemWrapper.m_Link;
switch( itemWrapper.m_UndoRedoStatus )
{
case UR_CHANGED: /* Exchange old and new data for each item */
SwapData( item, image );
break;
case UR_NEW: /* new items are deleted */
aList->SetItemStatus( 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 );
GetBoard()->Add( item );
item->m_Flags = 0;
break;
case UR_MOVED:
// item->Move( - aList->m_TransformPoint );
as_moved = true;
break;
case UR_MIRRORED_Y:
// item->Mirror_Y( aList->m_TransformPoint.x );
break;
default:
{
wxString msg;
msg.Printf( wxT(
"PutDataInPreviousState() error (unknown code %X)" ),
itemWrapper.m_UndoRedoStatus );
wxMessageBox( msg );
}
break;
}
}
// Undo for move transform needs to change the general move vector:
if( as_moved )
aList->m_TransformPoint = -aList->m_TransformPoint;
Compile_Ratsnest( NULL, true );
}
/**********************************************************/
void WinEDA_PcbFrame::GetBoardFromUndoList( wxCommandEvent& event )
/**********************************************************/
/** Function GetSchematicFromUndoList
* Undo the last edition:
* - Save the current schematic in Redo list
* - Get an old version of the schematic
* @return false if nothing done, else true
*/
{
if( GetScreen()->GetUndoCommandCount() <= 0 )
return;
/* Get the old wrapper and put it in RedoList */
PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromUndoList();
GetScreen()->PushCommandToRedoList( List );
/* Undo the command */
PutDataInPreviousState( List );
GetScreen()->SetModify();
ReCreateHToolbar();
SetToolbars();
DrawPanel->Refresh();
}
/**********************************************************/
void WinEDA_PcbFrame::GetBoardFromRedoList( wxCommandEvent& event )
/**********************************************************/
/* Redo the last edition:
* - Save the current schematic in undo list
* - Get the old version
* @return false if nothing done, else true
*/
{
if( GetScreen()->GetRedoCommandCount() == 0 )
return;
/* Get the old wrapper and put it in UndoList */
PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromRedoList();
GetScreen()->PushCommandToUndoList( List );
/* Redo the command: */
PutDataInPreviousState( List );
GetScreen()->SetModify();
ReCreateHToolbar();
SetToolbars();
DrawPanel->Refresh();
}
/***********************************************************************************/
void PCB_SCREEN::ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount )
/**********************************************************************************/
/** Function ClearUndoORRedoList
* free the undo or redo list from List element
* Wrappers are deleted.
* datas pointed by wrappers are deleted if not in use in schematic
* i.e. when they are copy of a schematic item or they are no more in use (DELETED)
* @param aList = the UNDO_REDO_CONTAINER to clear
* @param aItemCount = the count of items to remove. < 0 for all items
* items (commands stored in list) are removed from the beginning of the list.
* So this function can be called to remove old commands
*/
{
if( aItemCount == 0 )
return;
unsigned icnt = aList.m_CommandsList.size();
if( aItemCount > 0 )
icnt = aItemCount;
for( unsigned ii = 0; ii < icnt; ii++ )
{
if( aList.m_CommandsList.size() == 0 )
break;
PICKED_ITEMS_LIST* curr_cmd = aList.m_CommandsList[0];
aList.m_CommandsList.erase( aList.m_CommandsList.begin() );
// Delete items is they are not flagged UR_NEW, or if this is a block operation
while( 1 )
{
ITEM_PICKER wrapper = curr_cmd->PopItem();
EDA_BaseStruct* item = wrapper.m_Item;
if( item == NULL ) // No more item in list.
break;
switch( wrapper.m_UndoRedoStatus )
{
case UR_MOVED:
case UR_MIRRORED_X:
case UR_MIRRORED_Y:
case UR_ROTATED:
case UR_NEW: // Do nothing, items are in use, the picker is not owner of items
break;
default:
delete item; // the picker is owner of this item
break;
}
}
delete curr_cmd; // Delete command
}
}

View File

@ -49,6 +49,8 @@ BOARD::BOARD( EDA_BaseStruct* parent, WinEDA_BasePcbFrame* frame ) :
/***************/ /***************/
BOARD::~BOARD() BOARD::~BOARD()
{ {
m_PcbFrame->GetScreen()->ClearUndoRedoList();
while( m_ZoneDescriptorList.size() ) while( m_ZoneDescriptorList.size() )
{ {
ZONE_CONTAINER* area_to_remove = m_ZoneDescriptorList[0]; ZONE_CONTAINER* area_to_remove = m_ZoneDescriptorList[0];

View File

@ -81,6 +81,7 @@ PCB_SCREEN::PCB_SCREEN() : BASE_SCREEN( TYPE_SCREEN )
PCB_SCREEN::~PCB_SCREEN() PCB_SCREEN::~PCB_SCREEN()
/***************************/ /***************************/
{ {
ClearUndoRedoList();
} }

View File

@ -364,7 +364,9 @@ void WinEDA_PcbFrame::Delete_Cotation( COTATION* Cotation, wxDC* DC )
if( DC ) if( DC )
Cotation->Draw( DrawPanel, DC, GR_XOR ); Cotation->Draw( DrawPanel, DC, GR_XOR );
Cotation->DeleteStructure();
SaveCopyInUndoList(Cotation, UR_DELETED);
Cotation->UnLink();
GetScreen()->SetModify(); GetScreen()->SetModify();
} }

View File

@ -105,10 +105,13 @@ TRACK* WinEDA_PcbFrame::Delete_Segment( wxDC* DC, TRACK* aTrack )
current_net_code = aTrack->GetNet(); current_net_code = aTrack->GetNet();
DLIST<TRACK>* container = (DLIST<TRACK>*) aTrack->GetList();
wxASSERT( container );
container->Remove( aTrack );
// redraw the area where the track was // redraw the area where the track was
DrawPanel->PostDirtyRect( aTrack->GetBoundingBox() ); DrawPanel->PostDirtyRect( aTrack->GetBoundingBox() );
SaveItemEfface( aTrack, 1 ); SaveCopyInUndoList( aTrack, UR_DELETED );
GetScreen()->SetModify(); GetScreen()->SetModify();
test_1_net_connexion( DC, current_net_code ); test_1_net_connexion( DC, current_net_code );
@ -138,29 +141,37 @@ void WinEDA_PcbFrame::Delete_net( wxDC* DC, TRACK* aTrack )
if( aTrack == NULL ) if( aTrack == NULL )
return; return;
if( IsOK( this, _( "Delete NET ?" ) ) ) if( !IsOK( this, _( "Delete NET ?" ) ) )
return;
PICKED_ITEMS_LIST itemsList;
ITEM_PICKER picker(NULL,UR_DELETED);
int net_code_delete = aTrack->GetNet();
/* Search the first item for the given net code */
TRACK* trackList = GetBoard()->m_Track->GetStartNetCode( net_code_delete );
/* Remove all segments having the given net code */
int ii = 0;
TRACK * next_track;
for( TRACK* segm = trackList; segm; segm = next_track, ++ii )
{ {
int net_code_delete = aTrack->GetNet(); next_track = segm->Next();
if( segm->GetNet() != net_code_delete )
break;
/* Recherche du debut de la zone des pistes du net_code courant */ GetBoard()->m_Track.Remove( segm );
TRACK* trackList = GetBoard()->m_Track->GetStartNetCode( net_code_delete ); // redraw the area where the track was
DrawPanel->PostDirtyRect( segm->GetBoundingBox() );
/* Decompte du nombre de segments de la sous-chaine */ picker.m_Item = segm;
itemsList.PushItem(picker);
int ii = 0;
for( TRACK* segm = trackList; segm; segm = segm->Next(), ++ii )
{
if( segm->GetNet() != net_code_delete )
break;
DrawPanel->PostDirtyRect( segm->GetBoundingBox() );
}
SaveItemEfface( trackList, ii );
GetScreen()->SetModify();
test_1_net_connexion( DC, net_code_delete );
GetBoard()->DisplayInfo( this );
} }
SaveCopyInUndoList( itemsList, UR_DELETED );
GetScreen()->SetModify();
test_1_net_connexion( DC, net_code_delete );
GetBoard()->DisplayInfo( this );
} }
@ -173,29 +184,39 @@ void WinEDA_PcbFrame::Remove_One_Track( wxDC* DC, TRACK* pt_segm )
* jusqu'a un pad ou un point de jonction de plus de 2 segments * jusqu'a un pad ou un point de jonction de plus de 2 segments
*/ */
{ {
int nb_segm; int segments_to_delete_count;
if( pt_segm == NULL ) if( pt_segm == NULL )
return; return;
TRACK* trackList = Marque_Une_Piste( this, DC, pt_segm, &nb_segm, 0 ); TRACK* trackList = Marque_Une_Piste( this, DC, pt_segm, &segments_to_delete_count, 0 );
if( segments_to_delete_count == 0 )
return;
int net_code = pt_segm->GetNet(); int net_code = pt_segm->GetNet();
if( nb_segm ) /* Il y a nb_segm segments de piste a effacer */ PICKED_ITEMS_LIST itemsList;
ITEM_PICKER picker(NULL,UR_DELETED);
int ii = 0;
TRACK* tracksegment = trackList;
TRACK * next_track;
for( ; ii < segments_to_delete_count; ii++, tracksegment = next_track )
{ {
int ii = 0; next_track = tracksegment->Next();
for( TRACK* t = trackList; ii<nb_segm; ii++, t = t->Next() ) tracksegment->SetState( BUSY, OFF );
{
t->SetState( BUSY, OFF );
D(printf("%s: track %p status=\"%s\"\n", __func__, t, D(printf("%s: track %p status=\"%s\"\n", __func__, tracksegment,
CONV_TO_UTF8( TRACK::ShowState( t->GetState(-1)) ) CONV_TO_UTF8( TRACK::ShowState( tracksegment->GetState(-1)) )
);) );)
DrawPanel->PostDirtyRect( t->GetBoundingBox() ); GetBoard()->m_Track.Remove( tracksegment );
} // redraw the area where the track was
DrawPanel->PostDirtyRect( tracksegment->GetBoundingBox() );
SaveItemEfface( trackList, nb_segm ); picker.m_Item = tracksegment;
if ( net_code > 0 ) itemsList.PushItem(picker);
test_1_net_connexion( DC, net_code );
} }
SaveCopyInUndoList( itemsList, UR_DELETED );
if ( net_code > 0 )
test_1_net_connexion( DC, net_code );
} }

View File

@ -143,7 +143,8 @@ void DialogEditModuleText::OnOkClick( wxCommandEvent& event )
{ {
wxString msg; wxString msg;
m_Parent->SaveCopyInUndoList( m_Parent->GetBoard()->m_Modules ); if ( m_Module)
m_Parent->SaveCopyInUndoList( m_Module, UR_CHANGED );
if( m_DC ) //Erase old text on screen if( m_DC ) //Erase old text on screen
{ {
m_CurrentTextMod->Draw( m_Parent->DrawPanel, m_DC, GR_XOR, m_CurrentTextMod->Draw( m_Parent->DrawPanel, m_DC, GR_XOR,

View File

@ -475,7 +475,7 @@ void DialogPadProperties::PadPropertiesAccept( wxCommandEvent& event )
if( m_CurrentPad ) // Set Pad Name & Num if( m_CurrentPad ) // Set Pad Name & Num
{ {
m_Parent->SaveCopyInUndoList( m_Parent->GetBoard()->m_Modules ); m_Parent->SaveCopyInUndoList( m_Parent->GetBoard()->m_Modules, UR_CHANGED );
MODULE* Module = (MODULE*) m_CurrentPad->GetParent(); MODULE* Module = (MODULE*) m_CurrentPad->GetParent();
Module->m_LastEdit_Time = time( NULL ); Module->m_LastEdit_Time = time( NULL );

View File

@ -332,10 +332,6 @@ void WinEDA_PcbFrame::Process_Special_Functions( wxCommandEvent& event )
HandleBlockEnd( &dc ); HandleBlockEnd( &dc );
break; break;
case ID_UNDO_BUTT:
UnDeleteItem( &dc );
break;
case ID_DRC_CONTROL: case ID_DRC_CONTROL:
Install_Test_DRC_Frame( &dc ); Install_Test_DRC_Frame( &dc );
break; break;
@ -1269,7 +1265,7 @@ void WinEDA_PcbFrame::RemoveStruct( BOARD_ITEM* Item, wxDC* DC )
SetCurItem( NULL ); SetCurItem( NULL );
( (MARKER*) Item )->Draw( DrawPanel, DC, GR_XOR ); ( (MARKER*) Item )->Draw( DrawPanel, DC, GR_XOR );
// delete the marker, and free memory. Don't use undelete stack. // delete the marker, and free memory. Don't use undo stack.
GetBoard()->Delete( Item ); GetBoard()->Delete( Item );
break; break;

View File

@ -116,8 +116,8 @@ void WinEDA_PcbFrame::Delete_Texte_Pcb( TEXTE_PCB* TextePcb, wxDC* DC )
TextePcb->Draw( DrawPanel, DC, GR_XOR ); TextePcb->Draw( DrawPanel, DC, GR_XOR );
/* Suppression du texte en Memoire*/ SaveCopyInUndoList(TextePcb, UR_DELETED);
TextePcb ->DeleteStructure(); TextePcb ->UnLink();
DrawPanel->ManageCurseur = NULL; DrawPanel->ManageCurseur = NULL;
DrawPanel->ForceCloseManageCurseur = NULL; DrawPanel->ForceCloseManageCurseur = NULL;
SetCurItem( NULL ); SetCurItem( NULL );

View File

@ -120,7 +120,8 @@ void WinEDA_PcbFrame::Delete_Segment_Edge( DRAWSEGMENT* Segment, wxDC* DC )
{ {
Segment->Draw( DrawPanel, DC, GR_XOR ); Segment->Draw( DrawPanel, DC, GR_XOR );
Segment->m_Flags = 0; Segment->m_Flags = 0;
Segment ->DeleteStructure(); SaveCopyInUndoList(Segment, UR_DELETED);
Segment->UnLink();
SetCurItem( NULL ); SetCurItem( NULL );
GetScreen()->SetModify(); GetScreen()->SetModify();
} }

View File

@ -139,13 +139,6 @@ bool WinEDA_BasePcbFrame::Clear_Pcb( bool query )
// layer names are put into the BOARD. // layer names are put into the BOARD.
SetBoard( new BOARD( NULL, this ) ); SetBoard( new BOARD( NULL, this ) );
while( g_UnDeleteStackPtr > 0 )
{
g_UnDeleteStackPtr--;
delete g_UnDeleteStack[g_UnDeleteStackPtr];
}
/* init pointeurs et variables */ /* init pointeurs et variables */
GetScreen()->m_FileName.Empty(); GetScreen()->m_FileName.Empty();

View File

@ -161,7 +161,8 @@ void WinEDA_PcbFrame::Delete_Mire( MIREPCB* MirePcb, wxDC* DC )
return; return;
MirePcb->Draw( DrawPanel, DC, GR_XOR ); MirePcb->Draw( DrawPanel, DC, GR_XOR );
MirePcb->DeleteStructure(); SaveCopyInUndoList(MirePcb, UR_DELETED);
MirePcb->UnLink();
} }

View File

@ -622,16 +622,6 @@ void WinEDA_ModuleEditFrame::Process_Special_Functions( wxCommandEvent& event )
InstallGridFrame( pos ); InstallGridFrame( pos );
break; break;
case ID_MODEDIT_UNDO:
GetComponentFromUndoList();
redraw = true;
break;
case ID_MODEDIT_REDO:
GetComponentFromRedoList();
redraw = true;
break;
case ID_POPUP_PLACE_BLOCK: case ID_POPUP_PLACE_BLOCK:
GetScreen()->m_BlockLocate.m_Command = BLOCK_MOVE; GetScreen()->m_BlockLocate.m_Command = BLOCK_MOVE;
DrawPanel->m_AutoPAN_Request = FALSE; DrawPanel->m_AutoPAN_Request = FALSE;
@ -705,10 +695,10 @@ void WinEDA_ModuleEditFrame::Process_Special_Functions( wxCommandEvent& event )
void WinEDA_ModuleEditFrame::Transform( MODULE* module, int transform ) void WinEDA_ModuleEditFrame::Transform( MODULE* module, int transform )
/******************************************************************************/ /******************************************************************************/
/* Execute les transformations de la repr<70>sentation des modules. /* Execute a geometric transform on the current footprint.
* le module, apres transformation est toujours en position de reference: * The footprint, after transform is always in reference position and orientation:
* position 0,0 * position 0,0
* orientation 0, cot<EFBFBD> composant. * orientation 0, component side.
*/ */
{ {
D_PAD* pad = module->m_Pads; D_PAD* pad = module->m_Pads;

View File

@ -3,7 +3,7 @@
/********************************************/ /********************************************/
#include "fctsys.h" #include "fctsys.h"
#include "gr_basic.h" #include "class_drawpanel.h"
#include "common.h" #include "common.h"
#include "pcbnew.h" #include "pcbnew.h"
@ -13,8 +13,9 @@
/**************************************************************************/ /**************************************************************************/
void WinEDA_ModuleEditFrame::SaveCopyInUndoList( EDA_BaseStruct* ItemToCopy, void WinEDA_ModuleEditFrame::SaveCopyInUndoList( BOARD_ITEM* ItemToCopy,
int unused_flag ) UndoRedoOpType aTypeCommand,
const wxPoint& aTransformPoint )
/************************************************************************/ /************************************************************************/
{ {
EDA_BaseStruct* item; EDA_BaseStruct* item;
@ -50,7 +51,7 @@ void WinEDA_ModuleEditFrame::SaveCopyInUndoList( EDA_BaseStruct* ItemToCopy,
/*********************************************************/ /*********************************************************/
void WinEDA_ModuleEditFrame::GetComponentFromRedoList() void WinEDA_ModuleEditFrame::GetComponentFromRedoList(wxCommandEvent& event)
/*********************************************************/ /*********************************************************/
/* Redo the last edition: /* Redo the last edition:
@ -76,12 +77,13 @@ void WinEDA_ModuleEditFrame::GetComponentFromRedoList()
GetScreen()->SetModify(); GetScreen()->SetModify();
ReCreateHToolbar(); ReCreateHToolbar();
SetToolbars(); SetToolbars();
DrawPanel->Refresh();
} }
/*********************************************************/ /***************************************************************************/
void WinEDA_ModuleEditFrame::GetComponentFromUndoList() void WinEDA_ModuleEditFrame::GetComponentFromUndoList(wxCommandEvent& event)
/*********************************************************/ /***************************************************************************/
/* Undo the last edition: /* Undo the last edition:
* - Place the current edited library component in Redo list * - Place the current edited library component in Redo list
@ -108,4 +110,5 @@ void WinEDA_ModuleEditFrame::GetComponentFromUndoList()
SetCurItem( NULL );; SetCurItem( NULL );;
ReCreateHToolbar(); ReCreateHToolbar();
SetToolbars(); SetToolbars();
DrawPanel->Refresh();
} }

View File

@ -70,9 +70,9 @@ BEGIN_EVENT_TABLE( WinEDA_ModuleEditFrame, WinEDA_BasePcbFrame )
EVT_TOOL( ID_MODEDIT_EDIT_MODULE_PROPERTIES, EVT_TOOL( ID_MODEDIT_EDIT_MODULE_PROPERTIES,
WinEDA_ModuleEditFrame::Process_Special_Functions ) WinEDA_ModuleEditFrame::Process_Special_Functions )
EVT_TOOL( ID_MODEDIT_UNDO, EVT_TOOL( ID_MODEDIT_UNDO,
WinEDA_ModuleEditFrame::Process_Special_Functions ) WinEDA_ModuleEditFrame::GetComponentFromUndoList )
EVT_TOOL( ID_MODEDIT_REDO, EVT_TOOL( ID_MODEDIT_REDO,
WinEDA_ModuleEditFrame::Process_Special_Functions ) WinEDA_ModuleEditFrame::GetComponentFromRedoList )
// Vertical toolbar (left click): // Vertical toolbar (left click):
EVT_TOOL( ID_NO_SELECT_BUTT, EVT_TOOL( ID_NO_SELECT_BUTT,

View File

@ -320,10 +320,12 @@ bool WinEDA_PcbFrame::Delete_Module( MODULE* module, wxDC* DC, bool aAskBeforeDe
if( g_Show_Ratsnest ) if( g_Show_Ratsnest )
DrawGeneralRatsnest( DC ); DrawGeneralRatsnest( DC );
/* Sauvegarde en buffer des undelete */ /* Remove module from list, and put it in undo command list */
SaveItemEfface( module, 1 ); m_Pcb->m_Modules.Remove( module );
module->SetState( DELETED, ON );
SaveCopyInUndoList( module, UR_DELETED );
Compile_Ratsnest( DC, true ); Compile_Ratsnest( DC, true );
// redraw the area where the module was // redraw the area where the module was
if( DC ) if( DC )
@ -790,7 +792,7 @@ void DrawModuleOutlines( WinEDA_DrawPanel* panel, wxDC* DC, MODULE* module )
#ifndef __WXMAC__ #ifndef __WXMAC__
DisplayOpt.DisplayPadFill = true; /* Trace en SKETCH en deplacement */ DisplayOpt.DisplayPadFill = true; /* Trace en SKETCH en deplacement */
#else #else
DisplayOpt.DisplayPadFill = false; DisplayOpt.DisplayPadFill = false;
#endif #endif
pt_pad = module->m_Pads; pt_pad = module->m_Pads;
for( ; pt_pad != NULL; pt_pad = pt_pad->Next() ) for( ; pt_pad != NULL; pt_pad = pt_pad->Next() )

View File

@ -322,7 +322,8 @@ void WinEDA_BasePcbFrame::PlacePad( D_PAD* Pad, wxDC* DC )
Pad->Draw( DrawPanel, DC, GR_XOR ); Pad->Draw( DrawPanel, DC, GR_XOR );
/* Save old module */ /* Save old module */
Pad->m_Pos = Pad_OldPos; SaveCopyInUndoList( m_Pcb->m_Modules ); Pad->m_Pos = Pad_OldPos;
SaveCopyInUndoList( Module, UR_CHANGED );
Pad->m_Pos = GetScreen()->m_Curseur; Pad->m_Pos = GetScreen()->m_Curseur;
/* Compute local coordinates (i.e refer to Module position and for Module orient = 0)*/ /* Compute local coordinates (i.e refer to Module position and for Module orient = 0)*/

View File

@ -127,7 +127,8 @@ BEGIN_EVENT_TABLE( WinEDA_PcbFrame, WinEDA_BasePcbFrame )
EVT_TOOL( wxID_CUT, WinEDA_PcbFrame::Process_Special_Functions ) EVT_TOOL( wxID_CUT, WinEDA_PcbFrame::Process_Special_Functions )
EVT_TOOL( wxID_COPY, WinEDA_PcbFrame::Process_Special_Functions ) EVT_TOOL( wxID_COPY, WinEDA_PcbFrame::Process_Special_Functions )
EVT_TOOL( wxID_PASTE, WinEDA_PcbFrame::Process_Special_Functions ) EVT_TOOL( wxID_PASTE, WinEDA_PcbFrame::Process_Special_Functions )
EVT_TOOL( ID_UNDO_BUTT, WinEDA_PcbFrame::Process_Special_Functions ) EVT_TOOL( ID_UNDO_BUTT, WinEDA_PcbFrame::GetBoardFromUndoList )
EVT_TOOL( ID_REDO_BUTT, WinEDA_PcbFrame::GetBoardFromRedoList )
EVT_TOOL( ID_GEN_PRINT, WinEDA_DrawFrame::ToPrinter ) EVT_TOOL( ID_GEN_PRINT, WinEDA_DrawFrame::ToPrinter )
EVT_TOOL( ID_GEN_PLOT_SVG, WinEDA_DrawFrame::SVG_Print ) EVT_TOOL( ID_GEN_PLOT_SVG, WinEDA_DrawFrame::SVG_Print )
EVT_TOOL( ID_GEN_PLOT, WinEDA_PcbFrame::Process_Special_Functions ) EVT_TOOL( ID_GEN_PLOT, WinEDA_PcbFrame::Process_Special_Functions )
@ -369,7 +370,8 @@ void WinEDA_PcbFrame::SetToolbars()
{ {
size_t i; size_t i;
int ii, jj; int ii, jj;
bool state;
if( m_ID_current_state == ID_TRACK_BUTT ) if( m_ID_current_state == ID_TRACK_BUTT )
{ {
if( Drc_On ) if( Drc_On )
@ -384,32 +386,17 @@ void WinEDA_PcbFrame::SetToolbars()
m_HToolBar->EnableTool( ID_SAVE_BOARD, GetScreen()->IsModify() ); m_HToolBar->EnableTool( ID_SAVE_BOARD, GetScreen()->IsModify() );
if( GetScreen()->m_BlockLocate.m_Command == BLOCK_MOVE ) state = GetScreen()->m_BlockLocate.m_Command == BLOCK_MOVE;
{ m_HToolBar->EnableTool( wxID_CUT, state );
m_HToolBar->EnableTool( wxID_CUT, TRUE ); m_HToolBar->EnableTool( wxID_COPY, state );
m_HToolBar->EnableTool( wxID_COPY, TRUE );
}
else
{
m_HToolBar->EnableTool( wxID_CUT, FALSE );
m_HToolBar->EnableTool( wxID_COPY, FALSE );
}
if( g_UnDeleteStackPtr ) m_HToolBar->EnableTool( wxID_PASTE, FALSE );
{
m_HToolBar->EnableTool( wxID_PASTE, TRUE );
}
else
{
m_HToolBar->EnableTool( wxID_PASTE, FALSE );
}
if( g_UnDeleteStackPtr ) state = GetScreen()->GetUndoCommandCount() > 0;
{ m_HToolBar->EnableTool( ID_UNDO_BUTT, state );
m_HToolBar->EnableTool( ID_UNDO_BUTT, TRUE );
} state = GetScreen()->GetRedoCommandCount() > 0;
else m_HToolBar->EnableTool( ID_REDO_BUTT, state );
m_HToolBar->EnableTool( ID_UNDO_BUTT, FALSE );
if( m_OptionsToolBar ) if( m_OptionsToolBar )
{ {

View File

@ -228,8 +228,11 @@ void WinEDA_PcbFrame::ReCreateHToolbar()
_( "Paste" ) ); _( "Paste" ) );
#endif #endif
m_HToolBar->AddTool( ID_UNDO_BUTT, wxEmptyString, wxBitmap( undelete_xpm ), m_HToolBar->AddSeparator();
_( "Undelete" ) ); m_HToolBar->AddTool( ID_UNDO_BUTT, wxEmptyString, wxBitmap( undo_xpm ),
_( "Undo last edition" ) );
m_HToolBar->AddTool( ID_REDO_BUTT, wxEmptyString, wxBitmap( redo_xpm ),
_( "Redo the last undo command" ) );
m_HToolBar->AddSeparator(); m_HToolBar->AddSeparator();
m_HToolBar->AddTool( ID_GEN_PRINT, wxEmptyString, wxBitmap( print_button ), m_HToolBar->AddTool( ID_GEN_PRINT, wxEmptyString, wxBitmap( print_button ),

View File

@ -1,178 +0,0 @@
/********************************************************/
/* Effacements : Routines de sauvegarde et d'effacement */
/********************************************************/
#include "fctsys.h"
#include "gr_basic.h"
#include "common.h"
#include "class_drawpanel.h"
#include "confirm.h"
#include "pcbnew.h"
/* Routines externes : */
/* Routines Locales */
/********************************************/
void WinEDA_BasePcbFrame::UnDeleteItem( wxDC* DC )
/********************************************/
/* Restitution d'un element (MODULE ou TRACK ) Efface
*/
{
BOARD_ITEM* item;
int net_code = 0;
if( !g_UnDeleteStackPtr )
return;
g_UnDeleteStackPtr--;
item = g_UnDeleteStack[g_UnDeleteStackPtr];
if( item == NULL )
return; // Ne devrait pas se produire
// we decremented the stack pointer, so the stack no longer
// owns "item". We do here, so we have to delete item if its
// not going back into the board, see default case below.
g_UnDeleteStack[g_UnDeleteStackPtr] = NULL;
switch( item->Type() )
{
case TYPE_VIA:
case TYPE_TRACK:
TRACK* track;
track = (TRACK*) item;
D(printf("%s: track %p status=\"%s\"\n", __func__, track,
CONV_TO_UTF8( TRACK::ShowState( track->GetState(-1)) )
);)
track->SetState( DELETED, OFF );
DrawPanel->PostDirtyRect( track->GetBoundingBox() );
m_Pcb->Add( track );
net_code = track->GetNet();
#if !defined(GERBVIEW)
test_1_net_connexion( DC, net_code );
#endif
m_Pcb->DisplayInfo( this );
break;
case TYPE_BOARD_ITEM_LIST:
BOARD_ITEM_LIST* list;
list = (BOARD_ITEM_LIST*) item;
while( list->GetCount() )
{
TRACK* t = (TRACK*) list->Remove( 0 );
wxASSERT( t->Type()==TYPE_TRACK || t->Type()==TYPE_VIA );
t->SetState( DELETED, OFF );
DrawPanel->PostDirtyRect( t->GetBoundingBox() );
m_Pcb->Add( t );
net_code = t->GetNet();
}
delete list;
#if !defined(GERBVIEW)
test_1_net_connexion( DC, net_code );
#endif
m_Pcb->DisplayInfo( this );
break;
#if !defined(GERBVIEW)
case TYPE_MODULE:
// Erase general rastnest if needed
if( g_Show_Ratsnest )
DrawGeneralRatsnest( DC );
m_Pcb->Add( item );
item->Draw( DrawPanel, DC, GR_OR );
item->SetState( DELETED, OFF ); /* Creal DELETED flag */
item->m_Flags = 0;
Compile_Ratsnest( DC, true );
break;
#endif
default:
DisplayError( this, wxT( "WinEDA_PcbFrame::UnDeleteItem(): unexpected Struct type" ) );
delete item;
break;
}
}
/* Sauvegarde d'un element aux fins de restitution par Undelete
* Supporte actuellement : Module et segments de piste
*/
BOARD_ITEM* WinEDA_BasePcbFrame::SaveItemEfface( BOARD_ITEM* aItem, int nbitems )
{
if( aItem == NULL || nbitems == 0 )
return NULL;
if( g_UnDeleteStackPtr >= UNDELETE_STACK_SIZE )
{
// Delete last deleted item, and shift stack.
delete g_UnDeleteStack[0];
for( int ii = 0; ii < (g_UnDeleteStackPtr - 1); ii++ )
{
g_UnDeleteStack[ii] = g_UnDeleteStack[ii + 1];
}
g_UnDeleteStackPtr--;;
}
switch( aItem->Type() )
{
case TYPE_VIA:
case TYPE_TRACK:
{
DLIST<TRACK>* container = (DLIST<TRACK>*) aItem->GetList();
wxASSERT( container );
if( nbitems == 1 )
{
container->Remove( (TRACK*) aItem );
g_UnDeleteStack[g_UnDeleteStackPtr++] = aItem;
}
else
{
BOARD_ITEM_LIST* list = new BOARD_ITEM_LIST();
g_UnDeleteStack[g_UnDeleteStackPtr++] = list;
// copy the numerous tracks into the list, which is already on stack
int i = 0;
TRACK* next;
for( TRACK* track = (TRACK*) aItem; track && i<nbitems; track = next, ++i )
{
next = track->Next();
list->PushBack( container->Remove( track ) );
}
}
}
break;
#if !defined(GERBVIEW)
case TYPE_MODULE:
{
MODULE* module = (MODULE*) aItem;
m_Pcb->m_Modules.Remove( module );
module->SetState( DELETED, ON );
g_UnDeleteStack[g_UnDeleteStackPtr++] = module;
}
break;
#endif
default:
break;
}
// don't know why this is not simply return aItem?
return g_UnDeleteStack[g_UnDeleteStackPtr - 1];
}