From 059640bb5a50f25f63041c1b32aafc6effedc378 Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Wed, 11 May 2005 20:25:58 +0000 Subject: [PATCH] r578: Factored UndoStackItem into an interface class UndoStackItem and a derived class MainUndoStackItem that keeps the EDL backups. --- cinelerra/Makefile.am | 2 + cinelerra/mainundo.C | 124 ++++++++++++++++++++--- cinelerra/mainundo.h | 7 +- cinelerra/mwindowedit.C | 2 +- cinelerra/undostack.C | 247 +++++++++++++--------------------------------- cinelerra/undostack.h | 121 +++++++---------------- cinelerra/undostackitem.C | 33 +++++++ cinelerra/undostackitem.h | 34 +++++++ 8 files changed, 290 insertions(+), 280 deletions(-) rewrite cinelerra/undostack.C (62%) rewrite cinelerra/undostack.h (69%) create mode 100644 cinelerra/undostackitem.C create mode 100644 cinelerra/undostackitem.h diff --git a/cinelerra/Makefile.am b/cinelerra/Makefile.am index 0cf56c58..c52b6c4c 100644 --- a/cinelerra/Makefile.am +++ b/cinelerra/Makefile.am @@ -231,6 +231,7 @@ cinelerra_SOURCES = aattachmentpoint.C \ transitionpopup.C \ transportque.C \ undostack.C \ + undostackitem.C \ vattachmentpoint.C \ vautomation.C \ vdevice1394.C \ @@ -538,6 +539,7 @@ noinst_HEADERS = aattachmentpoint.h \ transitionpopup.h \ transportque.h \ undostack.h \ + undostackitem.h \ vattachmentpoint.h \ vautomation.h \ vdevice1394.h \ diff --git a/cinelerra/mainundo.C b/cinelerra/mainundo.C index bdc2b392..d226a5e4 100644 --- a/cinelerra/mainundo.C +++ b/cinelerra/mainundo.C @@ -8,8 +8,38 @@ #include "mainundo.h" #include "mwindow.h" #include "mwindowgui.h" +#include "undostackitem.h" #include + +class MainUndoStackItem : public UndoStackItem +{ +public: + MainUndoStackItem(MWindow* mwindow, char* description); + virtual ~MainUndoStackItem(); + + void set_data_before(char *data, uint32_t load_flags); + void set_data_after(char *data); + virtual void undo(); + virtual void redo(); + virtual int get_size(); + +private: +// type of modification + unsigned long load_flags; + +// data after the modification for redos + char *data_after; + +// data before the modification for undos + char *data_before; + + MWindow *mwindow; + + void load_from_undo(FileXML *file, uint32_t load_flags); // loads undo from the stringfile to the project +}; + + MainUndo::MainUndo(MWindow *mwindow) { this->mwindow = mwindow; @@ -24,6 +54,8 @@ void MainUndo::push_undo_item(UndoStackItem *item) { undo_stack.push(item); undo_stack.prune(); + + mwindow->session->changes_made = 1; mwindow->gui->lock_window("MainUndo::update_undo_before"); mwindow->gui->mainmenu->undo->update_caption(item->description); mwindow->gui->mainmenu->redo->update_caption(""); @@ -35,7 +67,6 @@ void MainUndo::update_undo_before(char *description, uint32_t load_flags) if(!undo_before_updated) { FileXML file; - mwindow->session->changes_made = 1; mwindow->edl->save_xml(mwindow->plugindb, &file, "", @@ -43,17 +74,8 @@ void MainUndo::update_undo_before(char *description, uint32_t load_flags) 0); file.terminate_string(); - current_entry = undo_stack.push(); - current_entry->load_flags = load_flags; - current_entry->set_data_before(file.string); - current_entry->set_description(description); - current_entry->set_mwindow(mwindow); - -// the after update is always without a description - mwindow->gui->lock_window("MainUndo::update_undo_before"); - mwindow->gui->mainmenu->undo->update_caption(description); - mwindow->gui->mainmenu->redo->update_caption(""); - mwindow->gui->unlock_window(); + new_entry = new MainUndoStackItem(mwindow, description); + new_entry->set_data_before(file.string, load_flags); undo_before_updated = 1; } @@ -73,8 +95,9 @@ void MainUndo::update_undo_after() //printf("MainUndo::update_undo_after 1\n"); file.terminate_string(); //printf("MainUndo::update_undo_after 1\n"); - current_entry->set_data_after(file.string); - undo_stack.prune(); + new_entry->set_data_after(file.string); + push_undo_item(new_entry); + //printf("MainUndo::update_undo_after 10\n"); undo_before_updated = 0; } @@ -89,7 +112,7 @@ int MainUndo::undo() { if(undo_stack.current) { - current_entry = undo_stack.current; + UndoStackItem* current_entry = undo_stack.current; if(current_entry->description && mwindow->gui) mwindow->gui->mainmenu->redo->update_caption(current_entry->description); @@ -110,7 +133,7 @@ int MainUndo::undo() int MainUndo::redo() { - current_entry = undo_stack.pull_next(); + UndoStackItem* current_entry = undo_stack.pull_next(); if(current_entry) { @@ -128,3 +151,72 @@ int MainUndo::redo() } return 0; } + + + + + + +MainUndoStackItem::MainUndoStackItem(MWindow* mwindow, char* description) +{ + data_after = data_before = 0; + load_flags = 0; + this->mwindow = mwindow; + set_description(description); +} + +MainUndoStackItem::~MainUndoStackItem() +{ + delete [] data_after; + delete [] data_before; +} + +void MainUndoStackItem::set_data_before(char *data, uint32_t load_flags) +{ + this->data_before = new char[strlen(data) + 1]; + strcpy(this->data_before, data); + this->load_flags = load_flags; +} + +void MainUndoStackItem::set_data_after(char *data) +{ + this->data_after = new char[strlen(data) + 1]; + strcpy(this->data_after, data); +} + +void MainUndoStackItem::undo() +{ + FileXML file; + + file.read_from_string(data_before); + load_from_undo(&file, load_flags); +} + +void MainUndoStackItem::redo() +{ + FileXML file; + file.read_from_string(data_after); + load_from_undo(&file, load_flags); +} + +int MainUndoStackItem::get_size() +{ + return strlen(data_before) + strlen(data_after); +} + +// Here the master EDL loads +void MainUndoStackItem::load_from_undo(FileXML *file, uint32_t load_flags) +{ + mwindow->edl->load_xml(mwindow->plugindb, file, load_flags); + for(Asset *asset = mwindow->edl->assets->first; + asset; + asset = asset->next) + { + mwindow->mainindexes->add_next_asset(asset); + } + mwindow->mainindexes->start_build(); +} + + + + diff --git a/cinelerra/mainundo.h b/cinelerra/mainundo.h index fd9a2634..d3699c70 100644 --- a/cinelerra/mainundo.h +++ b/cinelerra/mainundo.h @@ -2,12 +2,15 @@ #define MAINUNDO_H -#include "filexml.inc" #include "mwindow.inc" #include "undostack.h" #include + +class MainUndoStackItem; + + class MainUndo { public: @@ -28,7 +31,7 @@ public: private: UndoStack undo_stack; - UndoStackItem* current_entry; // for setting the after buffer + MainUndoStackItem* new_entry; // for setting the after buffer MWindow *mwindow; int undo_before_updated; }; diff --git a/cinelerra/mwindowedit.C b/cinelerra/mwindowedit.C index c02ee63a..062c5a1d 100644 --- a/cinelerra/mwindowedit.C +++ b/cinelerra/mwindowedit.C @@ -38,7 +38,7 @@ #include "transition.h" #include "transportque.h" #include "units.h" -#include "undostack.h" +#include "undostackitem.h" #include "vplayback.h" #include "vwindow.h" #include "vwindowgui.h" diff --git a/cinelerra/undostack.C b/cinelerra/undostack.C dissimilarity index 62% index 8c0cb105..4d87e742 100644 --- a/cinelerra/undostack.C +++ b/cinelerra/undostack.C @@ -1,176 +1,71 @@ -#include "stringfile.h" -#include "undostack.h" -#include "asset.h" -#include "assets.h" -#include "edl.h" -#include "filexml.h" -#include "mainindexes.h" -#include "mwindow.h" -#include - -UndoStack::UndoStack() : List() -{ - current = 0; -} - -UndoStack::~UndoStack() -{ -} - -void UndoStack::push(UndoStackItem *item) -{ -// current is only 0 if before first undo - if(current) - current = insert_after(current, item); - else - current = insert_before(first, item); - -// delete future undos if necessary - if(current && current->next) - { - while(current->next) remove(last); - } -} - -UndoStackItem* UndoStack::push() -{ -// current is only 0 if before first undo - if(current) - current = insert_after(current); - else - current = insert_before(first); - -// delete future undos if necessary - if(current && current->next) - { - while(current->next) remove(last); - } - - return current; -} - -int UndoStack::pull() -{ - if(current) current = PREVIOUS; -} - -UndoStackItem* UndoStack::pull_next() -{ -// use first entry if none - if(!current) current = first; - else -// use next entry if there is a next entry - if(current->next) - current = NEXT; -// don't change current if there is no next entry - else - return 0; - - return current; -} - -// enforces that the undo stack does not exceed a size of UNDOMEMORY -// except that it always has at least UNDOMINLEVELS entries -void UndoStack::prune() -{ - int size = 0; - int levels = 0; - - UndoStackItem* i = last; - while (i != 0 && (levels < UNDOMINLEVELS || size <= UNDOMEMORY)) - { - size += i->get_size(); - ++levels; - i = i->previous; - } - - if (i != 0) - { -// truncate everything before and including i - while (first != i) - remove(first); - remove(first); - } -} - - - - - - - -UndoStackItem::UndoStackItem() : ListItem() -{ - description = type = data_after = data_before = 0; -} - -UndoStackItem::~UndoStackItem() -{ - if(description) delete [] description; - if(type) delete [] type; - if(data_after) delete [] data_after; - if(data_before) delete [] data_before; -} - -int UndoStackItem::set_description(char *description) -{ - this->description = new char[strlen(description) + 1]; - strcpy(this->description, description); -} - -int UndoStackItem::set_type(char *type) -{ - this->type = new char[strlen(type) + 1]; - strcpy(this->type, type); -} - -int UndoStackItem::set_data_before(char *data) -{ - this->data_before = new char[strlen(data) + 1]; - strcpy(this->data_before, data); -} - -int UndoStackItem::set_data_after(char *data) -{ - this->data_after = new char[strlen(data) + 1]; - strcpy(this->data_after, data); -} - -void UndoStackItem::undo() -{ - FileXML file; - - file.read_from_string(data_before); - load_from_undo(&file, load_flags); -} - -void UndoStackItem::redo() -{ - FileXML file; - file.read_from_string(data_after); - load_from_undo(&file, load_flags); -} - -int UndoStackItem::get_size() -{ - return strlen(data_before) + strlen(data_after); -} - -void UndoStackItem::set_mwindow(MWindow *mwindow) -{ - this->mwindow = mwindow; -} - -// Here the master EDL loads -int UndoStackItem::load_from_undo(FileXML *file, uint32_t load_flags) -{ - mwindow->edl->load_xml(mwindow->plugindb, file, load_flags); - for(Asset *asset = mwindow->edl->assets->first; - asset; - asset = asset->next) - { - mwindow->mainindexes->add_next_asset(asset); - } - mwindow->mainindexes->start_build(); - return 0; -} +#include "undostack.h" +#include "undostackitem.h" + + +UndoStack::UndoStack() : List() +{ + current = 0; +} + +UndoStack::~UndoStack() +{ +} + +void UndoStack::push(UndoStackItem *item) +{ +// current is only 0 if before first undo + if(current) + current = insert_after(current, item); + else + current = insert_before(first, item); + +// delete future undos if necessary + if(current && current->next) + { + while(current->next) remove(last); + } +} + +int UndoStack::pull() +{ + if(current) current = PREVIOUS; +} + +UndoStackItem* UndoStack::pull_next() +{ +// use first entry if none + if(!current) current = first; + else +// use next entry if there is a next entry + if(current->next) + current = NEXT; +// don't change current if there is no next entry + else + return 0; + + return current; +} + +// enforces that the undo stack does not exceed a size of UNDOMEMORY +// except that it always has at least UNDOMINLEVELS entries +void UndoStack::prune() +{ + int size = 0; + int levels = 0; + + UndoStackItem* i = last; + while (i != 0 && (levels < UNDOMINLEVELS || size <= UNDOMEMORY)) + { + size += i->get_size(); + ++levels; + i = i->previous; + } + + if (i != 0) + { +// truncate everything before and including i + while (first != i) + remove(first); + remove(first); + } +} diff --git a/cinelerra/undostack.h b/cinelerra/undostack.h dissimilarity index 69% index e5bddf40..1d344d3f 100644 --- a/cinelerra/undostack.h +++ b/cinelerra/undostack.h @@ -1,85 +1,36 @@ -#ifndef UNDOSTACK_H -#define UNDOSTACK_H - -#include "linklist.h" -#include "mwindow.h" -#include "filexml.h" -#include "edl.h" -#include "stringfile.inc" - -// Minimum number of undoable operations on the undo stack -#define UNDOMINLEVELS 5 -// Limits the bytes of memory used by the undo stack -#define UNDOMEMORY 50000000 - -class UndoStackItem : public ListItem -{ -public: - UndoStackItem(); - virtual ~UndoStackItem(); - - int set_data_before(char *data); - int set_data_after(char *data); - int set_type(char *type); - int set_description(char *description); - - // These two virtual functions allow derived objects to be pushed - // on to the undo stack that are more efficient in time and memory - // usage than the default action of saving before and after copies - // of the EDL. - virtual void undo(); - virtual void redo(); - - // Return the amount of memory used for the data associated with this - // object in order to enable limiting the amount of memory used by the - // undo stack. - // Ignore overhead and just report the specific data values that the - // derived object adds. - virtual int get_size(); - - -// command description for the menu item - char *description; - -// type of modification - unsigned long load_flags; - char *type; - -// data after the modification for redos - char *data_after; - -// data before the modification for undos - char *data_before; - - MWindow *mwindow; - - void set_mwindow(MWindow *mwindow); - - int load_from_undo(FileXML *file, uint32_t load_flags); // loads undo from the stringfile to the project -}; - -class UndoStack : public List -{ -public: - UndoStack(); - ~UndoStack(); - -// create a new undo entry -// delete future undos if in the middle -// delete undos older than UNDOLEVELS if last - UndoStackItem* push(); - void push(UndoStackItem *item); - -// move to the previous undo entry - int pull(); - - -// move to the next undo entry for a redo - UndoStackItem* pull_next(); - - UndoStackItem* current; - - void prune(); -}; - -#endif +#ifndef UNDOSTACK_H +#define UNDOSTACK_H + +#include "linklist.h" + +// Minimum number of undoable operations on the undo stack +#define UNDOMINLEVELS 5 +// Limits the bytes of memory used by the undo stack +#define UNDOMEMORY 50000000 + +class UndoStackItem; + + +class UndoStack : public List +{ +public: + UndoStack(); + ~UndoStack(); + +// delete future undos if in the middle +// delete undos older than UNDOLEVELS if last + void push(UndoStackItem *item); + +// move to the previous undo entry + int pull(); + + +// move to the next undo entry for a redo + UndoStackItem* pull_next(); + + UndoStackItem* current; + + void prune(); +}; + +#endif diff --git a/cinelerra/undostackitem.C b/cinelerra/undostackitem.C new file mode 100644 index 00000000..35b37847 --- /dev/null +++ b/cinelerra/undostackitem.C @@ -0,0 +1,33 @@ +#include "undostackitem.h" +#include + + + +UndoStackItem::UndoStackItem() : ListItem() +{ + description = 0; +} + +UndoStackItem::~UndoStackItem() +{ + delete [] description; +} + +void UndoStackItem::set_description(char *description) +{ + this->description = new char[strlen(description) + 1]; + strcpy(this->description, description); +} + +void UndoStackItem::undo() +{ +} + +void UndoStackItem::redo() +{ +} + +int UndoStackItem::get_size() +{ + return 0; +} diff --git a/cinelerra/undostackitem.h b/cinelerra/undostackitem.h new file mode 100644 index 00000000..669bd6ed --- /dev/null +++ b/cinelerra/undostackitem.h @@ -0,0 +1,34 @@ +#ifndef UNDOSTACKITEM_H +#define UNDOSTACKITEM_H + +#include "linklist.h" + + +class UndoStackItem : public ListItem +{ +public: + UndoStackItem(); + virtual ~UndoStackItem(); + + void set_description(char *description); + +// These two virtual functions allow derived objects to be pushed +// on to the undo stack that are more efficient in time and memory +// usage than the default action of saving before and after copies +// of the EDL. + virtual void undo(); + virtual void redo(); + +// Return the amount of memory used for the data associated with this +// object in order to enable limiting the amount of memory used by the +// undo stack. +// Ignore overhead and just report the specific data values that the +// derived object adds. + virtual int get_size(); + + +// command description for the menu item + char *description; +}; + +#endif -- 2.11.4.GIT