diff --git a/common/class_undoredo_container.cpp b/common/class_undoredo_container.cpp index 9c71d1ad2d..ada087480e 100644 --- a/common/class_undoredo_container.cpp +++ b/common/class_undoredo_container.cpp @@ -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; diff --git a/include/class_undoredo_container.h b/include/class_undoredo_container.h index 13c9e85b23..ce54b45a8b 100644 --- a/include/class_undoredo_container.h +++ b/include/class_undoredo_container.h @@ -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 diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index 270643d3e1..4463c40664 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -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: */ /** diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index c4aff5177a..21380aaecb 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -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 diff --git a/pcbnew/array_creator.cpp b/pcbnew/array_creator.cpp index 537abea823..4567579751 100644 --- a/pcbnew/array_creator.cpp +++ b/pcbnew/array_creator.cpp @@ -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 ) diff --git a/pcbnew/block_module_editor.cpp b/pcbnew/block_module_editor.cpp index 1a635e972f..d1ff77b44f 100644 --- a/pcbnew/block_module_editor.cpp +++ b/pcbnew/block_module_editor.cpp @@ -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; diff --git a/pcbnew/dialogs/dialog_edit_module_for_Modedit.cpp b/pcbnew/dialogs/dialog_edit_module_for_Modedit.cpp index a087650fa2..0d1fe110a8 100644 --- a/pcbnew/dialogs/dialog_edit_module_for_Modedit.cpp +++ b/pcbnew/dialogs/dialog_edit_module_for_Modedit.cpp @@ -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() ) diff --git a/pcbnew/dialogs/dialog_graphic_item_properties_for_Modedit.cpp b/pcbnew/dialogs/dialog_graphic_item_properties_for_Modedit.cpp index 17106f65ce..27dc569d7b 100644 --- a/pcbnew/dialogs/dialog_graphic_item_properties_for_Modedit.cpp +++ b/pcbnew/dialogs/dialog_graphic_item_properties_for_Modedit.cpp @@ -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; diff --git a/pcbnew/edgemod.cpp b/pcbnew/edgemod.cpp index 5dc01b5581..f24dc07b99 100644 --- a/pcbnew/edgemod.cpp +++ b/pcbnew/edgemod.cpp @@ -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; diff --git a/pcbnew/edtxtmod.cpp b/pcbnew/edtxtmod.cpp index 733183f96d..07372bf50e 100644 --- a/pcbnew/edtxtmod.cpp +++ b/pcbnew/edtxtmod.cpp @@ -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 ); diff --git a/pcbnew/import_dxf/dialog_dxf_import.cpp b/pcbnew/import_dxf/dialog_dxf_import.cpp index 76d84c4d83..2501d1be48 100644 --- a/pcbnew/import_dxf/dialog_dxf_import.cpp +++ b/pcbnew/import_dxf/dialog_dxf_import.cpp @@ -245,7 +245,7 @@ bool InvokeDXFDialogModuleImport( PCB_BASE_FRAME* aCaller, MODULE* aModule ) { const std::list& list = dlg.GetImportedItems(); - aCaller->SaveCopyInUndoList( aModule, UR_MODEDIT ); + aCaller->SaveCopyInUndoList( aModule, UR_CHANGED ); aCaller->OnModify(); std::list::const_iterator it, itEnd; diff --git a/pcbnew/modedit.cpp b/pcbnew/modedit.cpp index cf0d77ee25..5a53fa1faf 100644 --- a/pcbnew/modedit.cpp +++ b/pcbnew/modedit.cpp @@ -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( 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(); diff --git a/pcbnew/modedit_onclick.cpp b/pcbnew/modedit_onclick.cpp index 6df77a19e9..97c1c090a5 100644 --- a/pcbnew/modedit_onclick.cpp +++ b/pcbnew/modedit_onclick.cpp @@ -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( 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 ); } diff --git a/pcbnew/modedit_undo_redo.cpp b/pcbnew/modedit_undo_redo.cpp deleted file mode 100644 index 08b8674fdd..0000000000 --- a/pcbnew/modedit_undo_redo.cpp +++ /dev/null @@ -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 -using namespace std::placeholders; - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - - -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( 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(); -} diff --git a/pcbnew/module_editor_frame.h b/pcbnew/module_editor_frame.h index 83ffbade0c..fb1a7ac799 100644 --- a/pcbnew/module_editor_frame.h +++ b/pcbnew/module_editor_frame.h @@ -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; diff --git a/pcbnew/pcb_base_edit_frame.h b/pcbnew/pcb_base_edit_frame.h index 3890bb9fc9..7fb313b5fa 100644 --- a/pcbnew/pcb_base_edit_frame.h +++ b/pcbnew/pcb_base_edit_frame.h @@ -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 ); diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 9724c209b5..5153f42b9b 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -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 ) diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index c4ecdc9b0d..c17b9e8849 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -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 ); diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 9d3b7dde1b..7104de6bc6 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -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_EDIT_FRAME* editFrame = getEditFrame(); 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 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; diff --git a/pcbnew/tools/module_tools.cpp b/pcbnew/tools/module_tools.cpp index 2e5ae48c8f..8ca9030783 100644 --- a/pcbnew/tools/module_tools.cpp +++ b/pcbnew/tools/module_tools.cpp @@ -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(); diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index 98d866c0e0..3ea20883d1 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -768,11 +768,7 @@ void POINT_EDITOR::addCorner( const VECTOR2I& aBreakPoint ) PCB_BASE_FRAME* frame = getEditFrame(); frame->OnModify(); - - if( moduleEdge ) - frame->SaveCopyInUndoList( getModel()->m_Modules, UR_MODEDIT ); - else - frame->SaveCopyInUndoList( selection.items, UR_CHANGED ); + frame->SaveCopyInUndoList( selection.items, UR_CHANGED ); DRAWSEGMENT* segment = static_cast( item ); diff --git a/pcbnew/board_undo_redo.cpp b/pcbnew/undo_redo.cpp similarity index 84% rename from pcbnew/board_undo_redo.cpp rename to pcbnew/undo_redo.cpp index 3a8ad90482..3b90c7c88c 100644 --- a/pcbnew/board_undo_redo.cpp +++ b/pcbnew/undo_redo.cpp @@ -3,7 +3,9 @@ * * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck - * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2016 CERN + * @author Maciej Suminski + * 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 ) +void PCB_BASE_EDIT_FRAME::SaveCopyInUndoList( BOARD_ITEM* aItem, UNDO_REDO_T aCommandType, + const wxPoint& aTransformPoint ) { - 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 ); + PICKED_ITEMS_LIST commandToUndo; + commandToUndo.PushItem( ITEM_PICKER( aItem, aCommandType ) ); + SaveCopyInUndoList( commandToUndo, aCommandType, aTransformPoint ); } -void PCB_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; - } -} - - -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( 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; -void PCB_EDIT_FRAME::RestoreCopyFromRedoList( wxCommandEvent& aEvent ) -{ - if( UndoRedoBlocked() ) - return; + case PCB_TRACE_T: + std::swap( *((TRACK*) this), *((TRACK*) aImage) ); + break; - if( GetScreen()->GetRedoCommandCount() == 0 ) - return; + case PCB_VIA_T: + std::swap( *((VIA*) this), *((VIA*) aImage) ); + break; - // Inform tools that redo command was issued - TOOL_EVENT event( TC_MESSAGE, TA_UNDO_REDO, AS_GLOBAL ); - m_toolManager->ProcessEvent( event ); + case PCB_TEXT_T: + std::swap( *((TEXTE_PCB*)this), *((TEXTE_PCB*)aImage) ); + break; - /* Get the old list */ - PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromRedoList(); + case PCB_TARGET_T: + std::swap( *((PCB_TARGET*)this), *((PCB_TARGET*)aImage) ); + break; - /* Redo the command: */ - PutDataInPreviousState( List, true ); + case PCB_DIMENSION_T: + std::swap( *((DIMENSION*)this), *((DIMENSION*)aImage) ); + break; - /* Put the old list in UndoList */ - List->ReversePickersListOrder(); - GetScreen()->PushCommandToUndoList( List ); + case PCB_ZONE_T: + default: + wxLogMessage( wxT( "SwapData() error: unexpected type %d" ), Type() ); + break; + } - 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 } } +