KiCad PCB EDA Suite
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 <stambaughw@verizon.net>
6  * Copyright (C) 2018 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 <fctsys.h>
27 #include <base_struct.h>
28 #include <undo_redo_container.h>
29 
30 
31 ITEM_PICKER::ITEM_PICKER( EDA_ITEM* aItem, UNDO_REDO_T aUndoRedoStatus )
32 {
33  m_undoRedoStatus = aUndoRedoStatus;
34  SetItem( aItem );
35  m_pickerFlags = 0;
36  m_link = NULL;
37 }
38 
39 
41 {
42  m_Status = UR_UNSPECIFIED;
43 }
44 
46 {
47 }
48 
49 
51 {
52  m_ItemsList.push_back( aItem );
53 }
54 
55 
57 {
58  ITEM_PICKER item;
59 
60  if( m_ItemsList.size() != 0 )
61  {
62  item = m_ItemsList.back();
63  m_ItemsList.pop_back();
64  }
65 
66  return item;
67 }
68 
69 
70 bool PICKED_ITEMS_LIST::ContainsItem( const EDA_ITEM* aItem ) const
71 {
72  for( size_t i = 0; i < m_ItemsList.size(); i++ )
73  {
74  if( m_ItemsList[ i ].GetItem() == aItem )
75  return true;
76  }
77 
78  return false;
79 }
80 
81 
82 int PICKED_ITEMS_LIST::FindItem( const EDA_ITEM* aItem ) const
83 {
84  for( size_t i = 0; i < m_ItemsList.size(); i++ )
85  {
86  if( m_ItemsList[i].GetItem() == aItem )
87  return i;
88  }
89 
90  return -1;
91 }
92 
93 
95 {
96  m_ItemsList.clear();
97 }
98 
99 
101 {
102  // Delete items is they are not flagged UR_NEW, or if this is a block operation
103  while( GetCount() > 0 )
104  {
105  ITEM_PICKER wrapper = PopItem();
106  if( wrapper.GetItem() == NULL ) // No more item in list.
107  break;
108 
109  // The Link is an undo construct; it is always owned by the undo/redo container
110  if( wrapper.GetLink() )
111  delete wrapper.GetLink();
112 
113  if( wrapper.GetFlags() & UR_TRANSIENT )
114  {
115  delete wrapper.GetItem();
116  }
117  else if( wrapper.GetStatus() == UR_WIRE_IMAGE )
118  {
119  // Specific to eeschema: a linked list of wires is stored. The wrapper picks only
120  // the first item (head of list), and is owner of all picked items.
121  EDA_ITEM* item = wrapper.GetItem();
122 
123  while( item )
124  {
125  // Delete old copy of wires
126  EDA_ITEM* nextitem = item->Next();
127  delete item;
128  item = nextitem;
129  }
130  }
131  else if( wrapper.GetStatus() == UR_DELETED )
132  {
133  // This should really be replaced with UR_TRANSIENT, but currently many clients
134  // (eeschema in particular) abuse this to achieve non-undo-related deletions.
135  delete wrapper.GetItem();
136  }
137  }
138 }
139 
140 
142 {
143  ITEM_PICKER picker;
144 
145  if( aIdx < m_ItemsList.size() )
146  picker = m_ItemsList[aIdx];
147 
148  return picker;
149 }
150 
151 
152 EDA_ITEM* PICKED_ITEMS_LIST::GetPickedItem( unsigned int aIdx ) const
153 {
154  if( aIdx < m_ItemsList.size() )
155  return m_ItemsList[aIdx].GetItem();
156 
157  return NULL;
158 }
159 
160 
162 {
163  if( aIdx < m_ItemsList.size() )
164  return m_ItemsList[aIdx].GetLink();
165 
166  return NULL;
167 }
168 
169 
171 {
172  if( aIdx < m_ItemsList.size() )
173  return m_ItemsList[aIdx].GetStatus();
174 
175  return UR_UNSPECIFIED;
176 }
177 
178 
180 {
181  if( aIdx < m_ItemsList.size() )
182  return m_ItemsList[aIdx].GetFlags();
183 
184  return 0;
185 }
186 
187 
188 bool PICKED_ITEMS_LIST::SetPickedItem( EDA_ITEM* aItem, unsigned aIdx )
189 {
190  if( aIdx < m_ItemsList.size() )
191  {
192  m_ItemsList[aIdx].SetItem( aItem );
193  return true;
194  }
195 
196  return false;
197 }
198 
199 
200 bool PICKED_ITEMS_LIST::SetPickedItemLink( EDA_ITEM* aLink, unsigned aIdx )
201 {
202  if( aIdx < m_ItemsList.size() )
203  {
204  m_ItemsList[aIdx].SetLink( aLink );
205  return true;
206  }
207 
208  return false;
209 }
210 
211 
212 bool PICKED_ITEMS_LIST::SetPickedItem( EDA_ITEM* aItem, UNDO_REDO_T aStatus, unsigned aIdx )
213 {
214  if( aIdx < m_ItemsList.size() )
215  {
216  m_ItemsList[aIdx].SetItem( aItem );
217  m_ItemsList[aIdx].SetStatus( aStatus );
218  return true;
219  }
220 
221  return false;
222 }
223 
224 
226 {
227  if( aIdx < m_ItemsList.size() )
228  {
229  m_ItemsList[aIdx].SetStatus( aStatus );
230  return true;
231  }
232 
233  return false;
234 }
235 
236 
237 bool PICKED_ITEMS_LIST::SetPickerFlags( STATUS_FLAGS aFlags, unsigned aIdx )
238 {
239  if( aIdx < m_ItemsList.size() )
240  {
241  m_ItemsList[aIdx].SetFlags( aFlags );
242  return true;
243  }
244 
245  return false;
246 }
247 
248 
249 bool PICKED_ITEMS_LIST::RemovePicker( unsigned aIdx )
250 {
251  if( aIdx >= m_ItemsList.size() )
252  return false;
253 
254  m_ItemsList.erase( m_ItemsList.begin() + aIdx );
255  return true;
256 }
257 
258 
260 {
261  m_ItemsList = aSource.m_ItemsList; // Vector's copy
262 }
263 
264 
266 {
267  std::vector <ITEM_PICKER> tmp;
268  while( !m_ItemsList.empty() )
269  {
270  tmp.push_back( m_ItemsList.back() );
271  m_ItemsList.pop_back();
272  }
273 
274  m_ItemsList.swap( tmp );
275 }
276 
277 
278 /**********************************************/
279 /********** UNDO_REDO_CONTAINER ***************/
280 /**********************************************/
281 
283 {
284 }
285 
286 
288 {
289  ClearCommandList();
290 }
291 
292 
294 {
295  for( unsigned ii = 0; ii < m_CommandsList.size(); ii++ )
296  delete m_CommandsList[ii];
297 
298  m_CommandsList.clear();
299 }
300 
301 
303 {
304  m_CommandsList.push_back( aItem );
305 }
306 
307 
309 {
310  if( m_CommandsList.size() != 0 )
311  {
312  PICKED_ITEMS_LIST* item = m_CommandsList.back();
313  m_CommandsList.pop_back();
314  return item;
315  }
316 
317  return NULL;
318 }
std::vector< ITEM_PICKER > m_ItemsList
ITEM_PICKER(EDA_ITEM *aItem=NULL, UNDO_REDO_T aUndoRedoStatus=UR_UNSPECIFIED)
void ReversePickersListOrder()
Function ReversePickersListOrder reverses the order of pickers stored in this list.
UNDO_REDO_T
Undo Redo considerations: Basically we have 3 cases New item Deleted item Modified item there is also...
STATUS_FLAGS GetFlags() const
void PushItem(const ITEM_PICKER &aItem)
Function PushItem pushes aItem to the top of the list.
EDA_ITEM * Next() const
Definition: base_struct.h:209
UNDO_REDO_T GetPickedItemStatus(unsigned int aIdx) const
Function GetPickedItemStatus.
PICKED_ITEMS_LIST * PopCommand()
EDA_ITEM * GetPickedItemLink(unsigned int aIdx) const
Function GetPickedItemLink.
UNDO_REDO_T GetStatus() const
void PushCommand(PICKED_ITEMS_LIST *aCommand)
EDA_ITEM * m_link
bool ContainsItem(const EDA_ITEM *aItem) const
Function IsItemInList.
void CopyList(const PICKED_ITEMS_LIST &aSource)
Function CopyList copies all data from aSource to the list.
EDA_ITEM * GetItem() const
bool SetPickedItem(EDA_ITEM *aItem, unsigned aIdx)
Function SetPickedItem.
unsigned STATUS_FLAGS
Definition: base_struct.h:147
bool RemovePicker(unsigned aIdx)
Function RemovePicker removes one entry (one picker) from the list of picked items.
Class PICKED_ITEMS_LIST is a holder to handle information on schematic or board items.
bool SetPickerFlags(STATUS_FLAGS aFlags, unsigned aIdx)
Function SetPickerFlags set the flags of the picker (usually to the picked item m_Flags value) ...
void SetItem(EDA_ITEM *aItem)
STATUS_FLAGS m_pickerFlags
STATUS_FLAGS GetPickerFlags(unsigned aIdx) const
Function GetPickerFlags returns the value of the picker flag.
bool SetPickedItemStatus(UNDO_REDO_T aStatus, unsigned aIdx)
Function SetPickedItemStatus sets the type of undo/redo operation for a given picked item...
EDA_ITEM * GetPickedItem(unsigned int aIdx) const
Function GetPickedItem.
size_t i
Definition: json11.cpp:597
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:154
ITEM_PICKER PopItem()
Function PopItem.
void ClearItemsList()
Function ClearItemsList deletes only the list of pickers, NOT the picked data itself.
bool SetPickedItemLink(EDA_ITEM *aLink, unsigned aIdx)
Function SetPickedItemLink set the link associated to a given picked item.
#define UR_TRANSIENT
indicates the item is owned by the undo/redo stack
Definition: base_struct.h:142
UNDO_REDO_T m_undoRedoStatus
Basic classes for most KiCad items.
int FindItem(const EDA_ITEM *aItem) const
Function FindItem.
ITEM_PICKER GetItemWrapper(unsigned int aIdx) const
Function GetItemWrapper.
EDA_ITEM * GetLink() const
void ClearListAndDeleteItems()
Function ClearListAndDeleteItems deletes the list of pickers, AND the data pointed by m_PickedItem or...