From 0b16a376754d7447a9022f9401e115fd25b0f871 Mon Sep 17 00:00:00 2001 From: Guillaume Simard Date: Tue, 13 Dec 2011 15:42:42 -0500 Subject: [PATCH] Add undo/redo support for Pcbnew auto place, auto move, and auto route features. --- pcbnew/automove.cpp | 18 ++++++++++++++++++ pcbnew/autoplac.cpp | 35 +++++++++++++++++++++++++++++++++++ pcbnew/solve.cpp | 10 ++++++++++ 3 files changed, 63 insertions(+) diff --git a/pcbnew/automove.cpp b/pcbnew/automove.cpp index f43ae9da6b..7fb839335b 100644 --- a/pcbnew/automove.cpp +++ b/pcbnew/automove.cpp @@ -18,6 +18,7 @@ #include "class_board.h" #include "class_module.h" +extern BOARD_ITEM* DuplicateStruct( BOARD_ITEM* aItem ); typedef enum { FIXE_MODULE, @@ -184,6 +185,11 @@ void PCB_EDIT_FRAME::AutoMoveModulesOnPcb( bool PlaceModulesHorsPcb ) int pas_grille = (int) GetScreen()->GetGridSize().x; double surface; + // Undo: init list + PICKED_ITEMS_LIST newList; + newList.m_Status = UR_CHANGED; + ITEM_PICKER picker( NULL, UR_CHANGED ); + if( GetBoard()->m_Modules == NULL ) { DisplayError( this, _( "No modules found!" ) ); @@ -264,6 +270,10 @@ void PCB_EDIT_FRAME::AutoMoveModulesOnPcb( bool PlaceModulesHorsPcb ) continue; } + // Undo: add copy of old Module to undo + picker.m_Link = DuplicateStruct( Module ); + picker.m_PickedItemType = Module->Type(); + if( current.x > (Xsize_allowed + start.x) ) { current.x = start.x; @@ -278,9 +288,17 @@ void PCB_EDIT_FRAME::AutoMoveModulesOnPcb( bool PlaceModulesHorsPcb ) PlaceModule( Module, NULL, true ); + // Undo: add new Module to undo + picker.m_PickedItem = Module; + newList.PushItem( picker ); + current.x += Module->m_BoundaryBox.GetWidth() + pas_grille; } + // Undo: commit + if( newList.GetCount() ) + SaveCopyInUndoList( newList, UR_CHANGED ); + DrawPanel->Refresh(); } diff --git a/pcbnew/autoplac.cpp b/pcbnew/autoplac.cpp index 4cb3c905d9..a941bf054e 100644 --- a/pcbnew/autoplac.cpp +++ b/pcbnew/autoplac.cpp @@ -109,6 +109,11 @@ void PCB_EDIT_FRAME::AutoPlaceModule( MODULE* Module, int place_mode, wxDC* DC ) float Pas; int lay_tmp_TOP, lay_tmp_BOTTOM; + // Undo: init list + PICKED_ITEMS_LIST newList; + newList.m_Status = UR_CHANGED; + ITEM_PICKER picker( NULL, UR_CHANGED ); + if( GetBoard()->m_Modules == NULL ) return; @@ -175,7 +180,14 @@ void PCB_EDIT_FRAME::AutoPlaceModule( MODULE* Module, int place_mode, wxDC* DC ) { case PLACE_1_MODULE: if( ThisModule == Module ) + { + // Module will be placed, add to undo. + picker.m_PickedItem = ThisModule; + picker.m_PickedItemType = ThisModule->Type(); + newList.PushItem( picker ); + Module->m_ModuleStatus |= MODULE_to_PLACE; + } break; @@ -186,7 +198,14 @@ void PCB_EDIT_FRAME::AutoPlaceModule( MODULE* Module, int place_mode, wxDC* DC ) break; if( !bbbox.Contains( Module->m_Pos ) ) + { + // Module will be placed, add to undo. + picker.m_PickedItem = Module; + picker.m_PickedItemType = Module->Type(); + newList.PushItem( picker ); + Module->m_ModuleStatus |= MODULE_to_PLACE; + } break; @@ -196,6 +215,11 @@ void PCB_EDIT_FRAME::AutoPlaceModule( MODULE* Module, int place_mode, wxDC* DC ) if( Module->m_ModuleStatus & MODULE_is_LOCKED ) break; + // Module will be placed, add to undo. + picker.m_PickedItem = Module; + picker.m_PickedItemType = Module->Type(); + newList.PushItem( picker ); + Module->m_ModuleStatus |= MODULE_to_PLACE; break; @@ -207,7 +231,14 @@ void PCB_EDIT_FRAME::AutoPlaceModule( MODULE* Module, int place_mode, wxDC* DC ) } if( !(Module->m_ModuleStatus & MODULE_is_PLACED) ) + { + // Module will be placed, add to undo. + picker.m_PickedItem = Module; + picker.m_PickedItemType = Module->Type(); + newList.PushItem( picker ); + Module->m_ModuleStatus |= MODULE_to_PLACE; + } break; } @@ -224,6 +255,10 @@ void PCB_EDIT_FRAME::AutoPlaceModule( MODULE* Module, int place_mode, wxDC* DC ) } } + // Undo: commit + if( newList.GetCount() ) + SaveCopyInUndoList( newList, UR_CHANGED ); + activ = 0; Pas = 100.0; diff --git a/pcbnew/solve.cpp b/pcbnew/solve.cpp index 7e4e68db4d..0c12dc06b6 100644 --- a/pcbnew/solve.cpp +++ b/pcbnew/solve.cpp @@ -79,6 +79,8 @@ static RATSNEST_ITEM* pt_cur_ch; static int Ncurrent; /* measures of progress */ static int s_Clearance; // Clearance value used in autorouter +static PICKED_ITEMS_LIST s_ItemsListPicker; + #define NOSUCCESS 0 #define STOP_FROM_ESC -1 @@ -272,6 +274,9 @@ int PCB_EDIT_FRAME::Solve( wxDC* DC, int two_sides ) Ncurrent = 0; + // Prepare the undo command info + s_ItemsListPicker.ClearListAndDeleteItems(); // Should not be necessary, but... + /* go until no more work to do */ GetWork( &row_source, &col_source, ¤t_net_code, &row_target, &col_target, &pt_cur_ch ); // First net to route. @@ -375,6 +380,9 @@ int PCB_EDIT_FRAME::Solve( wxDC* DC, int two_sides ) DrawPanel->m_AbortEnable = false; + SaveCopyInUndoList( s_ItemsListPicker, UR_UNSPECIFIED ); + s_ItemsListPicker.ClearItemsList(); // s_ItemsListPicker is no more owner of picked items + return SUCCESS; } @@ -1323,6 +1331,8 @@ static void AddNewTrace( PCB_EDIT_FRAME* pcbframe, wxDC* DC ) while( ( track = g_CurrentTrackList.PopFront() ) != NULL ) { + ITEM_PICKER picker( track, UR_NEW ); + s_ItemsListPicker.PushItem( picker ); pcbframe->GetBoard()->m_Track.Insert( track, insertBeforeMe ); }