4 * Copyright (C) 1997-2011 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include "mainindexes.h"
29 #include "mainsession.h"
32 #include "mwindowgui.h"
33 #include "nestededls.h"
35 #include "undostack.h"
37 MainUndo::MainUndo(MWindow *mwindow)
39 this->mwindow = mwindow;
40 undo_stack = new UndoStack;
41 last_update = new Timer;
51 void MainUndo::update_undo_entry(const char *description,
58 mwindow->edl->save_xml(&file,
62 file.terminate_string();
63 if(changes_made) mwindow->session->changes_made = 1;
65 // Remove all entries after current and create new one
66 UndoStackItem *current = undo_stack->push();
68 current->set_flags(load_flags);
69 current->set_data(file.string());
70 current->set_description((char*)description);
71 current->set_creator(creator);
72 current->set_filename(mwindow->session->filename);
73 //printf("MainUndo::update_undo_entry %d %p %s\n", __LINE__, current, current->get_filename());
75 // Can't undo only 1 record.
76 if(undo_stack->total() > 1)
78 // mwindow->gui->lock_window("MainUndo::update_undo");
79 mwindow->gui->mainmenu->undo->update_caption(description);
80 mwindow->gui->mainmenu->redo->update_caption("");
81 // mwindow->gui->unlock_window();
85 last_update->update();
88 void MainUndo::update_undo_before(const char *description, void *creator)
90 //printf("MainUndo::update_undo_before %d\n", __LINE__);
91 if(undo_stack->current && !(undo_stack->number_of(undo_stack->current) % 2))
93 printf("MainUndo::update_undo_before %d \"%s\": must be on an after entry to do this. size=%d\n",
101 // Move up an entry to get back in sync
105 mwindow->commit_commercial();
107 // Discard if creator matches previous before entry and within a time limit
110 UndoStackItem *current = undo_stack->current;
111 // Currently on an after entry
117 // Now on a before entry
120 if(current->get_creator() == creator &&
121 !strcmp(current->get_description(), description) &&
122 last_update->get_difference() < UNDO_SPAN)
124 // Before entry has same creator within minimum time. Reuse it.
125 // Stack must point to the before entry
126 undo_stack->current = current;
132 // Append new entry after current position
133 update_undo_entry("", 0, creator, 0);
136 void MainUndo::update_undo_after(const char *description,
140 //printf("MainUndo::update_undo_after %d\n", __LINE__);
141 if(undo_stack->number_of(undo_stack->current) % 2)
143 printf("MainUndo::update_undo_after %d \"%s\": must be on a before entry to do this. size=%d\n",
146 undo_stack->total());
150 // Not getting any update_undo_before to get back in sync, so just append 1 here
154 update_undo_entry(description, load_flags, 0, changes_made);
156 // Update the before entry flags
157 UndoStackItem *current = undo_stack->last;
158 if(current) current = PREVIOUS;
161 current->set_flags(load_flags);
162 current->set_description((char*)description);
169 UndoStackItem *current = undo_stack->current;
170 char after_description[BCTEXTLEN];
171 after_description[0] = 0;
173 mwindow->undo_commercial();
175 //printf("MainUndo::undo 1\n");
178 // Rewind to an after entry
179 if(current && !(undo_stack->number_of(current) % 2))
184 // Rewind to a before entry
185 if(current && (undo_stack->number_of(current) % 2))
187 strcpy(after_description, current->get_description());
191 // Now have an even number
194 undo_stack->current = current;
195 // Set the redo text to the current description
197 mwindow->gui->mainmenu->redo->update_caption(
201 char *current_data = current->get_data();
204 file.read_from_string(current_data);
205 load_from_undo(&file, current->get_flags());
206 //printf("MainUndo::undo %d %s\n", __LINE__, current->get_filename());
207 mwindow->set_filename(current->get_filename());
208 delete [] current_data;
210 // move current entry back one step
216 // Now update the menu with the after entry
218 // Must be a previous entry to perform undo
220 mwindow->gui->mainmenu->undo->update_caption(
221 current->get_description());
223 mwindow->gui->mainmenu->undo->update_caption("");
236 UndoStackItem *current = undo_stack->current;
237 //printf("MainUndo::redo 1\n");
241 if(!current) current = undo_stack->first;
243 // Advance to a before entry
244 if(current && (undo_stack->number_of(current) % 2))
249 // Advance to an after entry
250 if(current && !(undo_stack->number_of(current) % 2))
258 char *current_data = current->get_data();
259 undo_stack->current = current;
263 mwindow->set_filename(current->get_filename());
264 file.read_from_string(current_data);
265 load_from_undo(&file, current->get_flags());
266 delete [] current_data;
271 mwindow->gui->mainmenu->undo->update_caption(current->get_description());
273 // Get next after entry
279 mwindow->gui->mainmenu->redo->update_caption(current->get_description());
281 mwindow->gui->mainmenu->redo->update_caption("");
291 // Here the master EDL loads
292 int MainUndo::load_from_undo(FileXML *file, uint32_t load_flags)
294 mwindow->edl->load_xml(file, load_flags);
295 for(Asset *asset = mwindow->edl->assets->first;
299 mwindow->mainindexes->add_next_asset(0, asset);
302 for(int i = 0; i < mwindow->edl->nested_edls->size(); i++)
304 EDL *nested_edl = mwindow->edl->nested_edls->get(i);
305 mwindow->mainindexes->add_next_asset(0, nested_edl);
307 mwindow->mainindexes->start_build();
308 mwindow->update_plugin_guis(1);
313 void MainUndo::reset_creators()
315 for(UndoStackItem *current = undo_stack->first;
319 current->set_creator(0);
324 void MainUndo::dump(FILE *fp)
326 undo_stack->dump(fp);