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 <eda_item.h>
27 #include <undo_redo_container.h>
28 
29 
30 /*
31 ITEM_PICKER::ITEM_PICKER( EDA_ITEM* aItem, UNDO_REDO aUndoRedoStatus )
32 {
33  m_undoRedoStatus = aUndoRedoStatus;
34  SetItem( aItem );
35  m_pickerFlags = 0;
36  m_link = nullptr;
37  m_screen = nullptr;
38 }
39 */
40 
42 {
44  SetItem( nullptr );
45  m_pickerFlags = 0;
46  m_link = NULL;
47  m_screen = nullptr;
48 }
49 
50 
51 ITEM_PICKER::ITEM_PICKER( BASE_SCREEN* aScreen, EDA_ITEM* aItem, UNDO_REDO aUndoRedoStatus )
52 {
53  m_undoRedoStatus = aUndoRedoStatus;
54  SetItem( aItem );
55  m_pickerFlags = 0;
56  m_link = NULL;
57  m_screen = aScreen;
58 }
59 
60 
62 {
64 }
65 
67 {
68 }
69 
70 
72 {
73  m_ItemsList.push_back( aItem );
74 }
75 
76 
78 {
79  ITEM_PICKER item;
80 
81  if( m_ItemsList.size() != 0 )
82  {
83  item = m_ItemsList.back();
84  m_ItemsList.pop_back();
85  }
86 
87  return item;
88 }
89 
90 
91 bool PICKED_ITEMS_LIST::ContainsItem( const EDA_ITEM* aItem ) const
92 {
93  for( size_t i = 0; i < m_ItemsList.size(); i++ )
94  {
95  if( m_ItemsList[ i ].GetItem() == aItem )
96  return true;
97  }
98 
99  return false;
100 }
101 
102 
103 int PICKED_ITEMS_LIST::FindItem( const EDA_ITEM* aItem ) const
104 {
105  for( size_t i = 0; i < m_ItemsList.size(); i++ )
106  {
107  if( m_ItemsList[i].GetItem() == aItem )
108  return i;
109  }
110 
111  return -1;
112 }
113 
114 
116 {
117  m_ItemsList.clear();
118 }
119 
120 
122 {
123  // Delete items is they are not flagged NEWITEM, or if this is a block operation
124  while( GetCount() > 0 )
125  {
126  ITEM_PICKER wrapper = PopItem();
127  if( wrapper.GetItem() == NULL ) // No more item in list.
128  break;
129 
130  // The Link is an undo construct; it is always owned by the undo/redo container
131  if( wrapper.GetLink() )
132  delete wrapper.GetLink();
133 
134  if( wrapper.GetFlags() & UR_TRANSIENT )
135  {
136  delete wrapper.GetItem();
137  }
138  else if( wrapper.GetStatus() == UNDO_REDO::DELETED )
139  {
140  // This should really be replaced with UR_TRANSIENT, but currently many clients
141  // (eeschema in particular) abuse this to achieve non-undo-related deletions.
142  delete wrapper.GetItem();
143  }
144  }
145 }
146 
147 
149 {
150  ITEM_PICKER picker;
151 
152  if( aIdx < m_ItemsList.size() )
153  picker = m_ItemsList[aIdx];
154 
155  return picker;
156 }
157 
158 
159 EDA_ITEM* PICKED_ITEMS_LIST::GetPickedItem( unsigned int aIdx ) const
160 {
161  if( aIdx < m_ItemsList.size() )
162  return m_ItemsList[aIdx].GetItem();
163 
164  return NULL;
165 }
166 
167 
169 {
170  if( aIdx < m_ItemsList.size() )
171  return m_ItemsList[aIdx].GetScreen();
172 
173  return NULL;
174 }
175 
176 
178 {
179  if( aIdx < m_ItemsList.size() )
180  return m_ItemsList[aIdx].GetLink();
181 
182  return NULL;
183 }
184 
185 
187 {
188  if( aIdx < m_ItemsList.size() )
189  return m_ItemsList[aIdx].GetStatus();
190 
191  return UNDO_REDO::UNSPECIFIED;
192 }
193 
194 
196 {
197  if( aIdx < m_ItemsList.size() )
198  return m_ItemsList[aIdx].GetFlags();
199 
200  return 0;
201 }
202 
203 
204 bool PICKED_ITEMS_LIST::SetPickedItem( EDA_ITEM* aItem, unsigned aIdx )
205 {
206  if( aIdx < m_ItemsList.size() )
207  {
208  m_ItemsList[aIdx].SetItem( aItem );
209  return true;
210  }
211 
212  return false;
213 }
214 
215 
216 bool PICKED_ITEMS_LIST::SetPickedItemLink( EDA_ITEM* aLink, unsigned aIdx )
217 {
218  if( aIdx < m_ItemsList.size() )
219  {
220  m_ItemsList[aIdx].SetLink( aLink );
221  return true;
222  }
223 
224  return false;
225 }
226 
227 
228 bool PICKED_ITEMS_LIST::SetPickedItem( EDA_ITEM* aItem, UNDO_REDO aStatus, unsigned aIdx )
229 {
230  if( aIdx < m_ItemsList.size() )
231  {
232  m_ItemsList[aIdx].SetItem( aItem );
233  m_ItemsList[aIdx].SetStatus( aStatus );
234  return true;
235  }
236 
237  return false;
238 }
239 
240 
241 bool PICKED_ITEMS_LIST::SetPickedItemStatus( UNDO_REDO aStatus, unsigned aIdx )
242 {
243  if( aIdx < m_ItemsList.size() )
244  {
245  m_ItemsList[aIdx].SetStatus( aStatus );
246  return true;
247  }
248 
249  return false;
250 }
251 
252 
253 bool PICKED_ITEMS_LIST::SetPickerFlags( STATUS_FLAGS aFlags, unsigned aIdx )
254 {
255  if( aIdx < m_ItemsList.size() )
256  {
257  m_ItemsList[aIdx].SetFlags( aFlags );
258  return true;
259  }
260 
261  return false;
262 }
263 
264 
265 bool PICKED_ITEMS_LIST::RemovePicker( unsigned aIdx )
266 {
267  if( aIdx >= m_ItemsList.size() )
268  return false;
269 
270  m_ItemsList.erase( m_ItemsList.begin() + aIdx );
271  return true;
272 }
273 
274 
276 {
277  m_ItemsList = aSource.m_ItemsList; // Vector's copy
278 }
279 
280 
282 {
283  std::vector <ITEM_PICKER> tmp;
284  while( !m_ItemsList.empty() )
285  {
286  tmp.push_back( m_ItemsList.back() );
287  m_ItemsList.pop_back();
288  }
289 
290  m_ItemsList.swap( tmp );
291 }
292 
293 
294 /**********************************************/
295 /********** UNDO_REDO_CONTAINER ***************/
296 /**********************************************/
297 
299 {
300 }
301 
302 
304 {
306 }
307 
308 
310 {
311  for( unsigned ii = 0; ii < m_CommandsList.size(); ii++ )
312  delete m_CommandsList[ii];
313 
314  m_CommandsList.clear();
315 }
316 
317 
319 {
320  m_CommandsList.push_back( aItem );
321 }
322 
323 
325 {
326  if( m_CommandsList.size() != 0 )
327  {
328  PICKED_ITEMS_LIST* item = m_CommandsList.back();
329  m_CommandsList.pop_back();
330  return item;
331  }
332 
333  return NULL;
334 }
EDA_ITEM * GetPickedItemLink(unsigned int aIdx) const
Function GetPickedItemLink.
std::vector< ITEM_PICKER > m_ItemsList
#define UR_TRANSIENT
indicates the item is owned by the undo/redo stack
Definition: eda_item.h:131
int FindItem(const EDA_ITEM *aItem) const
Function FindItem.
void ReversePickersListOrder()
Function ReversePickersListOrder reverses the order of pickers stored in this list.
EDA_ITEM * GetItem() const
BASE_SCREEN * GetScreenForItem(unsigned int aIdx) const
Function GetScreenForItem.
STATUS_FLAGS GetPickerFlags(unsigned aIdx) const
Function GetPickerFlags returns the value of the picker flag.
void PushItem(const ITEM_PICKER &aItem)
Function PushItem pushes aItem to the top of the list.
UNDO_REDO
Undo Redo considerations: Basically we have 3 cases New item Deleted item Modified item there is also...
PICKED_ITEMS_LIST * PopCommand()
unsigned GetCount() const
Function GetCount.
EDA_ITEM * GetLink() const
void PushCommand(PICKED_ITEMS_LIST *aCommand)
EDA_ITEM * m_link
void CopyList(const PICKED_ITEMS_LIST &aSource)
Function CopyList copies all data from aSource to the list.
#define NULL
std::vector< PICKED_ITEMS_LIST * > m_CommandsList
bool SetPickedItem(EDA_ITEM *aItem, unsigned aIdx)
Function SetPickedItem.
BASE_SCREEN handles how to draw a screen (a board, a schematic ...)
Definition: base_screen.h:42
UNDO_REDO m_undoRedoStatus
EDA_ITEM * GetPickedItem(unsigned int aIdx) const
Function GetPickedItem.
unsigned STATUS_FLAGS
Definition: eda_item.h:140
STATUS_FLAGS GetFlags() const
bool RemovePicker(unsigned aIdx)
Function RemovePicker removes one entry (one picker) from the list of picked items.
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
ITEM_PICKER GetItemWrapper(unsigned int aIdx) const
Function GetItemWrapper.
bool SetPickedItemStatus(UNDO_REDO aStatus, unsigned aIdx)
Function SetPickedItemStatus sets the type of undo/redo operation for a given picked item.
EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boards.
Definition: eda_item.h:147
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.
UNDO_REDO GetPickedItemStatus(unsigned int aIdx) const
Function GetPickedItemStatus.
BASE_SCREEN * m_screen
bool ContainsItem(const EDA_ITEM *aItem) const
Function IsItemInList.
void ClearListAndDeleteItems()
Function ClearListAndDeleteItems deletes the list of pickers, AND the data pointed by m_PickedItem or...
UNDO_REDO GetStatus() const