|
Boost : |
From: Andreas Nicolai (Andreas.Nicolai_at_[hidden])
Date: 2003-01-23 05:13:58
Hello there!
I just wanted to ask if there would be someone interested in a framework
library for undo/redo-functionality. In other C++ groups sometimes the
question pops up, how to implement undo-functionality. Since I've written
such thing as part of a programm of mine and since I have it "boostenised"
already, I would like to introduce it briefly. Please feel free to give me
any comments about it...
Basicly there are two classes: boost::undo_list and boost::undo_action, the
latter is an abstract base class for any undo-function you want to
provide...
Instead of describing all the details I'll just give a short example of how
one could use the library...
// ----------------------------------------------------
#include <string>
#include <iostream>
using namespace std;
#include "undo_action.hpp" // class boost::undo_action
#include "undo_list.hpp" // class boost::undo_list
#include "myown_undoactions.hpp" // contains undo-action classes
int main() {
// 1. create the undo list somewhere
boost::undo_list undolist;
// 2. maybe you want to change the number of maximum undo steps
undolist.set_maxundo(100);
string teststring;
teststring = "This is a simple test of the boost undo library";
cout << "Original string: " << teststring << endl;
// Ok, someone want's to remove a part of that string.
// let's start with constructing the undo-action and adding that to
// the undo list. The class StringEraseUndo is a user defined
// undo class derived from undo_action
// 3. create and add an undo action
// NOTE: the constructor can look whatever the user wants it
// to look like (see example at end of posting)
undolist.add( new StringEraseUndo(10, 7,
teststring.substr(10, 7), teststring) );
// NOTE: All pointers added to the list make the objects
// be OWNED by the list, thus the list is responsable
// for cleaning up the memory
// 4. perform the will-be-made-undone action
// That means, let's finally delete that substring
teststring.erase(10, 7);
cout << "After erase: " << teststring << endl;
// 5. and now let's make this undone...
undolist.undo_last();
cout << "After UNDO: " << teststring << endl;
// 6. or re-done, if you like
undolist.redo_last();
cout << "After REDO: " << teststring << endl;
};
// ----------------------------------------------------
Well, it is obvious that the biggest problem in using the undo-library will
be the implementation of the user defined undo/redo-classes.
For the example above the class StringEraseUndo could look like this:
class StringEraseUndo : public undo_action {
public:
// Ctor
StringEraseUndo(std::size_t start, std::size_t size,
const std::string& snipped, std::string& str)
: start_(start), size_(size), snipped_(snipped), str_(str) {};
virtual bool undo();
virtual void redo();
private:
std::size_t start_;
std::size_t size_;
std::string snipped_;
std::string& str_;
};
bool StringEraseUndo::undo() {
str_.insert(start_, snipped_);
return true;
};
void StringEraseUndo::redo() {
str_.erase(start_, size_);
};
However, since the undo-classes can be whatever they want to be, including
non-C++-standard stuff like GUI things, this library can be used in almost
any circumstances. The Framework, that is the undo_list and the undo_action
classes can still be written in plain C++ without having to know anything
about the users environment. This clearly qualifies these classes as a
library.
Sorry for the long text, but with just describing the system shortly it
would have caused too much confusion :-)
The library itself (that is the undo_action.hpp, undo_list.hpp and
undo_list.cpp) are ready so far. Do you think this could be a useful
addition to the boost library?
Thanks for any comments!
Bye - Andreas
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk