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-2024 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
100{
101 for( const ITEM_PICKER& picker : m_ItemsList )
102 {
103 const EDA_ITEM* item = picker.GetItem();
104
105 wxCHECK2( item, continue );
106
107 if( item->Type() == aItemType )
108 return true;
109 }
110
111 return false;
112}
113
114
115int PICKED_ITEMS_LIST::FindItem( const EDA_ITEM* aItem ) const
116{
117 for( size_t i = 0; i < m_ItemsList.size(); i++ )
118 {
119 if( m_ItemsList[i].GetItem() == aItem )
120 return i;
121 }
122
123 return -1;
124}
125
126
128{
129 m_ItemsList.clear();
130}
131
132
133void PICKED_ITEMS_LIST::ClearListAndDeleteItems( std::function<void(EDA_ITEM*)> aItemDeleter )
134{
135 while( GetCount() > 0 )
136 {
137 ITEM_PICKER wrapper = PopItem();
138
139 if( wrapper.GetItem() == nullptr ) // No more items in list.
140 break;
141
142 // The Link is an undo construct; it is always owned by the undo/redo container
143 if( wrapper.GetLink() )
144 aItemDeleter( wrapper.GetLink() );
145
146 if( wrapper.GetFlags() & UR_TRANSIENT )
147 {
148 aItemDeleter( wrapper.GetItem() );
149 }
150 else if( wrapper.GetStatus() == UNDO_REDO::DELETED )
151 {
152 // This should really be replaced with UR_TRANSIENT, but currently many clients
153 // (eeschema in particular) abuse this to achieve non-undo-related deletions.
154 aItemDeleter( wrapper.GetItem() );
155 }
156 }
157}
158
159
161{
162 ITEM_PICKER picker;
163
164 if( aIdx < m_ItemsList.size() )
165 picker = m_ItemsList[aIdx];
166
167 return picker;
168}
169
170
172{
173 if( aIdx < m_ItemsList.size() )
174 return m_ItemsList[aIdx].GetItem();
175
176 return nullptr;
177}
178
179
181{
182 if( aIdx < m_ItemsList.size() )
183 return m_ItemsList[aIdx].GetScreen();
184
185 return nullptr;
186}
187
188
190{
191 if( aIdx < m_ItemsList.size() )
192 return m_ItemsList[aIdx].GetLink();
193
194 return nullptr;
195}
196
197
199{
200 if( aIdx < m_ItemsList.size() )
201 return m_ItemsList[aIdx].GetStatus();
202
203 return UNDO_REDO::UNSPECIFIED;
204}
205
206
208{
209 if( aIdx < m_ItemsList.size() )
210 return m_ItemsList[aIdx].GetFlags();
211
212 return 0;
213}
214
215
217{
218 if( aIdx < m_ItemsList.size() )
219 return m_ItemsList[aIdx].GetGroupId();
220
221 return KIID();
222}
223
224
225bool PICKED_ITEMS_LIST::SetPickedItemGroupId( KIID aGroupId, unsigned aIdx )
226{
227 if( aIdx < m_ItemsList.size() )
228 {
229 m_ItemsList[aIdx].SetGroupId( aGroupId );
230 return true;
231 }
232
233 return false;
234}
235
236
237bool PICKED_ITEMS_LIST::SetPickedItem( EDA_ITEM* aItem, unsigned aIdx )
238{
239 if( aIdx < m_ItemsList.size() )
240 {
241 m_ItemsList[aIdx].SetItem( aItem );
242 return true;
243 }
244
245 return false;
246}
247
248
250{
251 if( aIdx < m_ItemsList.size() )
252 {
253 m_ItemsList[aIdx].SetLink( aLink );
254 return true;
255 }
256
257 return false;
258}
259
260
261bool PICKED_ITEMS_LIST::SetPickedItem( EDA_ITEM* aItem, UNDO_REDO aStatus, unsigned aIdx )
262{
263 if( aIdx < m_ItemsList.size() )
264 {
265 m_ItemsList[aIdx].SetItem( aItem );
266 m_ItemsList[aIdx].SetStatus( aStatus );
267 return true;
268 }
269
270 return false;
271}
272
273
275{
276 if( aIdx < m_ItemsList.size() )
277 {
278 m_ItemsList[aIdx].SetStatus( aStatus );
279 return true;
280 }
281
282 return false;
283}
284
285
287{
288 if( aIdx < m_ItemsList.size() )
289 {
290 m_ItemsList[aIdx].SetFlags( aFlags );
291 return true;
292 }
293
294 return false;
295}
296
297
299{
300 if( aIdx >= m_ItemsList.size() )
301 return false;
302
303 m_ItemsList.erase( m_ItemsList.begin() + aIdx );
304 return true;
305}
306
307
309{
310 m_ItemsList = aSource.m_ItemsList; // Vector's copy
311}
312
313
315{
316 std::vector <ITEM_PICKER> tmp;
317
318 while( !m_ItemsList.empty() )
319 {
320 tmp.push_back( m_ItemsList.back() );
321 m_ItemsList.pop_back();
322 }
323
324 m_ItemsList.swap( tmp );
325}
326
327
329{
330}
331
332
334{
336}
337
338
340{
341 for( unsigned ii = 0; ii < m_CommandsList.size(); ii++ )
342 delete m_CommandsList[ii];
343
344 m_CommandsList.clear();
345}
346
347
349{
350 m_CommandsList.push_back( aItem );
351}
352
353
355{
356 if( m_CommandsList.size() != 0 )
357 {
358 PICKED_ITEMS_LIST* item = m_CommandsList.back();
359 m_CommandsList.pop_back();
360 return item;
361 }
362
363 return nullptr;
364}
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:89
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:101
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
Definition: kiid.h:49
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
KIID GetPickedItemGroupId(unsigned int aIdx) const
unsigned GetCount() const
bool ContainsItemType(KICAD_T aItemType) const
Check the undo/redo list for any EDA_ITEM of type aItemType.
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...
bool SetPickedItemGroupId(KIID aId, unsigned aIdx)
Set the group id associated to a given picked item.
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
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:78
@ 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...