Unified undo buffer handling code for PCB & module editor.

Replaced UR_MODEDIT with UR_CHANGED.
This commit is contained in:
Maciej Suminski 2016-05-25 11:52:43 +02:00
parent b0a191ce3d
commit 1dd43d1d98
22 changed files with 262 additions and 535 deletions

View File

@ -153,10 +153,6 @@ void PICKED_ITEMS_LIST::ClearListAndDeleteItems()
case UR_LIBEDIT: /* Libedit save always a copy of the current item
* So, the picker is always owner of the picked item
*/
case UR_MODEDIT: /* Specific to the module editor (modedit creates a full
* copy of the current module when changed),
* and the picker is owner of this item
*/
delete wrapper.GetItem();
break;

View File

@ -69,8 +69,6 @@ enum UNDO_REDO_T {
UR_ROTATED_CLOCKWISE, // Rotated item (clockwise), undo by rotating it
UR_FLIPPED, // flipped (board items only), undo by flipping it
UR_WIRE_IMAGE, // Specific to Eeschema for handling wires changes.
UR_MODEDIT, // Specific to the module editor (modedit creates a full copy of
// the current module when changed)
UR_LIBEDIT, // Specific to the component editor (libedit creates a full copy
// of the current component when changed)
UR_EXCHANGE_T ///< Use for changing the schematic text type where swapping

View File

@ -638,64 +638,6 @@ 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 UNDO_REDO_T)
* @param aTransformPoint = the reference point of the transformation, for
* commands like move
*/
virtual void SaveCopyInUndoList( BOARD_ITEM* aItemToCopy,
UNDO_REDO_T 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 UNDO_REDO_T)
* @param aTransformPoint = the reference point of the transformation, for
* commands like move
*/
virtual void SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
UNDO_REDO_T aTypeCommand,
const wxPoint& aTransformPoint = wxPoint( 0, 0 ) );
/**
* Function PutDataInPreviousState
* Used in undo or redo command.
* Put data pointed by List in the previous state, i.e. the state memorized by List
* @param aList = a PICKED_ITEMS_LIST pointer to the list of items to undo/redo
* @param aRedoCommand = a bool: true for redo, false for undo
* @param aRebuildRatsnet = a bool: true to rebuild ratsnest (normal use), false
* to just retrieve last state (used in abort commands that do not need to
* rebuild ratsnest)
*/
void PutDataInPreviousState( PICKED_ITEMS_LIST* aList,
bool aRedoCommand,
bool aRebuildRatsnet = true );
/**
* Function RestoreCopyFromRedoList
* Redo the last edition:
* - Save the current board in Undo list
* - Get an old version of the board from Redo list
* @return none
*/
void RestoreCopyFromRedoList( wxCommandEvent& aEvent );
/**
* Function RestoreCopyFromUndoList
* Undo the last edition:
* - Save the current board in Redo list
* - Get an old version of the board from Undo list
* @return none
*/
void RestoreCopyFromUndoList( wxCommandEvent& aEvent );
/* Block operations: */
/**

View File

@ -190,7 +190,6 @@ set( PCBNEW_CLASS_SRCS
array_creator.cpp
attribut.cpp
board_items_to_polygon_shape_transform.cpp
board_undo_redo.cpp
board_netlist_updater.cpp
block.cpp
block_module_editor.cpp
@ -237,7 +236,6 @@ set( PCBNEW_CLASS_SRCS
modedit.cpp
modedit_onclick.cpp
modeditoptions.cpp
modedit_undo_redo.cpp
moduleframe.cpp
modules.cpp
move-drag_pads.cpp
@ -266,6 +264,7 @@ set( PCBNEW_CLASS_SRCS
toolbars_update_user_interface.cpp
tracepcb.cpp
tr_modif.cpp
undo_redo.cpp
xchgmod.cpp
zones_convert_brd_items_to_polygons_with_Boost.cpp
zones_convert_to_polygons_aux_functions.cpp

View File

@ -59,7 +59,7 @@ void ARRAY_CREATOR::Invoke()
if( isModuleEditor )
{
// modedit saves everything upfront
m_parent.SaveCopyInUndoList( getBoard()->m_Modules, UR_MODEDIT );
m_parent.SaveCopyInUndoList( getBoard()->m_Modules, UR_CHANGED );
}
for ( int i = 0; i < numItems; ++i )

View File

@ -196,7 +196,7 @@ bool FOOTPRINT_EDIT_FRAME::HandleBlockEnd( wxDC* DC )
if( ret == wxID_OK )
{
SaveCopyInUndoList( currentModule, UR_MODEDIT );
SaveCopyInUndoList( currentModule, UR_CHANGED );
const wxPoint blockCentre = GetScreen()->m_BlockLocate.Centre();
MoveMarkedItemsExactly( currentModule, blockCentre, translation, rotation );
}
@ -213,7 +213,7 @@ bool FOOTPRINT_EDIT_FRAME::HandleBlockEnd( wxDC* DC )
itemsCount = MarkItemsInBloc( currentModule, GetScreen()->m_BlockLocate );
if( itemsCount )
SaveCopyInUndoList( currentModule, UR_MODEDIT );
SaveCopyInUndoList( currentModule, UR_CHANGED );
DeleteMarkedItems( currentModule );
break;
@ -226,7 +226,7 @@ bool FOOTPRINT_EDIT_FRAME::HandleBlockEnd( wxDC* DC )
itemsCount = MarkItemsInBloc( currentModule, GetScreen()->m_BlockLocate );
if( itemsCount )
SaveCopyInUndoList( currentModule, UR_MODEDIT );
SaveCopyInUndoList( currentModule, UR_CHANGED );
RotateMarkedItems( currentModule, GetScreen()->m_BlockLocate.Centre() );
break;
@ -237,7 +237,7 @@ bool FOOTPRINT_EDIT_FRAME::HandleBlockEnd( wxDC* DC )
itemsCount = MarkItemsInBloc( currentModule, GetScreen()->m_BlockLocate );
if( itemsCount )
SaveCopyInUndoList( currentModule, UR_MODEDIT );
SaveCopyInUndoList( currentModule, UR_CHANGED );
MirrorMarkedItems( currentModule, GetScreen()->m_BlockLocate.Centre() );
break;
@ -293,7 +293,7 @@ void FOOTPRINT_EDIT_FRAME::HandleBlockPlace( wxDC* DC )
case BLOCK_MOVE: // Move
case BLOCK_PRESELECT_MOVE: // Move with preselection list
GetScreen()->m_BlockLocate.ClearItemsList();
SaveCopyInUndoList( currentModule, UR_MODEDIT );
SaveCopyInUndoList( currentModule, UR_CHANGED );
MoveMarkedItems( currentModule, GetScreen()->m_BlockLocate.GetMoveVector() );
m_canvas->Refresh( true );
break;
@ -301,7 +301,7 @@ void FOOTPRINT_EDIT_FRAME::HandleBlockPlace( wxDC* DC )
case BLOCK_COPY: // Copy
case BLOCK_COPY_AND_INCREMENT: // Copy and increment pad names
GetScreen()->m_BlockLocate.ClearItemsList();
SaveCopyInUndoList( currentModule, UR_MODEDIT );
SaveCopyInUndoList( currentModule, UR_CHANGED );
CopyMarkedItems( currentModule, GetScreen()->m_BlockLocate.GetMoveVector(),
command == BLOCK_COPY_AND_INCREMENT );
break;
@ -313,12 +313,12 @@ void FOOTPRINT_EDIT_FRAME::HandleBlockPlace( wxDC* DC )
case BLOCK_MIRROR_X:
case BLOCK_MIRROR_Y:
case BLOCK_FLIP: // Mirror by popup menu, from block move
SaveCopyInUndoList( currentModule, UR_MODEDIT );
SaveCopyInUndoList( currentModule, UR_CHANGED );
MirrorMarkedItems( currentModule, GetScreen()->m_BlockLocate.Centre() );
break;
case BLOCK_ROTATE:
SaveCopyInUndoList( currentModule, UR_MODEDIT );
SaveCopyInUndoList( currentModule, UR_CHANGED );
RotateMarkedItems( currentModule, GetScreen()->m_BlockLocate.Centre() );
break;

View File

@ -465,7 +465,7 @@ void DIALOG_MODULE_MODULE_EDITOR::OnOkClick( wxCommandEvent& event )
return;
}
m_parent->SaveCopyInUndoList( m_currentModule, UR_MODEDIT );
m_parent->SaveCopyInUndoList( m_currentModule, UR_CHANGED );
m_currentModule->SetLocked( m_AutoPlaceCtrl->GetSelection() == 1 );
switch( m_AttributsCtrl->GetSelection() )

View File

@ -226,7 +226,7 @@ bool DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES::TransferDataFromWindow()
return false;;
}
m_parent->SaveCopyInUndoList( m_module, UR_MODEDIT );
m_parent->SaveCopyInUndoList( m_module, UR_CHANGED );
m_module->SetLastEditTime();
wxString msg;

View File

@ -163,7 +163,7 @@ void FOOTPRINT_EDIT_FRAME::Edit_Edge_Width( EDGE_MODULE* aEdge )
{
MODULE* module = GetBoard()->m_Modules;
SaveCopyInUndoList( module, UR_MODEDIT );
SaveCopyInUndoList( module, UR_CHANGED );
if( aEdge == NULL )
{
@ -225,7 +225,7 @@ void FOOTPRINT_EDIT_FRAME::Edit_Edge_Layer( EDGE_MODULE* aEdge )
if( aEdge && (aEdge->GetLayer() != new_layer) )
{
if( ! modified ) // save only once
SaveCopyInUndoList( module, UR_MODEDIT );
SaveCopyInUndoList( module, UR_CHANGED );
aEdge->SetLayer( new_layer );
modified = true;
}
@ -233,7 +233,7 @@ void FOOTPRINT_EDIT_FRAME::Edit_Edge_Layer( EDGE_MODULE* aEdge )
}
else if( aEdge->GetLayer() != new_layer )
{
SaveCopyInUndoList( module, UR_MODEDIT );
SaveCopyInUndoList( module, UR_CHANGED );
aEdge->SetLayer( new_layer );
modified = true;
}
@ -330,7 +330,7 @@ EDGE_MODULE* FOOTPRINT_EDIT_FRAME::Begin_Edge_Module( EDGE_MODULE* aEdge,
if( aEdge == NULL ) // Start a new edge item
{
SaveCopyInUndoList( module, UR_MODEDIT );
SaveCopyInUndoList( module, UR_CHANGED );
aEdge = new EDGE_MODULE( module );
MoveVector.x = MoveVector.y = 0;

View File

@ -243,7 +243,7 @@ void PCB_BASE_FRAME::PlaceTexteModule( TEXTE_MODULE* Text, wxDC* DC )
if( IsType( FRAME_PCB ) )
SaveCopyInUndoList( Module, UR_CHANGED );
else
SaveCopyInUndoList( Module, UR_MODEDIT );
SaveCopyInUndoList( Module, UR_CHANGED );
Text->SetOrientation( tmp );

View File

@ -245,7 +245,7 @@ bool InvokeDXFDialogModuleImport( PCB_BASE_FRAME* aCaller, MODULE* aModule )
{
const std::list<BOARD_ITEM*>& list = dlg.GetImportedItems();
aCaller->SaveCopyInUndoList( aModule, UR_MODEDIT );
aCaller->SaveCopyInUndoList( aModule, UR_CHANGED );
aCaller->OnModify();
std::list<BOARD_ITEM*>::const_iterator it, itEnd;

View File

@ -651,7 +651,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break;
case ID_POPUP_PCB_DELETE_PAD:
SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
DeletePad( (D_PAD*) GetScreen()->GetCurItem(), false );
SetCurItem( NULL );
m_canvas->MoveCursorToCrossHair();
@ -674,13 +674,13 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break;
case ID_POPUP_PCB_IMPORT_PAD_SETTINGS:
SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
m_canvas->MoveCursorToCrossHair();
Import_Pad_Settings( (D_PAD*) GetScreen()->GetCurItem(), true );
break;
case ID_POPUP_PCB_GLOBAL_IMPORT_PAD_SETTINGS:
SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
// Calls the global change dialog:
DlgGlobalChange_PadSettings( (D_PAD*) GetScreen()->GetCurItem() );
m_canvas->MoveCursorToCrossHair();
@ -707,7 +707,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break;
case ID_POPUP_PCB_DELETE_TEXTMODULE:
SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
DeleteTextModule( static_cast<TEXTE_MODULE*>( GetScreen()->GetCurItem() ) );
SetCurItem( NULL );
m_canvas->MoveCursorToCrossHair();
@ -765,7 +765,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break;
case ID_POPUP_PCB_DELETE_EDGE:
SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
m_canvas->MoveCursorToCrossHair();
RemoveStruct( GetScreen()->GetCurItem() );
SetCurItem( NULL );
@ -774,7 +774,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
case ID_MODEDIT_MODULE_ROTATE:
case ID_MODEDIT_MODULE_MIRROR:
case ID_MODEDIT_MODULE_MOVE_EXACT:
SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
Transform( (MODULE*) GetScreen()->GetCurItem(), id );
m_canvas->Refresh();
break;
@ -870,7 +870,7 @@ void FOOTPRINT_EDIT_FRAME::moveExact()
if( ret == wxID_OK )
{
SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
BOARD_ITEM* item = GetScreen()->GetCurItem();

View File

@ -61,7 +61,7 @@ void FOOTPRINT_EDIT_FRAME::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
break;
case PCB_MODULE_EDGE_T:
SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
Place_EdgeMod( static_cast<EDGE_MODULE*>( item ) );
break;
@ -147,7 +147,7 @@ void FOOTPRINT_EDIT_FRAME::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
if( item && item->Type() != PCB_MODULE_T ) // Cannot delete the module itself
{
SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
RemoveStruct( item );
SetCurItem( NULL );
}
@ -162,7 +162,7 @@ void FOOTPRINT_EDIT_FRAME::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
|| (module->GetFlags() != 0) )
break;
SaveCopyInUndoList( module, UR_MODEDIT );
SaveCopyInUndoList( module, UR_CHANGED );
// set the new relative internal local coordinates of footprint items
wxPoint moveVector = module->GetPosition() - GetCrossHairPosition();
@ -187,14 +187,14 @@ void FOOTPRINT_EDIT_FRAME::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
if( GetBoard()->m_Modules == NULL )
break;
SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
CreateTextModule( GetBoard()->m_Modules, DC );
break;
case ID_MODEDIT_PAD_TOOL:
if( GetBoard()->m_Modules )
{
SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
AddPad( GetBoard()->m_Modules, true );
}

View File

@ -1,176 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2007-2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <functional>
using namespace std::placeholders;
#include <fctsys.h>
#include <class_drawpanel.h>
#include <class_draw_panel_gal.h>
#include <tool/tool_manager.h>
#include <wxPcbStruct.h>
#include <class_board.h>
#include <class_module.h>
#include <pcbnew.h>
#include <protos.h>
#include <module_editor_frame.h>
void FOOTPRINT_EDIT_FRAME::SaveCopyInUndoList( BOARD_ITEM* aItem,
UNDO_REDO_T aTypeCommand,
const wxPoint& aTransformPoint )
{
EDA_ITEM* item;
MODULE* CopyItem;
PICKED_ITEMS_LIST* lastcmd;
CopyItem = new MODULE( *( (MODULE*) aItem ) );
CopyItem->SetParent( GetBoard() );
lastcmd = new PICKED_ITEMS_LIST();
ITEM_PICKER wrapper( CopyItem, UR_MODEDIT );
lastcmd->PushItem( wrapper );
GetScreen()->PushCommandToUndoList( lastcmd );
/* Clear current flags (which can be temporary set by a current edit command) */
for( item = CopyItem->GraphicalItems(); item != NULL; item = item->Next() )
item->ClearFlags();
for( D_PAD* pad = CopyItem->Pads(); pad; pad = pad->Next() )
pad->ClearFlags();
CopyItem->Reference().ClearFlags();
CopyItem->Value().ClearFlags();
/* Clear redo list, because after new save there is no redo to do */
GetScreen()->ClearUndoORRedoList( GetScreen()->m_RedoList );
}
void FOOTPRINT_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
UNDO_REDO_T aTypeCommand,
const wxPoint& aTransformPoint )
{
assert( aItemsList.GetPickedItem( 0 )->GetParent()->Type() == PCB_MODULE_T );
MODULE* owner = static_cast<MODULE*>( aItemsList.GetPickedItem( 0 )->GetParent() );
#ifndef NDEBUG
// All items should have the same parent (MODULE) to make undo/redo entry valid
for( unsigned int i = 0; i < aItemsList.GetCount(); ++i )
assert( aItemsList.GetPickedItem( i )->GetParent() == owner );
#endif /* not NDEBUG */
SaveCopyInUndoList( owner, aTypeCommand, aTransformPoint );
}
void FOOTPRINT_EDIT_FRAME::RestoreCopyFromRedoList( wxCommandEvent& aEvent )
{
if( GetScreen()->GetRedoCommandCount() <= 0 )
return;
// Inform tools that undo command was issued
TOOL_EVENT event( TC_MESSAGE, TA_UNDO_REDO, AS_GLOBAL );
m_toolManager->ProcessEvent( event );
// Save current module state in undo list
PICKED_ITEMS_LIST* lastcmd = new PICKED_ITEMS_LIST();
MODULE* module = GetBoard()->m_Modules.PopFront();
ITEM_PICKER wrapper( module, UR_MODEDIT );
KIGFX::VIEW* view = GetGalCanvas()->GetView();
lastcmd->PushItem( wrapper );
GetScreen()->PushCommandToUndoList( lastcmd );
view->Remove( module );
module->RunOnChildren( std::bind( &KIGFX::VIEW::Remove, view, _1 ) );
// Retrieve last module state from undo list
lastcmd = GetScreen()->PopCommandFromRedoList();
wrapper = lastcmd->PopItem();
module = (MODULE*) wrapper.GetItem();
delete lastcmd;
if( module )
{
GetBoard()->Add( module );
GetGalCanvas()->GetView()->Add( module );
module->RunOnChildren( std::bind( &KIGFX::VIEW::Add, view, _1 ) );
module->ViewUpdate();
}
SetCurItem( NULL );
OnModify();
m_canvas->Refresh();
}
void FOOTPRINT_EDIT_FRAME::RestoreCopyFromUndoList( wxCommandEvent& aEvent )
{
if( UndoRedoBlocked() )
return;
if( GetScreen()->GetUndoCommandCount() <= 0 )
return;
// Inform tools that undo command was issued
TOOL_EVENT event( TC_MESSAGE, TA_UNDO_REDO, AS_GLOBAL );
m_toolManager->ProcessEvent( event );
if( UndoRedoBlocked() )
return;
// Save current module state in redo list
PICKED_ITEMS_LIST* lastcmd = new PICKED_ITEMS_LIST();
MODULE* module = GetBoard()->m_Modules.PopFront();
ITEM_PICKER wrapper( module, UR_MODEDIT );
KIGFX::VIEW* view = GetGalCanvas()->GetView();
lastcmd->PushItem( wrapper );
GetScreen()->PushCommandToRedoList( lastcmd );
view->Remove( module );
module->RunOnChildren( std::bind( &KIGFX::VIEW::Remove, view, _1 ) );
// Retrieve last module state from undo list
lastcmd = GetScreen()->PopCommandFromUndoList();
wrapper = lastcmd->PopItem();
module = (MODULE*) wrapper.GetItem();
delete lastcmd;
if( module )
{
GetBoard()->Add( module, ADD_APPEND );
view->Add( module );
module->RunOnChildren( std::bind( &KIGFX::VIEW::Add, view, _1 ) );
module->ViewUpdate();
}
SetCurItem( NULL );
OnModify();
m_canvas->Refresh();
}

View File

@ -270,50 +270,6 @@ public:
BOARD_ITEM* ModeditLocateAndDisplay( int aHotKeyCode = 0 );
/* Undo and redo functions */
/**
* Function SaveCopyInUndoList.
* Creates a new entry in undo list of commands.
* add a picker to handle aItemToCopy
* @param aItem = the board item modified by the command to undo
* @param aTypeCommand = command type (see enum UNDO_REDO_T)
* @param aTransformPoint = the reference point of the transformation, for
* commands like move
*/
virtual void SaveCopyInUndoList( BOARD_ITEM* aItem,
UNDO_REDO_T 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 UNDO_REDO_T)
* @param aTransformPoint = the reference point of the transformation, for
* commands like move
*/
virtual void SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
UNDO_REDO_T aTypeCommand,
const wxPoint& aTransformPoint = wxPoint( 0, 0 ) );
/**
* Function RestoreCopyFromUndoList
* performs an undo operation on the last edition:
* - Place the current edited library component in Redo list
* - Get old version of the current edited library component
*/
void RestoreCopyFromUndoList( wxCommandEvent& aEvent );
/**
* Function RestoreCopyFromRedoList
* performs a redo operation on the the last edition:
* - Place the current edited library component in undo list
* - Get old version of the current edited library component
*/
void RestoreCopyFromRedoList( wxCommandEvent& aEvent );
/// Return the current library nickname.
const wxString GetCurrentLib() const;

View File

@ -69,26 +69,62 @@ public:
*/
virtual void OnEditItemRequest( wxDC* aDC, BOARD_ITEM* aItem ) = 0;
// Undo buffer handling
/**
* 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 UNDO_REDO_T)
* @param aTransformPoint = the reference point of the transformation, for
* commands like move
*/
void SaveCopyInUndoList( BOARD_ITEM* aItemToCopy, UNDO_REDO_T aTypeCommand,
const wxPoint& aTransformPoint = wxPoint( 0, 0 ) ) override;
/**
* Function SaveCopyInUndoList
* 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 UNDO_REDO_T)
* @param aTransformPoint = the reference point of the transformation,
* for commands like move
*/
void SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList, UNDO_REDO_T aTypeCommand,
const wxPoint& aTransformPoint = wxPoint( 0, 0 ) ) override;
/**
* Function RestoreCopyFromRedoList
* Redo the last edition:
* - Save the current data in Undo list
* - Get an old version of the data from Redo list
* - Save the current board in Undo list
* - Get an old version of the board from Redo list
* @return none
*/
virtual void RestoreCopyFromRedoList( wxCommandEvent& aEvent ) = 0;
void RestoreCopyFromRedoList( wxCommandEvent& aEvent );
/**
* Function RestoreCopyFromUndoList
* Undo the last edition:
* - Save the current board in Redo list
* - Get an old version of the data from Undo list
* - Get an old version of the board from Undo list
* @return none
*/
virtual void RestoreCopyFromUndoList( wxCommandEvent& aEvent ) = 0;
void RestoreCopyFromUndoList( wxCommandEvent& aEvent );
int GetRotationAngle() const { return m_rotationAngle; }
void SetRotationAngle( int aRotationAngle );
bool PostCommandMenuEvent( int evt_type );
/**
* Function PutDataInPreviousState
* Used in undo or redo command.
* Put data pointed by List in the previous state, i.e. the state memorized by List
* @param aList = a PICKED_ITEMS_LIST pointer to the list of items to undo/redo
* @param aRedoCommand = a bool: true for redo, false for undo
* @param aRebuildRatsnet = a bool: true to rebuild ratsnest (normal use), false
* to just retrieve last state (used in abort commands that do not need to
* rebuild ratsnest)
*/
void PutDataInPreviousState( PICKED_ITEMS_LIST* aList,
bool aRedoCommand,
bool aRebuildRatsnet = true );
/**
* Function UndoRedoBlocked
@ -108,6 +144,20 @@ public:
m_undoRedoBlocked = aBlock;
}
/**
* Function GetRotationAngle()
* Returns the angle used for rotate operations.
*/
int GetRotationAngle() const { return m_rotationAngle; }
/**
* Function SetRotationAngle()
* Sets the angle used for rotate operations.
*/
void SetRotationAngle( int aRotationAngle );
bool PostCommandMenuEvent( int evt_type );
///> @copydoc EDA_DRAW_FRAME::UseGalCanvas()
void UseGalCanvas( bool aEnable );

View File

@ -196,8 +196,8 @@ BEGIN_EVENT_TABLE( PCB_EDIT_FRAME, PCB_BASE_FRAME )
EVT_TOOL( wxID_CUT, PCB_EDIT_FRAME::Process_Special_Functions )
EVT_TOOL( wxID_COPY, PCB_EDIT_FRAME::Process_Special_Functions )
EVT_TOOL( wxID_PASTE, PCB_EDIT_FRAME::Process_Special_Functions )
EVT_TOOL( wxID_UNDO, PCB_EDIT_FRAME::RestoreCopyFromUndoList )
EVT_TOOL( wxID_REDO, PCB_EDIT_FRAME::RestoreCopyFromRedoList )
EVT_TOOL( wxID_UNDO, PCB_BASE_EDIT_FRAME::RestoreCopyFromUndoList )
EVT_TOOL( wxID_REDO, PCB_BASE_EDIT_FRAME::RestoreCopyFromRedoList )
EVT_TOOL( wxID_PRINT, PCB_EDIT_FRAME::ToPrinter )
EVT_TOOL( ID_GEN_PLOT_SVG, PCB_EDIT_FRAME::SVG_Print )
EVT_TOOL( ID_GEN_PLOT, PCB_EDIT_FRAME::Process_Special_Functions )

View File

@ -85,7 +85,7 @@ int DRAWING_TOOL::DrawLine( const TOOL_EVENT& aEvent )
if( line )
{
m_frame->OnModify();
m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_MODEDIT );
m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_CHANGED );
line->SetParent( m_board->m_Modules );
line->SetLocalCoord();
m_board->m_Modules->GraphicalItems().PushFront( line );
@ -142,7 +142,7 @@ int DRAWING_TOOL::DrawCircle( const TOOL_EVENT& aEvent )
if( circle )
{
m_frame->OnModify();
m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_MODEDIT );
m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_CHANGED );
circle->SetParent( m_board->m_Modules );
circle->SetLocalCoord();
m_board->m_Modules->GraphicalItems().PushFront( circle );
@ -189,7 +189,7 @@ int DRAWING_TOOL::DrawArc( const TOOL_EVENT& aEvent )
if( arc )
{
m_frame->OnModify();
m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_MODEDIT );
m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_CHANGED );
arc->SetParent( m_board->m_Modules );
arc->SetLocalCoord();
m_board->m_Modules->GraphicalItems().PushFront( arc );
@ -237,10 +237,6 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
DIMENSION* dimension = NULL;
int maxThickness;
// if one day it is possible to draw dimensions in the footprint editor,
// then hereby I'm letting you know that this tool does not handle UR_MODEDIT undo yet
assert( !m_editModules );
// Add a VIEW_GROUP that serves as a preview for the new item
KIGFX::VIEW_GROUP preview( m_view );
m_view->Add( &preview );
@ -516,7 +512,7 @@ int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent )
if( m_editModules )
{
assert( m_board->m_Modules );
m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_MODEDIT );
m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_CHANGED );
m_board->m_Modules->SetLastEditTime();
for( KIGFX::VIEW_GROUP::const_iter it = preview.Begin(), end = preview.End(); it != end; ++it )
@ -608,7 +604,7 @@ int DRAWING_TOOL::SetAnchor( const TOOL_EVENT& aEvent )
{
if( evt->IsClick( BUT_LEFT ) )
{
m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_MODEDIT );
m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_CHANGED );
m_board->m_Modules->SetLastEditTime();
// set the new relative internal local coordinates of footprint items
@ -763,7 +759,7 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic,
l->SetEnd( aGraphic->GetStart() );
l->SetLocalCoord();
m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_MODEDIT );
m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_CHANGED );
m_board->m_Modules->SetLastEditTime();
m_board->m_Modules->GraphicalItems().PushFront( l );
@ -1032,10 +1028,6 @@ int DRAWING_TOOL::drawZone( bool aKeepout )
DRAWSEGMENT line45;
DRAWSEGMENT* helperLine = NULL; // we will need more than one helper line
// if one day it is possible to draw zones in the footprint editor,
// then hereby I'm letting you know that this tool does not handle UR_MODEDIT undo yet
assert( !m_editModules );
// Add a VIEW_GROUP that serves as a preview for the new item
KIGFX::VIEW_GROUP preview( m_view );
m_view->Add( &preview );
@ -1334,7 +1326,7 @@ int DRAWING_TOOL::placeTextModule()
text->ClearFlags();
// Module has to be saved before any modification is made
m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_MODEDIT );
m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_CHANGED );
m_board->m_Modules->SetLastEditTime();
m_board->m_Modules->GraphicalItems().PushFront( text );

View File

@ -715,7 +715,7 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
// we have a selection to work on now, so start the tool process
PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
editFrame->OnModify();
// prevent other tools making undo points while the duplicate is going on
@ -723,8 +723,9 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
// the original
incUndoInhibit();
// TODO remove the following when undo buffer handles UR_NEW
if( m_editModules )
editFrame->SaveCopyInUndoList( editFrame->GetBoard()->m_Modules, UR_MODEDIT );
editFrame->SaveCopyInUndoList( editFrame->GetBoard()->m_Modules, UR_CHANGED );
std::vector<BOARD_ITEM*> old_items;
@ -776,6 +777,7 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
}
// record the new items as added
// TODO remove m_editModules condition when undo buffer handles UR_NEW)
if( !m_editModules && !selection.Empty() )
{
editFrame->SaveCopyInUndoList( selection.items, UR_NEW );
@ -1007,9 +1009,6 @@ void EDIT_TOOL::processPickedList( const PICKED_ITEMS_LIST* aList )
{
case UR_CHANGED:
ratsnest->Update( updItem );
// fall through
case UR_MODEDIT:
updItem->ViewUpdate( KIGFX::VIEW_ITEM::ALL );
break;

View File

@ -158,7 +158,7 @@ int MODULE_TOOLS::PlacePad( const TOOL_EVENT& aEvent )
else if( evt->IsClick( BUT_LEFT ) )
{
m_frame->OnModify();
m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_MODEDIT );
m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_CHANGED );
m_board->m_Status_Pcb = 0; // I have no clue why, but it is done in the legacy view
pad->SetParent( m_board->m_Modules );
@ -308,7 +308,7 @@ int MODULE_TOOLS::EnumeratePads( const TOOL_EVENT& aEvent )
{
// Accept changes
m_frame->OnModify();
m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_MODEDIT );
m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_CHANGED );
for( D_PAD* pad : pads )
{
@ -476,7 +476,7 @@ int MODULE_TOOLS::PasteItems( const TOOL_EVENT& aEvent )
else if( evt->IsClick( BUT_LEFT ) )
{
m_frame->OnModify();
m_frame->SaveCopyInUndoList( currentModule, UR_MODEDIT );
m_frame->SaveCopyInUndoList( currentModule, UR_CHANGED );
m_board->m_Status_Pcb = 0; // I have no clue why, but it is done in the legacy view
currentModule->SetLastEditTime();

View File

@ -768,10 +768,6 @@ void POINT_EDITOR::addCorner( const VECTOR2I& aBreakPoint )
PCB_BASE_FRAME* frame = getEditFrame<PCB_BASE_FRAME>();
frame->OnModify();
if( moduleEdge )
frame->SaveCopyInUndoList( getModel<BOARD>()->m_Modules, UR_MODEDIT );
else
frame->SaveCopyInUndoList( selection.items, UR_CHANGED );
DRAWSEGMENT* segment = static_cast<DRAWSEGMENT*>( item );

View File

@ -3,7 +3,9 @@
*
* Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2016 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -165,166 +167,42 @@ static bool TestForExistingItem( BOARD* aPcb, BOARD_ITEM* aItem )
}
void BOARD_ITEM::SwapData( BOARD_ITEM* aImage )
{
if( aImage == NULL )
return;
// Remark: to create images of edited items to undo, we are using Clone method
// which can duplication of items foe copy, but does not clone all members
// mainly pointers in chain and time stamp, which is set to new, unique value.
// So we have to use the current values of these parameters.
EDA_ITEM * pnext = Next();
EDA_ITEM * pback = Back();
DHEAD* mylist = m_List;
time_t timestamp = GetTimeStamp();
switch( Type() )
{
case PCB_MODULE_T:
std::swap( *((MODULE*) this), *((MODULE*) aImage) );
break;
case PCB_ZONE_AREA_T:
std::swap( *((ZONE_CONTAINER*) this), *((ZONE_CONTAINER*) aImage) );
break;
case PCB_LINE_T:
std::swap( *((DRAWSEGMENT*) this), *((DRAWSEGMENT*) aImage) );
break;
case PCB_TRACE_T:
std::swap( *((TRACK*) this), *((TRACK*) aImage) );
break;
case PCB_VIA_T:
std::swap( *((VIA*) this), *((VIA*) aImage) );
break;
case PCB_TEXT_T:
std::swap( *((TEXTE_PCB*) this), *((TEXTE_PCB*) aImage) );
break;
case PCB_TARGET_T:
std::swap( *((PCB_TARGET*) this), *((PCB_TARGET*) aImage) );
break;
case PCB_DIMENSION_T:
std::swap( *((DIMENSION*) this), *((DIMENSION*) aImage) );
break;
case PCB_ZONE_T:
default:
wxLogMessage( wxT( "SwapData() error: unexpected type %d" ), Type() );
break;
}
// Restore pointers and time stamp, to be sure they are not broken
Pnext = pnext;
Pback = pback;
m_List = mylist;
SetTimeStamp( timestamp );
}
void PCB_EDIT_FRAME::SaveCopyInUndoList( BOARD_ITEM* aItem,
UNDO_REDO_T aCommandType,
void PCB_BASE_EDIT_FRAME::SaveCopyInUndoList( BOARD_ITEM* aItem, UNDO_REDO_T aCommandType,
const wxPoint& aTransformPoint )
{
if( aItem == NULL ) // Nothing to save
return;
// For texts belonging to modules, we need to save state of the parent module
if( aItem->Type() == PCB_MODULE_TEXT_T )
{
aItem = aItem->GetParent();
wxASSERT( aItem->Type() == PCB_MODULE_T );
aCommandType = UR_CHANGED;
if( aItem == NULL )
return;
}
PICKED_ITEMS_LIST* commandToUndo = new PICKED_ITEMS_LIST();
commandToUndo->m_TransformPoint = aTransformPoint;
ITEM_PICKER itemWrapper( aItem, aCommandType );
switch( aCommandType )
{
case UR_CHANGED: // Create a copy of item
if( itemWrapper.GetLink() == NULL ) // When not null, the copy is already done
itemWrapper.SetLink( aItem->Clone() );
commandToUndo->PushItem( itemWrapper );
break;
case UR_NEW:
case UR_DELETED:
#ifdef USE_WX_OVERLAY
// Avoid to redraw when autoplacing
if( aItem->Type() == PCB_MODULE_T )
if( ((MODULE*)aItem)->GetFlags() & MODULE_to_PLACE )
break;
m_canvas->Refresh();
#endif
case UR_MOVED:
case UR_FLIPPED:
case UR_ROTATED:
case UR_ROTATED_CLOCKWISE:
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;
}
PICKED_ITEMS_LIST commandToUndo;
commandToUndo.PushItem( ITEM_PICKER( aItem, aCommandType ) );
SaveCopyInUndoList( commandToUndo, aCommandType, aTransformPoint );
}
void PCB_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
UNDO_REDO_T aTypeCommand,
const wxPoint& aTransformPoint )
void PCB_BASE_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
UNDO_REDO_T aTypeCommand, const wxPoint& aTransformPoint )
{
PICKED_ITEMS_LIST* commandToUndo = new PICKED_ITEMS_LIST();
commandToUndo->m_TransformPoint = aTransformPoint;
// First, filter unnecessary stuff from the list (i.e. for multiple pads / labels modified),
// take the first occurence of the module.
// take the first occurence of the module (we save copies of modules when one of its subitems
// is changed).
for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
{
ITEM_PICKER picker = aItemsList.GetItemWrapper(ii);
BOARD_ITEM* item = (BOARD_ITEM*) aItemsList.GetPickedItem( ii );
// For texts belonging to modules, we need to save state of the parent module
if( item->Type() == PCB_MODULE_TEXT_T || item->Type() == PCB_PAD_T )
// For items belonging to modules, we need to save state of the parent module
if( item->Type() == PCB_MODULE_TEXT_T || item->Type() == PCB_MODULE_EDGE_T
|| item->Type() == PCB_PAD_T )
{
// Item to be stored in the undo buffer is the parent module
item = item->GetParent();
wxASSERT( item->Type() == PCB_MODULE_T );
wxASSERT( item && item->Type() == PCB_MODULE_T );
if( item == NULL )
continue;
// Check if the parent module has already been saved in another entry
bool found = false;
for( unsigned j = 0; j < commandToUndo->GetCount(); j++ )
@ -337,11 +215,32 @@ void PCB_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
}
if( !found )
commandToUndo->PushItem( ITEM_PICKER( item, UR_CHANGED ) );
{
// Create a clean copy of the parent module
MODULE* clone = new MODULE( *static_cast<MODULE*>( item ) );
clone->SetParent( GetBoard() );
// Clear current flags (which can be temporary set by a current edit command)
for( EDA_ITEM* item = clone->GraphicalItems(); item; item = item->Next() )
item->ClearFlags();
for( D_PAD* pad = clone->Pads(); pad; pad = pad->Next() )
pad->ClearFlags();
clone->Reference().ClearFlags();
clone->Value().ClearFlags();
ITEM_PICKER picker( item, UR_CHANGED );
picker.SetLink( clone );
commandToUndo->PushItem( picker );
}
else
{
continue;
}
} else {
// Normal case: all other BOARD_ITEMs, are simply copied to the new list
commandToUndo->PushItem( picker );
}
}
@ -388,7 +287,6 @@ void PCB_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
msg.Printf( wxT( "SaveCopyInUndoList() error (unknown code %X)" ), command );
wxMessageBox( msg );
}
break;
}
@ -402,14 +300,70 @@ void PCB_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
/* Clear redo list, because after a new command one cannot redo a command */
GetScreen()->ClearUndoORRedoList( GetScreen()->m_RedoList );
}
else // Should not occur
else
{
// Should not occur
wxASSERT( false );
delete commandToUndo;
}
}
void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRedoCommand,
void PCB_BASE_EDIT_FRAME::RestoreCopyFromUndoList( wxCommandEvent& aEvent )
{
if( UndoRedoBlocked() )
return;
if( GetScreen()->GetUndoCommandCount() <= 0 )
return;
// Inform tools that undo command was issued
TOOL_EVENT event( TC_MESSAGE, TA_UNDO_REDO, AS_GLOBAL );
m_toolManager->ProcessEvent( event );
// Get the old list
PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromUndoList();
// Undo the command
PutDataInPreviousState( List, false );
// Put the old list in RedoList
List->ReversePickersListOrder();
GetScreen()->PushCommandToRedoList( List );
OnModify();
m_canvas->Refresh();
}
void PCB_BASE_EDIT_FRAME::RestoreCopyFromRedoList( wxCommandEvent& aEvent )
{
if( UndoRedoBlocked() )
return;
if( GetScreen()->GetRedoCommandCount() == 0 )
return;
// Inform tools that redo command was issued
TOOL_EVENT event( TC_MESSAGE, TA_UNDO_REDO, AS_GLOBAL );
m_toolManager->ProcessEvent( event );
// Get the old list
PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromRedoList();
// Redo the command
PutDataInPreviousState( List, true );
// Put the old list in UndoList
List->ReversePickersListOrder();
GetScreen()->PushCommandToUndoList( List );
OnModify();
m_canvas->Refresh();
}
void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRedoCommand,
bool aRebuildRatsnet )
{
BOARD_ITEM* item;
@ -449,6 +403,9 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
if( !TestForExistingItem( GetBoard(), item ) )
{
// Checking if it ever happens
wxASSERT_MSG( false, "Item in the undo buffer does not exist" );
// Remove this non existent item
aList->RemovePicker( ii );
ii++; // the current item was removed, ii points now the next item
@ -479,6 +436,9 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
break;
}
// It is possible that we are going to replace the selected item, so clear it
SetCurItem( NULL );
switch( aList->GetPickedItemStatus( ii ) )
{
case UR_CHANGED: /* Exchange old and new data for each item */
@ -516,7 +476,7 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
case UR_NEW: /* new items are deleted */
aList->SetPickedItemStatus( UR_DELETED, ii );
GetBoard()->Remove( item );
GetModel()->Remove( item );
if( item->Type() == PCB_MODULE_T )
{
@ -530,7 +490,7 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
case UR_DELETED: /* deleted items are put in List, as new items */
aList->SetPickedItemStatus( UR_NEW, ii );
GetBoard()->Add( item );
GetModel()->Add( item );
if( item->Type() == PCB_MODULE_T )
{
@ -600,56 +560,70 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
}
void PCB_EDIT_FRAME::RestoreCopyFromUndoList( wxCommandEvent& aEvent )
void BOARD_ITEM::SwapData( BOARD_ITEM* aImage )
{
if( UndoRedoBlocked() )
if( aImage == NULL )
return;
if( GetScreen()->GetUndoCommandCount() <= 0 )
return;
wxASSERT( Type() == aImage->Type() );
// Inform tools that undo command was issued
TOOL_EVENT event( TC_MESSAGE, TA_UNDO_REDO, AS_GLOBAL );
m_toolManager->ProcessEvent( event );
// Remark: to create images of edited items to undo, we are using Clone method
// which can duplication of items foe copy, but does not clone all members
// mainly pointers in chain and time stamp, which is set to new, unique value.
// So we have to use the current values of these parameters.
/* Get the old list */
PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromUndoList();
/* Undo the command */
PutDataInPreviousState( List, false );
EDA_ITEM* pnext = Next();
EDA_ITEM* pback = Back();
DHEAD* mylist = m_List;
time_t timestamp = GetTimeStamp();
EDA_ITEM* parent = GetParent();
/* Put the old list in RedoList */
List->ReversePickersListOrder();
GetScreen()->PushCommandToRedoList( List );
switch( Type() )
{
case PCB_MODULE_T:
std::swap( *((MODULE*) this), *((MODULE*) aImage) );
break;
OnModify();
m_canvas->Refresh();
case PCB_ZONE_AREA_T:
std::swap( *((ZONE_CONTAINER*) this), *((ZONE_CONTAINER*) aImage) );
break;
case PCB_LINE_T:
std::swap( *((DRAWSEGMENT*) this), *((DRAWSEGMENT*) aImage) );
break;
case PCB_TRACE_T:
std::swap( *((TRACK*) this), *((TRACK*) aImage) );
break;
case PCB_VIA_T:
std::swap( *((VIA*) this), *((VIA*) aImage) );
break;
case PCB_TEXT_T:
std::swap( *((TEXTE_PCB*)this), *((TEXTE_PCB*)aImage) );
break;
case PCB_TARGET_T:
std::swap( *((PCB_TARGET*)this), *((PCB_TARGET*)aImage) );
break;
case PCB_DIMENSION_T:
std::swap( *((DIMENSION*)this), *((DIMENSION*)aImage) );
break;
case PCB_ZONE_T:
default:
wxLogMessage( wxT( "SwapData() error: unexpected type %d" ), Type() );
break;
}
void PCB_EDIT_FRAME::RestoreCopyFromRedoList( wxCommandEvent& aEvent )
{
if( UndoRedoBlocked() )
return;
if( GetScreen()->GetRedoCommandCount() == 0 )
return;
// Inform tools that redo command was issued
TOOL_EVENT event( TC_MESSAGE, TA_UNDO_REDO, AS_GLOBAL );
m_toolManager->ProcessEvent( event );
/* Get the old list */
PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromRedoList();
/* Redo the command: */
PutDataInPreviousState( List, true );
/* Put the old list in UndoList */
List->ReversePickersListOrder();
GetScreen()->PushCommandToUndoList( List );
OnModify();
m_canvas->Refresh();
// Restore pointers and time stamp, to be sure they are not broken
Pnext = pnext;
Pback = pback;
m_List = mylist;
SetTimeStamp( timestamp );
SetParent( parent );
}
@ -675,3 +649,4 @@ void PCB_SCREEN::ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount
delete curr_cmd; // Delete command
}
}