1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2007 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2014-2021 KiCad Developers, see AUTHORS.TXT for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
23  */
24 
25 #include <symbol_edit_frame.h>
26 #include <symbol_library_manager.h>
27 #include <widgets/lib_tree.h>
28 #include <symbol_tree_pane.h>
29 #include <tool/tool_manager.h>
30 #include <tools/ee_actions.h>
31 #include <tools/ee_selection_tool.h>
32 
SaveCopyInUndoList(EDA_ITEM * aItem,UNDO_REDO aUndoType,bool aAppend)33 void SYMBOL_EDIT_FRAME::SaveCopyInUndoList( EDA_ITEM* aItem, UNDO_REDO aUndoType, bool aAppend )
34 {
35     wxASSERT_MSG( !aAppend, "Append not needed/supported for symbol editor" );
36 
37     if( !aItem )
38         return;
39 
40     LIB_SYMBOL*        copyItem;
41     PICKED_ITEMS_LIST* lastcmd = new PICKED_ITEMS_LIST();
42 
43     copyItem = new LIB_SYMBOL( * (LIB_SYMBOL*) aItem );
44 
45     // Clear current flags (which can be temporary set by a current edit command).
46     copyItem->ClearTempFlags();
47     copyItem->ClearEditFlags();
48     copyItem->SetFlags( UR_TRANSIENT );
49 
50     ITEM_PICKER wrapper( GetScreen(), copyItem, aUndoType );
51     lastcmd->PushItem( wrapper );
52     PushCommandToUndoList( lastcmd );
53 
54     // Clear redo list, because after new save there is no redo to do.
55     ClearUndoORRedoList( REDO_LIST );
56 }
57 
58 
GetSymbolFromRedoList()59 void SYMBOL_EDIT_FRAME::GetSymbolFromRedoList()
60 {
61     if( GetRedoCommandCount() <= 0 )
62         return;
63 
64     m_toolManager->RunAction( EE_ACTIONS::clearSelection, true );
65 
66     // Load the last redo entry
67     PICKED_ITEMS_LIST* redoCommand = PopCommandFromRedoList();
68     ITEM_PICKER redoWrapper = redoCommand->PopItem();
69     delete redoCommand;
70     LIB_SYMBOL* symbol = (LIB_SYMBOL*) redoWrapper.GetItem();
71     wxCHECK( symbol, /* void */ );
72     symbol->ClearFlags( UR_TRANSIENT );
73     UNDO_REDO undoRedoType = redoWrapper.GetStatus();
74 
75     // Store the current symbol in the undo buffer
76     PICKED_ITEMS_LIST* undoCommand = new PICKED_ITEMS_LIST();
77     LIB_SYMBOL* oldSymbol = m_symbol;
78     oldSymbol->SetFlags( UR_TRANSIENT );
79     ITEM_PICKER undoWrapper( GetScreen(), oldSymbol, undoRedoType );
80     undoCommand->PushItem( undoWrapper );
81     PushCommandToUndoList( undoCommand );
82 
83     // Do not delete the previous symbol by calling SetCurSymbol( symbol )
84     // which calls delete <previous symbol>.
85     // <previous symbol> is now put in undo list and is owned by this list
86     // Just set the current symbol to the symbol which come from the redo list
87     m_symbol = symbol;
88 
89     if( undoRedoType == UNDO_REDO::LIB_RENAME )
90     {
91         wxString lib = GetCurLib();
92         m_libMgr->UpdateSymbolAfterRename( symbol, oldSymbol->GetName(), lib );
93 
94         // Reselect the renamed symbol
95         m_treePane->GetLibTree()->SelectLibId( LIB_ID( lib, symbol->GetName() ) );
96     }
97 
98     RebuildSymbolUnitsList();
99     SetShowDeMorgan( symbol->HasConversion() );
100     updateTitle();
101 
102     RebuildView();
103     OnModify();
104 }
105 
106 
GetSymbolFromUndoList()107 void SYMBOL_EDIT_FRAME::GetSymbolFromUndoList()
108 {
109     if( GetUndoCommandCount() <= 0 )
110         return;
111 
112     m_toolManager->RunAction( EE_ACTIONS::clearSelection, true );
113 
114     // Load the last undo entry
115     PICKED_ITEMS_LIST* undoCommand = PopCommandFromUndoList();
116     ITEM_PICKER undoWrapper = undoCommand->PopItem();
117     delete undoCommand;
118     LIB_SYMBOL* symbol = (LIB_SYMBOL*) undoWrapper.GetItem();
119     wxCHECK( symbol, /* void */ );
120     symbol->ClearFlags( UR_TRANSIENT );
121     UNDO_REDO undoRedoType = undoWrapper.GetStatus();
122 
123     // Store the current symbol in the redo buffer
124     PICKED_ITEMS_LIST* redoCommand = new PICKED_ITEMS_LIST();
125     LIB_SYMBOL* oldSymbol = m_symbol;
126     oldSymbol->SetFlags( UR_TRANSIENT );
127     ITEM_PICKER redoWrapper( GetScreen(), oldSymbol, undoRedoType );
128     redoCommand->PushItem( redoWrapper );
129     PushCommandToRedoList( redoCommand );
130 
131     // Do not delete the previous symbol by calling SetCurSymbol( symbol ),
132     // which calls delete <previous symbol>.
133     // <previous symbol> is now put in redo list and is owned by this list.
134     // Just set the current symbol to the symbol which come from the undo list
135     m_symbol = symbol;
136 
137     if( undoRedoType == UNDO_REDO::LIB_RENAME )
138     {
139         wxString lib = GetCurLib();
140         m_libMgr->UpdateSymbolAfterRename( symbol, oldSymbol->GetName(), lib );
141 
142         // Reselect the renamed symbol
143         m_treePane->GetLibTree()->SelectLibId( LIB_ID( lib, symbol->GetName() ) );
144     }
145 
146     RebuildSymbolUnitsList();
147     SetShowDeMorgan( symbol->HasConversion() );
148     updateTitle();
149 
150     RebuildView();
151     OnModify();
152 }
153 
154 
RollbackSymbolFromUndo()155 void SYMBOL_EDIT_FRAME::RollbackSymbolFromUndo()
156 {
157     m_toolManager->RunAction( EE_ACTIONS::clearSelection, true );
158 
159     // Load the last undo entry
160     PICKED_ITEMS_LIST* undoCommand = PopCommandFromUndoList();
161 
162     // Check if we were already at the top of the stack
163     if( !undoCommand )
164         return;
165 
166     ITEM_PICKER undoWrapper = undoCommand->PopItem();
167     delete undoCommand;
168     LIB_SYMBOL* symbol = (LIB_SYMBOL*) undoWrapper.GetItem();
169     symbol->ClearFlags( UR_TRANSIENT );
170     SetCurSymbol( symbol, false );
171 
172     EE_SELECTION_TOOL* selTool = m_toolManager->GetTool<EE_SELECTION_TOOL>();
173     selTool->RebuildSelection();
174 
175     RebuildSymbolUnitsList();
176     SetShowDeMorgan( symbol->HasConversion() );
177 
178     RebuildView();
179 }
180