5 #include "mainindexes.h"
7 #include "mainsession.h"
10 #include "mwindowgui.h"
11 #include "undostackitem.h"
14 // Minimum number of undoable operations on the undo stack
15 #define UNDOMINLEVELS 5
16 // Limits the bytes of memory used by the undo stack
17 #define UNDOMEMORY 50000000
20 class MainUndoStackItem : public UndoStackItem
23 MainUndoStackItem(MainUndo* undo, char* description,
25 virtual ~MainUndoStackItem();
27 void set_data_before(char *data);
29 virtual int get_size();
32 // type of modification
33 unsigned long load_flags;
35 // data before the modification for undos
40 void load_from_undo(FileXML *file, uint32_t load_flags); // loads undo from the stringfile to the project
44 MainUndo::MainUndo(MWindow *mwindow)
46 this->mwindow = mwindow;
50 // get the initial project so we have something that the last undo reverts to
59 void MainUndo::push_undo_item(UndoStackItem *item)
62 while (redo_stack.last)
63 redo_stack.remove(redo_stack.last);
65 // move item onto undo_stack
66 undo_stack.append(item);
71 mwindow->session->changes_made = 1;
72 mwindow->gui->lock_window("MainUndo::update_undo_before");
73 mwindow->gui->mainmenu->undo->update_caption(item->description);
74 mwindow->gui->mainmenu->redo->update_caption("");
75 mwindow->gui->unlock_window();
78 void MainUndo::capture_state()
81 mwindow->edl->save_xml(mwindow->plugindb,
86 file.terminate_string();
88 data_after = new char[strlen(file.string)+1];
89 strcpy(data_after, file.string);
92 void MainUndo::update_undo_before(char *description, uint32_t load_flags)
96 new_entry = new MainUndoStackItem(this, description, load_flags);
100 void MainUndo::update_undo_after()
104 // the old data_after is the state before the change
105 new_entry->set_data_before(data_after);
108 push_undo_item(new_entry);
120 UndoStackItem* current_entry = undo_stack.last;
124 // move item to redo_stack
125 undo_stack.remove_pointer(current_entry);
126 current_entry->undo();
127 redo_stack.append(current_entry);
132 mwindow->gui->mainmenu->redo->update_caption(current_entry->description);
135 mwindow->gui->mainmenu->undo->update_caption(undo_stack.last->description);
137 mwindow->gui->mainmenu->undo->update_caption("");
145 UndoStackItem* current_entry = redo_stack.last;
149 // move item to undo_stack
150 redo_stack.remove_pointer(current_entry);
151 current_entry->undo();
152 undo_stack.append(current_entry);
157 mwindow->gui->mainmenu->undo->update_caption(current_entry->description);
160 mwindow->gui->mainmenu->redo->update_caption(redo_stack.last->description);
162 mwindow->gui->mainmenu->redo->update_caption("");
168 // enforces that the undo stack does not exceed a size of UNDOMEMORY
169 // except that it always has at least UNDOMINLEVELS entries
170 void MainUndo::prune_undo()
175 UndoStackItem* i = undo_stack.last;
176 while (i != 0 && (levels < UNDOMINLEVELS || size <= UNDOMEMORY))
178 size += i->get_size();
185 // truncate everything before and including i
186 while (undo_stack.first != i)
187 undo_stack.remove(undo_stack.first);
188 undo_stack.remove(undo_stack.first);
196 MainUndoStackItem::MainUndoStackItem(MainUndo* main_undo, char* description,
200 this->load_flags = load_flags;
201 this->main_undo = main_undo;
202 set_description(description);
205 MainUndoStackItem::~MainUndoStackItem()
207 delete [] data_before;
210 void MainUndoStackItem::set_data_before(char *data)
212 data_before = new char[strlen(data) + 1];
213 strcpy(data_before, data);
216 void MainUndoStackItem::undo()
218 // move the old data_after here
219 char* before = data_before;
221 set_data_before(main_undo->data_after);
226 file.read_from_string(before);
227 load_from_undo(&file, load_flags);
230 int MainUndoStackItem::get_size()
232 return data_before ? strlen(data_before) : 0;
235 // Here the master EDL loads
236 void MainUndoStackItem::load_from_undo(FileXML *file, uint32_t load_flags)
238 MWindow* mwindow = main_undo->mwindow;
239 mwindow->edl->load_xml(mwindow->plugindb, file, load_flags);
240 for(Asset *asset = mwindow->edl->assets->first;
244 mwindow->mainindexes->add_next_asset(asset);
246 mwindow->mainindexes->start_build();