Commit d535a0fc authored by charras's avatar charras

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

pcbnew: Starting work on undo/redo in pcbnew. Only some delete item commands are stored in undo/redo stack
parent 2a7ac9d3
......@@ -4,6 +4,13 @@ KiCad ChangeLog 2009
Please add newer entries at the top, list the date and your name with
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>
================================================================================
++all
......
......@@ -8,7 +8,7 @@
#include "appl_wxstruct.h"
#define BUILD_VERSION "(20090723-unstable)"
#define BUILD_VERSION "(20090729-unstable)"
#ifdef HAVE_SVN_VERSION
......
......@@ -28,7 +28,7 @@ BASE_SCREEN* ActiveScreen = NULL;
BASE_SCREEN::BASE_SCREEN( KICAD_T aType ) : EDA_BaseStruct( aType )
{
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_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()
/******************************/
{
ClearUndoRedoList();
}
......@@ -484,8 +483,8 @@ void BASE_SCREEN::ClearUndoRedoList()
/* free the undo and the redo lists
*/
{
m_UndoList.ClearCommandList();
m_RedoList.ClearCommandList();
ClearUndoORRedoList( m_UndoList );
ClearUndoORRedoList( m_RedoList );
}
......@@ -497,14 +496,12 @@ void BASE_SCREEN::PushCommandToUndoList( PICKED_ITEMS_LIST* aNewitem )
* Deletes olds items if > count max.
*/
{
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() );
}
m_UndoList.PushCommand( aNewitem );
/* 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 )
/***********************************************************/
{
m_RedoList.PushCommand(aNewitem);
while( m_RedoList.m_CommandsList.size() > 0 &&
m_RedoList.m_CommandsList.size() >= m_UndoRedoCountMax )
{
delete m_RedoList.m_CommandsList[0];
m_RedoList.m_CommandsList.erase( m_RedoList.m_CommandsList.begin() );
}
m_RedoList.PushCommand( aNewitem );
/* Delete the extra items, if count max reached */
int extraitems = GetRedoCommandCount() - m_UndoRedoCountMax;
if( extraitems > 0 ) // Delete the extra items
ClearUndoORRedoList( m_RedoList, extraitems );
}
......
......@@ -67,9 +67,6 @@ wxString g_ViaType_Name[4] = {
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 */
/* PCB file name extension definitions. */
......
......@@ -219,6 +219,16 @@ public:
void Process_Settings( 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()
};
......
......@@ -308,3 +308,12 @@ void WinEDA_DisplayFrame::Show3D_Frame( wxCommandEvent& event )
wxFRAME_FLOAT_ON_PARENT );
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 )
{
}
......@@ -84,7 +84,6 @@ SCH_SCREEN::SCH_SCREEN( KICAD_T type ) : BASE_SCREEN( type )
AddGrid( SchematicGridList[i] );
SetGrid( wxRealPoint( 50, 50 ) ); /* usual grid size */
m_UndoRedoCountMax = 10; // Undo/redo levels count. 10 is a reasonnable value
m_RefCount = 0;
m_Center = false; // Suitable for schematic only. for libedit and viewlib, must be set to true
InitDatas();
......
......@@ -127,6 +127,7 @@ bool WinEDA_LibeditFrame::LoadOneLibraryPart()
return FALSE;
}
GetScreen()->ClearUndoRedoList();
LoadOneLibraryPartAux( LibEntry, CurrentLib );
ReCreateHToolbar();
Zoom_Automatique( FALSE );
......
......@@ -3,13 +3,13 @@
/********************************************/
#include "fctsys.h"
#include "gr_basic.h"
#include "class_drawpanel.h"
#include "common.h"
#include "program.h"
#include "libcmp.h"
#include "general.h"
#include "id.h"
//#include "id.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:
......@@ -59,7 +59,7 @@ bool WinEDA_LibeditFrame::GetComponentFromRedoList()
*/
{
if ( GetScreen()->GetRedoCommandCount() <= 0 )
return false;
return;
PICKED_ITEMS_LIST* lastcmd = new PICKED_ITEMS_LIST();
ITEM_PICKER wrapper(CurrentLibEntry);
......@@ -77,12 +77,12 @@ bool WinEDA_LibeditFrame::GetComponentFromRedoList()
ReCreateHToolbar();
SetToolbars();
return true;
DrawPanel->Refresh();
}
/******************************************************/
bool WinEDA_LibeditFrame::GetComponentFromUndoList()
void WinEDA_LibeditFrame::GetComponentFromUndoList(wxCommandEvent& event)
/******************************************************/
/* Undo the last edition:
......@@ -92,7 +92,7 @@ bool WinEDA_LibeditFrame::GetComponentFromUndoList()
*/
{
if ( GetScreen()->GetUndoCommandCount() <= 0 )
return false;
return;
PICKED_ITEMS_LIST* lastcmd = new PICKED_ITEMS_LIST();
ITEM_PICKER wrapper(CurrentLibEntry);
......@@ -111,5 +111,5 @@ bool WinEDA_LibeditFrame::GetComponentFromUndoList()
ReCreateHToolbar();
SetToolbars();
return true;
DrawPanel->Refresh();
}
......@@ -44,8 +44,37 @@ BEGIN_EVENT_TABLE( WinEDA_LibeditFrame, WinEDA_DrawFrame )
// Tools et boutons de Libedit:
/* 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 )
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,
WinEDA_LibeditFrame::Process_Special_Functions )
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,
WinEDA_LibeditFrame::Process_Special_Functions )
// Annulation de commande en cours
EVT_MENU_RANGE( ID_POPUP_GENERAL_START_RANGE, ID_POPUP_GENERAL_END_RANGE,
WinEDA_LibeditFrame::Process_Special_Functions )
......@@ -768,16 +796,6 @@ void WinEDA_LibeditFrame::Process_Special_Functions( wxCommandEvent& event )
HandleBlockPlace( &dc );
break;
case ID_LIBEDIT_UNDO:
if( GetComponentFromUndoList() )
DrawPanel->Refresh( true );
break;
case ID_LIBEDIT_REDO:
if( GetComponentFromRedoList() )
DrawPanel->Refresh( true );
break;
default:
DisplayError( this, wxT( "WinEDA_LibeditFrame::Process_Special_Functions error" ) );
break;
......
......@@ -256,7 +256,7 @@ void WinEDA_SchematicFrame::ReCreateMenuBar()
item->SetBitmap( add_hierarchical_subsheet_xpm );
placeMenu->Append( item );
item = new wxMenuItem( placeMenu, ID_IMPORT_GLABEL_BUTT,
item = new wxMenuItem( placeMenu, ID_IMPORT_HLABEL_BUTT,
_( "Import Hierarchical Label" ),
_( "Place a pin sheet created by importing a hierarchical label from sheet" ),
wxITEM_NORMAL );
......
......@@ -248,7 +248,7 @@ void WinEDA_SchematicFrame::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
}
break;
case ID_IMPORT_GLABEL_BUTT:
case ID_IMPORT_HLABEL_BUTT:
case ID_SHEET_LABEL_BUTT:
if( (DrawStruct == NULL) || (DrawStruct->m_Flags == 0) )
DrawStruct = SchematicGeneralLocateAndDisplay();
......@@ -259,7 +259,7 @@ void WinEDA_SchematicFrame::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
if( (DrawStruct->Type() == DRAW_SHEET_STRUCT_TYPE)
&& (DrawStruct->m_Flags == 0) )
{
if( m_ID_current_state == ID_IMPORT_GLABEL_BUTT )
if( m_ID_current_state == ID_IMPORT_HLABEL_BUTT )
GetScreen()->SetCurItem(
Import_PinSheet( (DrawSheetStruct*) DrawStruct, DC ) );
else
......
......@@ -240,7 +240,7 @@ void WinEDA_SchematicFrame::Process_Special_Functions( wxCommandEvent& event )
SetToolID( id, wxCURSOR_PENCIL, _( "Add PinSheet" ) );
break;
case ID_IMPORT_GLABEL_BUTT:
case ID_IMPORT_HLABEL_BUTT:
SetToolID( id, wxCURSOR_PENCIL, _( "Import PinSheet" ) );
break;
......@@ -718,22 +718,6 @@ void WinEDA_SchematicFrame::Process_Special_Functions( wxCommandEvent& event )
((MARKER_SCH*)screen->GetCurItem())->DisplayMarkerInfo( this );
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:
DisplayError( this,
wxT( "WinEDA_SchematicFrame::Process_Special_Functions error" ) );
......
/*************************************************************/
/* eeschema: undo and redo functions for schematic editor */
/*************************************************************/
/************************************************************/
/* eeschema: undo and redo functions for schematic editor */
/************************************************************/
#include "fctsys.h"
#include "common.h"
#include "confirm.h"
#include "class_drawpanel.h"
#include "program.h"
#include "libcmp.h"
......@@ -29,6 +29,9 @@
* - delete item(s) command
* - change item(s) command
* - add item(s) command
* and 2 cases for block:
* - move list of items
* - mirror (Y) list of items
*
* Undo command
* - delete item(s) command:
......@@ -52,6 +55,11 @@
* - 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.
*
* A problem is the hierarchical sheet handling.
* 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)
......@@ -166,7 +174,7 @@ void SwapData( EDA_BaseStruct* aItem, EDA_BaseStruct* aImage )
// not directly used in schematic:
default:
DisplayInfoMessage( NULL, wxT( "SwapData() error: unexpected type" ) );
wxMessageBox(wxT( "SwapData() error: unexpected type" ) );
break;
}
}
......@@ -211,6 +219,7 @@ void WinEDA_SchematicFrame::SaveCopyInUndoList( SCH_ITEM* aItemToCopy,
CopyOfItem = DuplicateStruct( aItemToCopy );
itemWrapper.m_Item = CopyOfItem;
itemWrapper.m_Link = aItemToCopy;
if ( CopyOfItem )
commandToUndo->PushItem( itemWrapper );
break;
......@@ -225,16 +234,21 @@ void WinEDA_SchematicFrame::SaveCopyInUndoList( SCH_ITEM* aItemToCopy,
{
wxString msg;
msg.Printf( wxT( "SaveCopyInUndoList() error (unknown code %X)" ), aCommandType );
DisplayError( this, msg );
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;
}
......@@ -268,6 +282,7 @@ void WinEDA_SchematicFrame::SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList,
CopyOfItem = DuplicateStruct( ItemToCopy );
itemWrapper.m_Item = CopyOfItem;
itemWrapper.m_Link = ItemToCopy;
if ( CopyOfItem )
commandToUndo->PushItem( itemWrapper );
break;
......@@ -286,48 +301,22 @@ void WinEDA_SchematicFrame::SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList,
{
wxString msg;
msg.Printf( wxT( "SaveCopyInUndoList() error (unknown code %X)" ), command );
DisplayError( this, msg );
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 );
}
/**********************************************************/
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;
}
else
delete commandToUndo;
}
......@@ -401,7 +390,7 @@ void WinEDA_SchematicFrame::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
msg.Printf( wxT(
"PutDataInPreviousState() error (unknown code %X)" ),
itemWrapper.m_UndoRedoStatus );
DisplayError( this, msg );
wxMessageBox( msg );
}
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
......@@ -425,7 +414,7 @@ bool WinEDA_SchematicFrame::GetSchematicFromUndoList()
*/
{
if( GetScreen()->GetUndoCommandCount() <= 0 )
return false;
return;
/* Get the old wrapper and put it in RedoList */
PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromUndoList();
......@@ -439,7 +428,39 @@ bool WinEDA_SchematicFrame::GetSchematicFromUndoList()
ReCreateHToolbar();
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
* free the undo or redo list from List element
* Wrappers are deleted.
* datas pointed by wrappers are deleted if not flagged UR_NEW
* because they are copy of used data or they are not in use (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 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
*/
{
......@@ -506,45 +527,3 @@ void SCH_SCREEN::ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount
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 );
}
......@@ -48,10 +48,6 @@ BEGIN_EVENT_TABLE( WinEDA_SchematicFrame, WinEDA_DrawFrame )
EVT_TOOL( ID_NEW_PROJECT, WinEDA_SchematicFrame::OnNewProject )
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_ONE_SHEET, 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_COPY, 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_GEN_PRINT, WinEDA_SchematicFrame::ToPrinter )
EVT_TOOL( ID_GET_ERC, WinEDA_SchematicFrame::OnErc )
......
......@@ -201,7 +201,7 @@ void WinEDA_SchematicFrame::ReCreateVToolbar()
wxBitmap( add_hierarchical_subsheet_xpm ),
_( "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 ),
_( "Place a pin sheet , imported from the corresponding hierarchical label in sheet" ),
wxITEM_CHECK );
......
......@@ -38,7 +38,7 @@ set(GERBVIEW_SRCS
set(GERBVIEW_EXTRA_SRCS
# ../pcbnew/class_board_item.cpp
# ../pcbnew/class_drawsegment.cpp
../pcbnew/undelete.cpp
# ../pcbnew/undelete.cpp
../share/setpage.cpp
../pcbnew/dialog_print_using_printer.cpp
......
......@@ -90,7 +90,10 @@ TRACK* WinEDA_GerberFrame::Delete_Segment( wxDC* DC, TRACK* Track )
Trace_Segment( DrawPanel, DC, Track, GR_XOR );
SaveItemEfface( Track, 1 );
DLIST<TRACK>* container = (DLIST<TRACK>*) Track->GetList();
wxASSERT( container );
container->Remove( Track );
GetScreen()->SetModify();
return NULL;
}
......@@ -144,22 +144,6 @@ void WinEDA_GerberFrame::Process_Special_Functions( wxCommandEvent& event )
case ID_PCB_GLOBAL_DELETE:
Erase_Current_Layer( TRUE );
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:
// InstallToolsFrame(this, wxPoint(-1,-1) );
......
......@@ -225,18 +225,6 @@ void WinEDA_GerberFrame::SetToolbars()
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() !=
( (PCB_SCREEN*) GetScreen() )->m_Active_Layer )
{
......
......@@ -10,6 +10,7 @@
#include "gestfich.h"
#include "gerbview.h"
#include "wxGerberFrame.h"
#include "pcbplot.h"
#include "bitmaps.h"
#include "protos.h"
......
......@@ -441,5 +441,6 @@ extern GERBER* g_GERBER_List[32];
extern int g_DisplayPolygonsModeSketch;
#include "pcbcommon.h"
#include "wxGerberFrame.h"
#endif // ifndef GERBVIEW_H
......@@ -3,11 +3,8 @@
/***************/
#include "fctsys.h"
#include "gr_basic.h"
#include "common.h"
#include "pcbnew.h"
#include "gerbview.h"
#include "id.h"
#include "hotkeys.h"
......
......@@ -43,12 +43,6 @@ bool WinEDA_GerberFrame::Clear_Pcb( bool query )
GetBoard()->m_Zone.DeleteAll();
for( ; g_UnDeleteStackPtr != 0; )
{
g_UnDeleteStackPtr--;
delete g_UnDeleteStack[ g_UnDeleteStackPtr];
}
/* init pointeurs et variables */
for( layer = 0; layer < 32; layer++ )
{
......
......@@ -186,3 +186,13 @@ void WinEDA_GerberFrame::Trace_Gerber( wxDC* DC, int draw_mode, int printmasklay
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 )
{
}
/***********************************************************/
/* 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 */
......@@ -134,10 +134,49 @@ public:
wxPoint CursorRealPosition( const wxPoint& ScreenPos );
/* 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();
/** 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 );
/** 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 );
/** PopCommandFromUndoList
* return the last command to undo and remove it from list
* nothing is deleted.
*/
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();
int GetUndoCommandCount()
......
......@@ -56,21 +56,20 @@ public:
SCH_ITEM* ExtractWires( bool CreateCopy );
/* full undo redo management : */
virtual void ClearUndoRedoList();
virtual void PushCommandToUndoList( PICKED_ITEMS_LIST* aItem );
virtual void PushCommandToRedoList( PICKED_ITEMS_LIST* aItem );
// use BASE_SCREEN::PushCommandToUndoList( PICKED_ITEMS_LIST* aItem )
// use BASE_SCREEN::PushCommandToRedoList( PICKED_ITEMS_LIST* aItem )
/** Function ClearUndoORRedoList
* free the undo or redo list from List element
* Wrappers are deleted.
* datas pointed by wrappers are deleted if not flagged IS_NEW
* because they are copy of used data or they are not in use (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 are removed from the beginning of the list.
* 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
......
......@@ -137,10 +137,8 @@ enum main_id {
// ID du Main Toolbar de Schematique
ID_SCHEMATIC_MAIN_TOOLBAR_START,
ID_SCHEMATIC_UNDO,
ID_SCHEMATIC_REDO,
ID_SCHEMATIC_MAIN_TOOLBAR_END,
// ID du Vertical Toolbar de Schematique
ID_SCHEMATIC_VERTICAL_TOOLBAR_START,
......@@ -155,7 +153,7 @@ enum main_id {
ID_LABEL_BUTT,
ID_GLABEL_BUTT,
ID_HIERLABEL_BUTT,
ID_IMPORT_GLABEL_BUTT,
ID_IMPORT_HLABEL_BUTT,
ID_SHEET_LABEL_BUTT,
ID_NOCONN_BUTT,
ID_JUNCTION_BUTT,
......
......@@ -5,7 +5,6 @@
#include "pcbstruct.h"
#include "dlist.h"
#define UNDELETE_STACK_SIZE 10
#define L_MIN_DESSIN 1 /* Min width segments to allow draws with tickness */
class DPAD;
......@@ -23,8 +22,6 @@ extern int g_TabAllCopperLayerMask[NB_COPPER_LAYERS];
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 wxString PcbExtBuffer;
......
......@@ -127,9 +127,6 @@ class NETINFO_ITEM;
class MARKER;
class RATSNEST_ITEM;
//class Ki_PageDescr;
//class DrawBlockStruct;
/* main window classes : */
#include "wxPcbStruct.h"
......@@ -204,48 +201,7 @@ enum DisplayViaMode {
};
/* Handle info to display a board */
class PCB_SCREEN : public BASE_SCREEN
{
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 );
};
#include "class_pcb_screen.h"
/**********************************/
/* Module (Footprint) description */
......
......@@ -392,8 +392,8 @@ public:
private:
void PutDataInPreviousState( PICKED_ITEMS_LIST* aList );
bool GetSchematicFromRedoList();
bool GetSchematicFromUndoList();
void GetSchematicFromRedoList(wxCommandEvent& event);
void GetSchematicFromUndoList(wxCommandEvent& event);
public:
......@@ -502,8 +502,8 @@ public:
void InstallFieldsEditorDialog( void );
private:
bool GetComponentFromUndoList();
bool GetComponentFromRedoList();
void GetComponentFromUndoList(wxCommandEvent& event);
void GetComponentFromRedoList(wxCommandEvent& event);
// Edition des Pins:
void CreatePin( wxDC* DC );
......
......@@ -19,9 +19,7 @@
/* Forward declarations of classes. */
class PCB_SCREEN;
class WinEDA_GerberFrame; // GERBER viewer main frame
class WinEDA_Toolbar;
class WinEDA_CvpcbFrame;
class WinEDA_PcbFrame;
class WinEDA_ModuleEditFrame;
class BOARD;
......@@ -111,14 +109,6 @@ public:
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:
// Read/write fonctions:
......@@ -133,9 +123,6 @@ public:
// PCB handling
bool Clear_Pcb( bool query );
void UnDeleteItem( wxDC* DC );
BOARD_ITEM* SaveItemEfface( BOARD_ITEM* aItem, int nbitems );
/**
* Function PcbGeneralLocateAndDisplay
......@@ -312,6 +299,16 @@ public:
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: */
/**
* Function Block_Delete
......@@ -459,6 +456,30 @@ public:
void OnSelectOptionToolbar( 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 */
int ReturnBlockCommand( int key );
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 for the footprint editor */
......@@ -1007,11 +900,12 @@ public:
/* Undo and redo functions */
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:
void GetComponentFromUndoList();
void GetComponentFromRedoList();
void GetComponentFromUndoList(wxCommandEvent& event);
void GetComponentFromRedoList(wxCommandEvent& event);
public:
......
......@@ -14,6 +14,7 @@ set(PCBNEW_SRCS
block.cpp
block_module_editor.cpp
board.cpp
board_undo_redo.cpp
build_BOM_from_board.cpp
# class_board_item.cpp
# class_drawsegment.cpp
......@@ -141,7 +142,6 @@ set(PCBNEW_SRCS
track.cpp
tr_modif.cpp
trpiste.cpp
undelete.cpp
via_edit.cpp
work.cpp
xchgmod.cpp
......
......@@ -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 )
......
/*************************************************************/
/* 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
}
}
......@@ -49,6 +49,8 @@ BOARD::BOARD( EDA_BaseStruct* parent, WinEDA_BasePcbFrame* frame ) :
/***************/
BOARD::~BOARD()
{
m_PcbFrame->GetScreen()->ClearUndoRedoList();
while( m_ZoneDescriptorList.size() )
{
ZONE_CONTAINER* area_to_remove = m_ZoneDescriptorList[0];
......
......@@ -81,6 +81,7 @@ PCB_SCREEN::PCB_SCREEN() : BASE_SCREEN( TYPE_SCREEN )
PCB_SCREEN::~PCB_SCREEN()
/***************************/
{
ClearUndoRedoList();
}
......
......@@ -364,7 +364,9 @@ void WinEDA_PcbFrame::Delete_Cotation( COTATION* Cotation, wxDC* DC )
if( DC )
Cotation->Draw( DrawPanel, DC, GR_XOR );
Cotation->DeleteStructure();
SaveCopyInUndoList(Cotation, UR_DELETED);
Cotation->UnLink();
GetScreen()->SetModify();
}
......
......@@ -105,10 +105,13 @@ TRACK* WinEDA_PcbFrame::Delete_Segment( wxDC* DC, TRACK* aTrack )
current_net_code = aTrack->GetNet();
DLIST<TRACK>* container = (DLIST<TRACK>*) aTrack->GetList();
wxASSERT( container );
container->Remove( aTrack );
// redraw the area where the track was
DrawPanel->PostDirtyRect( aTrack->GetBoundingBox() );
SaveItemEfface( aTrack, 1 );
SaveCopyInUndoList( aTrack, UR_DELETED );
GetScreen()->SetModify();
test_1_net_connexion( DC, current_net_code );
......@@ -138,29 +141,37 @@ void WinEDA_PcbFrame::Delete_net( wxDC* DC, TRACK* aTrack )
if( aTrack == NULL )
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();
/* Recherche du debut de la zone des pistes du net_code courant */
/* Search the first item for the given net code */
TRACK* trackList = GetBoard()->m_Track->GetStartNetCode( net_code_delete );
/* Decompte du nombre de segments de la sous-chaine */
/* Remove all segments having the given net code */
int ii = 0;
for( TRACK* segm = trackList; segm; segm = segm->Next(), ++ii )
TRACK * next_track;
for( TRACK* segm = trackList; segm; segm = next_track, ++ii )
{
next_track = segm->Next();
if( segm->GetNet() != net_code_delete )
break;
GetBoard()->m_Track.Remove( segm );
// redraw the area where the track was
DrawPanel->PostDirtyRect( segm->GetBoundingBox() );
picker.m_Item = segm;
itemsList.PushItem(picker);
}
SaveItemEfface( trackList, ii );
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
*/
{
int nb_segm;
int segments_to_delete_count;
if( pt_segm == NULL )
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();
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;
for( TRACK* t = trackList; ii<nb_segm; ii++, t = t->Next() )
TRACK* tracksegment = trackList;
TRACK * next_track;
for( ; ii < segments_to_delete_count; ii++, tracksegment = next_track )
{
t->SetState( BUSY, OFF );
next_track = tracksegment->Next();
tracksegment->SetState( BUSY, OFF );
D(printf("%s: track %p status=\"%s\"\n", __func__, t,
CONV_TO_UTF8( TRACK::ShowState( t->GetState(-1)) )
D(printf("%s: track %p status=\"%s\"\n", __func__, tracksegment,
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() );
picker.m_Item = tracksegment;
itemsList.PushItem(picker);
}
SaveItemEfface( trackList, nb_segm );
SaveCopyInUndoList( itemsList, UR_DELETED );
if ( net_code > 0 )
test_1_net_connexion( DC, net_code );
}
}
......@@ -143,7 +143,8 @@ void DialogEditModuleText::OnOkClick( wxCommandEvent& event )
{
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
{
m_CurrentTextMod->Draw( m_Parent->DrawPanel, m_DC, GR_XOR,
......
......@@ -475,7 +475,7 @@ void DialogPadProperties::PadPropertiesAccept( wxCommandEvent& event )
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->m_LastEdit_Time = time( NULL );
......
......@@ -332,10 +332,6 @@ void WinEDA_PcbFrame::Process_Special_Functions( wxCommandEvent& event )
HandleBlockEnd( &dc );
break;
case ID_UNDO_BUTT:
UnDeleteItem( &dc );
break;
case ID_DRC_CONTROL:
Install_Test_DRC_Frame( &dc );
break;
......@@ -1269,7 +1265,7 @@ void WinEDA_PcbFrame::RemoveStruct( BOARD_ITEM* Item, wxDC* DC )
SetCurItem( NULL );
( (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 );
break;
......
......@@ -116,8 +116,8 @@ void WinEDA_PcbFrame::Delete_Texte_Pcb( TEXTE_PCB* TextePcb, wxDC* DC )
TextePcb->Draw( DrawPanel, DC, GR_XOR );
/* Suppression du texte en Memoire*/
TextePcb ->DeleteStructure();
SaveCopyInUndoList(TextePcb, UR_DELETED);
TextePcb ->UnLink();
DrawPanel->ManageCurseur = NULL;
DrawPanel->ForceCloseManageCurseur = NULL;
SetCurItem( NULL );
......
......@@ -120,7 +120,8 @@ void WinEDA_PcbFrame::Delete_Segment_Edge( DRAWSEGMENT* Segment, wxDC* DC )
{
Segment->Draw( DrawPanel, DC, GR_XOR );
Segment->m_Flags = 0;
Segment ->DeleteStructure();
SaveCopyInUndoList(Segment, UR_DELETED);
Segment->UnLink();
SetCurItem( NULL );
GetScreen()->SetModify();
}
......
......@@ -139,13 +139,6 @@ bool WinEDA_BasePcbFrame::Clear_Pcb( bool query )
// layer names are put into the BOARD.
SetBoard( new BOARD( NULL, this ) );
while( g_UnDeleteStackPtr > 0 )
{
g_UnDeleteStackPtr--;
delete g_UnDeleteStack[g_UnDeleteStackPtr];
}
/* init pointeurs et variables */
GetScreen()->m_FileName.Empty();
......
......@@ -161,7 +161,8 @@ void WinEDA_PcbFrame::Delete_Mire( MIREPCB* MirePcb, wxDC* DC )
return;
MirePcb->Draw( DrawPanel, DC, GR_XOR );
MirePcb->DeleteStructure();
SaveCopyInUndoList(MirePcb, UR_DELETED);
MirePcb->UnLink();
}
......
......@@ -622,16 +622,6 @@ void WinEDA_ModuleEditFrame::Process_Special_Functions( wxCommandEvent& event )
InstallGridFrame( pos );
break;
case ID_MODEDIT_UNDO:
GetComponentFromUndoList();
redraw = true;
break;
case ID_MODEDIT_REDO:
GetComponentFromRedoList();
redraw = true;
break;
case ID_POPUP_PLACE_BLOCK:
GetScreen()->m_BlockLocate.m_Command = BLOCK_MOVE;
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 )
/******************************************************************************/
/* Execute les transformations de la repr�sentation des modules.
* le module, apres transformation est toujours en position de reference:
/* Execute a geometric transform on the current footprint.
* The footprint, after transform is always in reference position and orientation:
* position 0,0
* orientation 0, cot� composant.
* orientation 0, component side.
*/
{
D_PAD* pad = module->m_Pads;
......
......@@ -3,7 +3,7 @@
/********************************************/
#include "fctsys.h"
#include "gr_basic.h"
#include "class_drawpanel.h"
#include "common.h"
#include "pcbnew.h"
......@@ -13,8 +13,9 @@
/**************************************************************************/
void WinEDA_ModuleEditFrame::SaveCopyInUndoList( EDA_BaseStruct* ItemToCopy,
int unused_flag )
void WinEDA_ModuleEditFrame::SaveCopyInUndoList( BOARD_ITEM* ItemToCopy,
UndoRedoOpType aTypeCommand,
const wxPoint& aTransformPoint )
/************************************************************************/
{
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:
......@@ -76,12 +77,13 @@ void WinEDA_ModuleEditFrame::GetComponentFromRedoList()
GetScreen()->SetModify();
ReCreateHToolbar();
SetToolbars();
DrawPanel->Refresh();
}
/*********************************************************/
void WinEDA_ModuleEditFrame::GetComponentFromUndoList()
/*********************************************************/
/***************************************************************************/
void WinEDA_ModuleEditFrame::GetComponentFromUndoList(wxCommandEvent& event)
/***************************************************************************/
/* Undo the last edition:
* - Place the current edited library component in Redo list
......@@ -108,4 +110,5 @@ void WinEDA_ModuleEditFrame::GetComponentFromUndoList()
SetCurItem( NULL );;
ReCreateHToolbar();
SetToolbars();
DrawPanel->Refresh();
}
......@@ -70,9 +70,9 @@ BEGIN_EVENT_TABLE( WinEDA_ModuleEditFrame, WinEDA_BasePcbFrame )
EVT_TOOL( ID_MODEDIT_EDIT_MODULE_PROPERTIES,
WinEDA_ModuleEditFrame::Process_Special_Functions )
EVT_TOOL( ID_MODEDIT_UNDO,
WinEDA_ModuleEditFrame::Process_Special_Functions )
WinEDA_ModuleEditFrame::GetComponentFromUndoList )
EVT_TOOL( ID_MODEDIT_REDO,
WinEDA_ModuleEditFrame::Process_Special_Functions )
WinEDA_ModuleEditFrame::GetComponentFromRedoList )
// Vertical toolbar (left click):
EVT_TOOL( ID_NO_SELECT_BUTT,
......
......@@ -320,8 +320,10 @@ bool WinEDA_PcbFrame::Delete_Module( MODULE* module, wxDC* DC, bool aAskBeforeDe
if( g_Show_Ratsnest )
DrawGeneralRatsnest( DC );
/* Sauvegarde en buffer des undelete */
SaveItemEfface( module, 1 );
/* Remove module from list, and put it in undo command list */
m_Pcb->m_Modules.Remove( module );
module->SetState( DELETED, ON );
SaveCopyInUndoList( module, UR_DELETED );
Compile_Ratsnest( DC, true );
......
......@@ -322,7 +322,8 @@ void WinEDA_BasePcbFrame::PlacePad( D_PAD* Pad, wxDC* DC )
Pad->Draw( DrawPanel, DC, GR_XOR );
/* 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;
/* Compute local coordinates (i.e refer to Module position and for Module orient = 0)*/
......
......@@ -127,7 +127,8 @@ BEGIN_EVENT_TABLE( WinEDA_PcbFrame, WinEDA_BasePcbFrame )
EVT_TOOL( wxID_CUT, 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( 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_PLOT_SVG, WinEDA_DrawFrame::SVG_Print )
EVT_TOOL( ID_GEN_PLOT, WinEDA_PcbFrame::Process_Special_Functions )
......@@ -369,6 +370,7 @@ void WinEDA_PcbFrame::SetToolbars()
{
size_t i;
int ii, jj;
bool state;
if( m_ID_current_state == ID_TRACK_BUTT )
{
......@@ -384,32 +386,17 @@ void WinEDA_PcbFrame::SetToolbars()
m_HToolBar->EnableTool( ID_SAVE_BOARD, GetScreen()->IsModify() );
if( GetScreen()->m_BlockLocate.m_Command == BLOCK_MOVE )
{
m_HToolBar->EnableTool( wxID_CUT, TRUE );
m_HToolBar->EnableTool( wxID_COPY, TRUE );
}
else
{
m_HToolBar->EnableTool( wxID_CUT, FALSE );
m_HToolBar->EnableTool( wxID_COPY, FALSE );
}
state = GetScreen()->m_BlockLocate.m_Command == BLOCK_MOVE;
m_HToolBar->EnableTool( wxID_CUT, state );
m_HToolBar->EnableTool( wxID_COPY, state );
if( g_UnDeleteStackPtr )
{
m_HToolBar->EnableTool( wxID_PASTE, TRUE );
}
else
{
m_HToolBar->EnableTool( wxID_PASTE, FALSE );
}
if( g_UnDeleteStackPtr )
{
m_HToolBar->EnableTool( ID_UNDO_BUTT, TRUE );
}
else
m_HToolBar->EnableTool( ID_UNDO_BUTT, FALSE );
state = GetScreen()->GetUndoCommandCount() > 0;
m_HToolBar->EnableTool( ID_UNDO_BUTT, state );
state = GetScreen()->GetRedoCommandCount() > 0;
m_HToolBar->EnableTool( ID_REDO_BUTT, state );
if( m_OptionsToolBar )
{
......
......@@ -228,8 +228,11 @@ void WinEDA_PcbFrame::ReCreateHToolbar()
_( "Paste" ) );
#endif
m_HToolBar->AddTool( ID_UNDO_BUTT, wxEmptyString, wxBitmap( undelete_xpm ),
_( "Undelete" ) );
m_HToolBar->AddSeparator();
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->AddTool( ID_GEN_PRINT, wxEmptyString, wxBitmap( print_button ),
......
/********************************************************/
/* 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];
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment