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 {
63 }
64 
66 {
67 }
68 
69 
71 {
72  m_ItemsList.push_back( aItem );
73 }
74 
75 
77 {
78  ITEM_PICKER item;
79 
80  if( m_ItemsList.size() != 0 )
81  {
82  item = m_ItemsList.back();
83  m_ItemsList.pop_back();
84  }
85 
86  return item;
87 }
88 
89 
90 bool PICKED_ITEMS_LIST::ContainsItem( const EDA_ITEM* aItem ) const
91 {
92  for( size_t i = 0; i < m_ItemsList.size(); i++ )
93  {
94  if( m_ItemsList[ i ].GetItem() == aItem )
95  return true;
96  }
97 
98  return false;
99 }
100 
101 
102 int PICKED_ITEMS_LIST::FindItem( const EDA_ITEM* aItem ) const
103 {
104  for( size_t i = 0; i < m_ItemsList.size(); i++ )
105  {
106  if( m_ItemsList[i].GetItem() == aItem )
107  return i;
108  }
109 
110  return -1;
111 }
112 
113 
115 {
116  m_ItemsList.clear();
117 }
118 
119 
121 {
122  // Delete items is they are not flagged NEWITEM, or if this is a block operation
123  while( GetCount() > 0 )
124  {
125  ITEM_PICKER wrapper = PopItem();
126  if( wrapper.GetItem() == NULL ) // No more item in list.
127  break;
128 
129  // The Link is an undo construct; it is always owned by the undo/redo container
130  if( wrapper.GetLink() )
131  delete wrapper.GetLink();
132 
133  if( wrapper.GetFlags() & UR_TRANSIENT )
134  {
135  delete wrapper.GetItem();
136  }
137  else if( wrapper.GetStatus() == UNDO_REDO::DELETED )
138  {
139  // This should really be replaced with UR_TRANSIENT, but currently many clients
140  // (eeschema in particular) abuse this to achieve non-undo-related deletions.
141  delete wrapper.GetItem();
142  }
143  }
144 }
145 
146 
148 {
149  ITEM_PICKER picker;
150 
151  if( aIdx < m_ItemsList.size() )
152  picker = m_ItemsList[aIdx];
153 
154  return picker;
155 }
156 
157 
158 EDA_ITEM* PICKED_ITEMS_LIST::GetPickedItem( unsigned int aIdx ) const
159 {
160  if( aIdx < m_ItemsList.size() )
161  return m_ItemsList[aIdx].GetItem();
162 
163  return NULL;
164 }
165 
166 
168 {
169  if( aIdx < m_ItemsList.size() )
170  return m_ItemsList[aIdx].GetScreen();
171 
172  return NULL;
173 }
174 
175 
177 {
178  if( aIdx < m_ItemsList.size() )
179  return m_ItemsList[aIdx].GetLink();
180 
181  return NULL;
182 }
183 
184 
186 {
187  if( aIdx < m_ItemsList.size() )
188  return m_ItemsList[aIdx].GetStatus();
189 
190  return UNDO_REDO::UNSPECIFIED;
191 }
192 
193 
195 {
196  if( aIdx < m_ItemsList.size() )
197  return m_ItemsList[aIdx].GetFlags();
198 
199  return 0;
200 }
201 
202 
203 bool PICKED_ITEMS_LIST::SetPickedItem( EDA_ITEM* aItem, unsigned aIdx )
204 {
205  if( aIdx < m_ItemsList.size() )
206  {
207  m_ItemsList[aIdx].SetItem( aItem );
208  return true;
209  }
210 
211  return false;
212 }
213 
214 
215 bool PICKED_ITEMS_LIST::SetPickedItemLink( EDA_ITEM* aLink, unsigned aIdx )
216 {
217  if( aIdx < m_ItemsList.size() )
218  {
219  m_ItemsList[aIdx].SetLink( aLink );
220  return true;
221  }
222 
223  return false;
224 }
225 
226 
227 bool PICKED_ITEMS_LIST::SetPickedItem( EDA_ITEM* aItem, UNDO_REDO aStatus, unsigned aIdx )
228 {
229  if( aIdx < m_ItemsList.size() )
230  {
231  m_ItemsList[aIdx].SetItem( aItem );
232  m_ItemsList[aIdx].SetStatus( aStatus );
233  return true;
234  }
235 
236  return false;
237 }
238 
239 
240 bool PICKED_ITEMS_LIST::SetPickedItemStatus( UNDO_REDO aStatus, unsigned aIdx )
241 {
242  if( aIdx < m_ItemsList.size() )
243  {
244  m_ItemsList[aIdx].SetStatus( aStatus );
245  return true;
246  }
247 
248  return false;
249 }
250 
251 
252 bool PICKED_ITEMS_LIST::SetPickerFlags( STATUS_FLAGS aFlags, unsigned aIdx )
253 {
254  if( aIdx < m_ItemsList.size() )
255  {
256  m_ItemsList[aIdx].SetFlags( aFlags );
257  return true;
258  }
259 
260  return false;
261 }
262 
263 
264 bool PICKED_ITEMS_LIST::RemovePicker( unsigned aIdx )
265 {
266  if( aIdx >= m_ItemsList.size() )
267  return false;
268 
269  m_ItemsList.erase( m_ItemsList.begin() + aIdx );
270  return true;
271 }
272 
273 
275 {
276  m_ItemsList = aSource.m_ItemsList; // Vector's copy
277 }
278 
279 
281 {
282  std::vector <ITEM_PICKER> tmp;
283  while( !m_ItemsList.empty() )
284  {
285  tmp.push_back( m_ItemsList.back() );
286  m_ItemsList.pop_back();
287  }
288 
289  m_ItemsList.swap( tmp );
290 }
291 
292 
293 /**********************************************/
294 /********** UNDO_REDO_CONTAINER ***************/
295 /**********************************************/
296 
298 {
299 }
300 
301 
303 {
305 }
306 
307 
309 {
310  for( unsigned ii = 0; ii < m_CommandsList.size(); ii++ )
311  delete m_CommandsList[ii];
312 
313  m_CommandsList.clear();
314 }
315 
316 
318 {
319  m_CommandsList.push_back( aItem );
320 }
321 
322 
324 {
325  if( m_CommandsList.size() != 0 )
326  {
327  PICKED_ITEMS_LIST* item = m_CommandsList.back();
328  m_CommandsList.pop_back();
329  return item;
330  }
331 
332  return NULL;
333 }
EDA_ITEM * GetPickedItemLink(unsigned int aIdx) const
std::vector< ITEM_PICKER > m_ItemsList
#define UR_TRANSIENT
indicates the item is owned by the undo/redo stack
Definition: eda_item.h:134
int FindItem(const EDA_ITEM *aItem) const
void ReversePickersListOrder()
Reverse the order of pickers stored in this list.
EDA_ITEM * GetItem() const
BASE_SCREEN * GetScreenForItem(unsigned int aIdx) const
STATUS_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.
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
EDA_ITEM * GetLink() const
void PushCommand(PICKED_ITEMS_LIST *aCommand)
void CopyList(const PICKED_ITEMS_LIST &aSource)
Copy all data from aSource to the list.
#define NULL
std::vector< PICKED_ITEMS_LIST * > m_CommandsList
bool SetPickedItem(EDA_ITEM *aItem, unsigned aIdx)
Handles how to draw a screen (a board, a schematic ...)
Definition: base_screen.h:40
UNDO_REDO m_undoRedoStatus
EDA_ITEM * GetPickedItem(unsigned int aIdx) const
unsigned STATUS_FLAGS
Definition: eda_item.h:144
STATUS_FLAGS GetFlags() const
bool RemovePicker(unsigned aIdx)
Remove one entry (one picker) from the list of picked items.
A holder to handle information on schematic or board items.
bool SetPickerFlags(STATUS_FLAGS aFlags, unsigned aIdx)
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
bool SetPickedItemStatus(UNDO_REDO aStatus, unsigned aIdx)
Set the type of undo/redo operation for a given picked item.
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:149
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.
UNDO_REDO GetPickedItemStatus(unsigned int aIdx) const
BASE_SCREEN * m_screen
bool ContainsItem(const EDA_ITEM *aItem) const
void ClearListAndDeleteItems()
Delete the list of pickers AND the data pointed by #m_PickedItem or #m_PickedItemLink according to th...
UNDO_REDO GetStatus() const