KiCad PCB EDA Suite
Loading...
Searching...
No Matches
undo_redo_container.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2018 jp.charras at wanadoo.fr
5 * Copyright (C) 2011 Wayne Stambaugh <[email protected]>
6 * Copyright (C) 2021-2022 KiCad Developers, see AUTHORS.txt for contributors.
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 <eda_item.h>
27#include <undo_redo_container.h>
28
29
31{
32 m_undoRedoStatus = UNDO_REDO::UNSPECIFIED;
33 SetItem( nullptr );
34 m_pickerFlags = 0;
35 m_link = nullptr;
36 m_screen = nullptr;
37}
38
39
40ITEM_PICKER::ITEM_PICKER( BASE_SCREEN* aScreen, EDA_ITEM* aItem, UNDO_REDO aUndoRedoStatus )
41{
42 m_undoRedoStatus = aUndoRedoStatus;
43 SetItem( aItem );
44 m_pickerFlags = 0;
45 m_link = nullptr;
46 m_screen = aScreen;
47}
48
49
51{
52 m_pickedItem = aItem;
53 m_pickedItemType = aItem ? aItem->Type() : TYPE_NOT_INIT;
54}
55
56
58{
59}
60
61
63{
64}
65
66
68{
69 m_ItemsList.push_back( aItem );
70}
71
72
74{
75 ITEM_PICKER item;
76
77 if( m_ItemsList.size() != 0 )
78 {
79 item = m_ItemsList.back();
80 m_ItemsList.pop_back();
81 }
82
83 return item;
84}
85
86
87bool PICKED_ITEMS_LIST::ContainsItem( const EDA_ITEM* aItem ) const
88{
89 for( const ITEM_PICKER& picker : m_ItemsList )
90 {
91 if( picker.GetItem() == aItem )
92 return true;
93 }
94
95 return false;
96}
97
98
99int PICKED_ITEMS_LIST::FindItem( const EDA_ITEM* aItem ) const
100{
101 for( size_t i = 0; i < m_ItemsList.size(); i++ )
102 {
103 if( m_ItemsList[i].GetItem() == aItem )
104 return i;
105 }
106
107 return -1;
108}
109
110
112{
113 m_ItemsList.clear();
114}
115
116
117void PICKED_ITEMS_LIST::ClearListAndDeleteItems( std::function<void(EDA_ITEM*)> aItemDeleter )
118{
119 while( GetCount() > 0 )
120 {
121 ITEM_PICKER wrapper = PopItem();
122
123 if( wrapper.GetItem() == nullptr ) // No more items in list.
124 break;
125
126 // The Link is an undo construct; it is always owned by the undo/redo container
127 if( wrapper.GetLink() )
128 aItemDeleter( wrapper.GetLink() );
129
130 if( wrapper.GetFlags() & UR_TRANSIENT )
131 {
132 aItemDeleter( wrapper.GetItem() );
133 }
134 else if( wrapper.GetStatus() == UNDO_REDO::DELETED )
135 {
136 // This should really be replaced with UR_TRANSIENT, but currently many clients
137 // (eeschema in particular) abuse this to achieve non-undo-related deletions.
138 aItemDeleter( wrapper.GetItem() );
139 }
140 }
141}
142
143
145{
146 ITEM_PICKER picker;
147
148 if( aIdx < m_ItemsList.size() )
149 picker = m_ItemsList[aIdx];
150
151 return picker;
152}
153
154
156{
157 if( aIdx < m_ItemsList.size() )
158 return m_ItemsList[aIdx].GetItem();
159
160 return nullptr;
161}
162
163
165{
166 if( aIdx < m_ItemsList.size() )
167 return m_ItemsList[aIdx].GetScreen();
168
169 return nullptr;
170}
171
172
174{
175 if( aIdx < m_ItemsList.size() )
176 return m_ItemsList[aIdx].GetLink();
177
178 return nullptr;
179}
180
181
183{
184 if( aIdx < m_ItemsList.size() )
185 return m_ItemsList[aIdx].GetStatus();
186
187 return UNDO_REDO::UNSPECIFIED;
188}
189
190
192{
193 if( aIdx < m_ItemsList.size() )
194 return m_ItemsList[aIdx].GetFlags();
195
196 return 0;
197}
198
199
200bool PICKED_ITEMS_LIST::SetPickedItem( EDA_ITEM* aItem, unsigned aIdx )
201{
202 if( aIdx < m_ItemsList.size() )
203 {
204 m_ItemsList[aIdx].SetItem( aItem );
205 return true;
206 }
207
208 return false;
209}
210
211
213{
214 if( aIdx < m_ItemsList.size() )
215 {
216 m_ItemsList[aIdx].SetLink( aLink );
217 return true;
218 }
219
220 return false;
221}
222
223
224bool PICKED_ITEMS_LIST::SetPickedItem( EDA_ITEM* aItem, UNDO_REDO aStatus, unsigned aIdx )
225{
226 if( aIdx < m_ItemsList.size() )
227 {
228 m_ItemsList[aIdx].SetItem( aItem );
229 m_ItemsList[aIdx].SetStatus( aStatus );
230 return true;
231 }
232
233 return false;
234}
235
236
238{
239 if( aIdx < m_ItemsList.size() )
240 {
241 m_ItemsList[aIdx].SetStatus( aStatus );
242 return true;
243 }
244
245 return false;
246}
247
248
250{
251 if( aIdx < m_ItemsList.size() )
252 {
253 m_ItemsList[aIdx].SetFlags( aFlags );
254 return true;
255 }
256
257 return false;
258}
259
260
262{
263 if( aIdx >= m_ItemsList.size() )
264 return false;
265
266 m_ItemsList.erase( m_ItemsList.begin() + aIdx );
267 return true;
268}
269
270
272{
273 m_ItemsList = aSource.m_ItemsList; // Vector's copy
274}
275
276
278{
279 std::vector <ITEM_PICKER> tmp;
280
281 while( !m_ItemsList.empty() )
282 {
283 tmp.push_back( m_ItemsList.back() );
284 m_ItemsList.pop_back();
285 }
286
287 m_ItemsList.swap( tmp );
288}
289
290
292{
293}
294
295
297{
299}
300
301
303{
304 for( unsigned ii = 0; ii < m_CommandsList.size(); ii++ )
305 delete m_CommandsList[ii];
306
307 m_CommandsList.clear();
308}
309
310
312{
313 m_CommandsList.push_back( aItem );
314}
315
316
318{
319 if( m_CommandsList.size() != 0 )
320 {
321 PICKED_ITEMS_LIST* item = m_CommandsList.back();
322 m_CommandsList.pop_back();
323 return item;
324 }
325
326 return nullptr;
327}
Handles how to draw a screen (a board, a schematic ...)
Definition: base_screen.h:41
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:85
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:97
void SetItem(EDA_ITEM *aItem)
BASE_SCREEN * m_screen
EDA_ITEM * GetItem() const
KICAD_T m_pickedItemType
EDA_ITEM * GetLink() const
EDA_ITEM_FLAGS GetFlags() const
EDA_ITEM_FLAGS m_pickerFlags
EDA_ITEM * m_pickedItem
UNDO_REDO m_undoRedoStatus
UNDO_REDO GetStatus() const
A holder to handle information on schematic or board items.
bool SetPickedItemStatus(UNDO_REDO aStatus, unsigned aIdx)
Set the type of undo/redo operation for a given picked item.
EDA_ITEM_FLAGS GetPickerFlags(unsigned aIdx) const
Return the value of the picker flag.
void PushItem(const ITEM_PICKER &aItem)
Push aItem to the top of the list.
int FindItem(const EDA_ITEM *aItem) const
UNDO_REDO GetPickedItemStatus(unsigned int aIdx) const
ITEM_PICKER GetItemWrapper(unsigned int aIdx) const
EDA_ITEM * GetPickedItemLink(unsigned int aIdx) const
std::vector< ITEM_PICKER > m_ItemsList
bool RemovePicker(unsigned aIdx)
Remove one entry (one picker) from the list of picked items.
bool ContainsItem(const EDA_ITEM *aItem) const
unsigned GetCount() const
bool SetPickedItem(EDA_ITEM *aItem, unsigned aIdx)
void CopyList(const PICKED_ITEMS_LIST &aSource)
Copy all data from aSource to the list.
void ReversePickersListOrder()
Reverse the order of pickers stored in this list.
void ClearItemsList()
Delete only the list of pickers NOT the picked data itself.
bool SetPickedItemLink(EDA_ITEM *aLink, unsigned aIdx)
Set the link associated to a given picked item.
void ClearListAndDeleteItems(std::function< void(EDA_ITEM *)> aItemDeleter)
Delete the list of pickers AND the data pointed by #m_PickedItem or #m_PickedItemLink according to th...
BASE_SCREEN * GetScreenForItem(unsigned int aIdx) const
EDA_ITEM * GetPickedItem(unsigned int aIdx) const
bool SetPickerFlags(EDA_ITEM_FLAGS aFlags, unsigned aIdx)
Set the flags of the picker (usually to the picked item m_flags value).
void PushCommand(PICKED_ITEMS_LIST *aCommand)
PICKED_ITEMS_LIST * PopCommand()
std::vector< PICKED_ITEMS_LIST * > m_CommandsList
std::uint32_t EDA_ITEM_FLAGS
#define UR_TRANSIENT
indicates the item is owned by the undo/redo stack
@ TYPE_NOT_INIT
Definition: typeinfo.h:81
UNDO_REDO
Undo Redo considerations: Basically we have 3 cases New item Deleted item Modified item there is also...