1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2013 CERN
5  * Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
6  * @author Jean-Pierre Charras, jp.charras at wanadoo.fr
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
24  */
25 
26 #include <drawing_sheet/ds_data_model.h>
27 #include <drawing_sheet/ds_proxy_undo_item.h>
28 #include <tool/tool_manager.h>
29 #include <tool/actions.h>
30 
31 #include "pl_editor_frame.h"
32 #include "tools/pl_selection_tool.h"
33 
SaveCopyInUndoList()34 void PL_EDITOR_FRAME::SaveCopyInUndoList()
35 {
36     PICKED_ITEMS_LIST*  lastcmd = new PICKED_ITEMS_LIST();
37     DS_PROXY_UNDO_ITEM* copyItem = new DS_PROXY_UNDO_ITEM( this );
38     ITEM_PICKER         wrapper( GetScreen(), copyItem, UNDO_REDO::LIBEDIT );
39 
40     lastcmd->PushItem( wrapper );
41     PushCommandToUndoList( lastcmd );
42 
43     // Clear redo list, because after new save there is no redo to do.
44     ClearUndoORRedoList( REDO_LIST );
45 }
46 
47 
48 /* Redo the last edit:
49  * - Place the current edited layout in undo list
50  * - Get previous version of the current edited layput
51  */
GetLayoutFromRedoList()52 void PL_EDITOR_FRAME::GetLayoutFromRedoList()
53 {
54     PL_SELECTION_TOOL*  selTool = GetToolManager()->GetTool<PL_SELECTION_TOOL>();
55 
56     if ( GetRedoCommandCount() <= 0 )
57         return;
58 
59     ITEM_PICKER         redoWrapper = PopCommandFromRedoList()->PopItem();
60     DS_PROXY_UNDO_ITEM* redoItem = static_cast<DS_PROXY_UNDO_ITEM*>( redoWrapper.GetItem() );
61     bool                pageSettingsAndTitleBlock = redoItem->Type() == WS_PROXY_UNDO_ITEM_PLUS_T;
62 
63     PICKED_ITEMS_LIST*  undoCmd = new PICKED_ITEMS_LIST();
64     DS_PROXY_UNDO_ITEM* undoItem = new DS_PROXY_UNDO_ITEM( pageSettingsAndTitleBlock ? this : nullptr );
65     ITEM_PICKER         undoWrapper( GetScreen(), undoItem );
66 
67     undoCmd->PushItem( undoWrapper );
68     PushCommandToUndoList( undoCmd );
69 
70     selTool->ClearSelection();
71     redoItem->Restore( this, GetCanvas()->GetView() );
72     selTool->RebuildSelection();
73 
74     delete redoItem;
75 
76     if( pageSettingsAndTitleBlock )
77         HardRedraw();   // items based off of corners will need re-calculating
78     else
79         GetCanvas()->Refresh();
80 
81     OnModify();
82 }
83 
84 
85 /* Undo the last edit:
86  * - Place the current layout in Redo list
87  * - Get previous version of the current edited layout
88  */
GetLayoutFromUndoList()89 void PL_EDITOR_FRAME::GetLayoutFromUndoList()
90 {
91     PL_SELECTION_TOOL*  selTool = GetToolManager()->GetTool<PL_SELECTION_TOOL>();
92 
93     if ( GetUndoCommandCount() <= 0 )
94         return;
95 
96     ITEM_PICKER         undoWrapper = PopCommandFromUndoList()->PopItem();
97     DS_PROXY_UNDO_ITEM* undoItem = static_cast<DS_PROXY_UNDO_ITEM*>( undoWrapper.GetItem() );
98     bool                pageSettingsAndTitleBlock = undoItem->Type() == WS_PROXY_UNDO_ITEM_PLUS_T;
99 
100     PICKED_ITEMS_LIST*  redoCmd = new PICKED_ITEMS_LIST();
101     DS_PROXY_UNDO_ITEM* redoItem = new DS_PROXY_UNDO_ITEM( pageSettingsAndTitleBlock ? this : nullptr );
102     ITEM_PICKER         redoWrapper( GetScreen(), redoItem );
103 
104     redoCmd->PushItem( redoWrapper );
105     PushCommandToRedoList( redoCmd );
106 
107     selTool->ClearSelection();
108     undoItem->Restore( this, GetCanvas()->GetView() );
109     selTool->RebuildSelection();
110 
111     delete undoItem;
112 
113     if( pageSettingsAndTitleBlock )
114         HardRedraw();   // items based off of corners will need re-calculating
115     else
116         GetCanvas()->Refresh();
117 
118     OnModify();
119 }
120 
121 
122 /* Remove the last command in Undo List.
123  * Used to clean the uUndo stack after a cancel command
124  */
RollbackFromUndo()125 void PL_EDITOR_FRAME::RollbackFromUndo()
126 {
127     PL_SELECTION_TOOL*  selTool = GetToolManager()->GetTool<PL_SELECTION_TOOL>();
128 
129     if ( GetUndoCommandCount() <= 0 )
130         return;
131 
132     ITEM_PICKER         undoWrapper = PopCommandFromUndoList()->PopItem();
133     DS_PROXY_UNDO_ITEM* undoItem = static_cast<DS_PROXY_UNDO_ITEM*>( undoWrapper.GetItem() );
134     bool                pageSettingsAndTitleBlock = undoItem->Type() == WS_PROXY_UNDO_ITEM_PLUS_T;
135 
136     selTool->ClearSelection();
137     undoItem->Restore( this, GetCanvas()->GetView() );
138     selTool->RebuildSelection();
139 
140     delete undoItem;
141 
142     if( pageSettingsAndTitleBlock )
143     {
144         GetToolManager()->RunAction( ACTIONS::zoomFitScreen, true );
145         HardRedraw();   // items based off of corners will need re-calculating
146     }
147     else
148         GetCanvas()->Refresh();
149 }
150