Main Page | Namespace List | Class Hierarchy | Class List | File List | Class Members | File Members

Undo.h

Go to the documentation of this file.
00001 
00002 // Name:        Undo.h
00003 // Purpose:     
00004 // Author:      Joe Yates
00005 // Modified by:
00006 // Created:     11/10/2004
00007 // RCS-ID:      $Id: Undo.h,v 1.1.1.1 2006/01/24 22:13:19 titusd Exp $
00008 // Copyright:   (c) BID Snc
00009 // License:     BSD license (see the file 'LICENSE.txt')
00011 
00012 #ifndef __Undo_h__
00013 #define __Undo_h__
00014 
00015 // undo is a template class that maintains a dual undo/redo stack.
00016 // The items on the stack are of type 'Type', user-defined.
00017 // The stack itself is actually an STL vector containing both undo and redo items.
00018 // The variable m_uiWaterline is the indicator of the division between the undo and the redo items.
00019 
00020 #include <vector>
00021 
00022 namespace Undo
00023 {
00024 
00025 template<typename Type>
00026 class Stack
00027   {
00028   public:
00029     Stack() :
00030       m_uiWaterline(0)
00031       {
00032       Clear();
00033       }
00034 
00035     virtual ~Stack()
00036       {
00037       Clear();
00038       }
00039 
00040     virtual void Clear()
00041       {
00042       int nCount = m_v.size();
00043       if(nCount > 0)
00044         m_v.clear();
00045       m_uiWaterline = 0;
00046       }
00047 
00048     virtual void Add(Type typ)
00049       {
00050       // Clear all redo elements
00051       m_v.erase(m_v.begin() + m_uiWaterline, m_v.end());
00052       // Add the new element
00053       m_v.push_back(typ);
00054       m_uiWaterline++;
00055       }
00056 
00057     bool CanUndo()
00058       {
00059       unsigned int uiSize = m_v.size();
00060       return (m_uiWaterline > 0) ? true : false;
00061       }
00062 
00063     bool CanRedo()
00064       {
00065       unsigned int uiSize = m_v.size();
00066       return (m_uiWaterline < uiSize)? true : false;
00067       }
00068 
00069     Type Undo()
00070       {
00071       if(!CanUndo())
00072         throw "Undo called on empty undo stack";
00073       
00074       m_uiWaterline--;
00075       Type typ = m_v.at(m_uiWaterline);
00076       return typ;
00077       }
00078 
00079     Type Redo()
00080       {
00081       if(!CanRedo())
00082         throw "Stack::Redo() called on empty stack";
00083 
00084       m_uiWaterline++;
00085       Type typ = m_v.at(m_uiWaterline - 1);
00086       return typ;
00087       }
00088 
00089   protected:
00090     std::vector<Type> m_v;
00091     unsigned int      m_uiWaterline;
00092   };
00093 
00094 template <typename Type>
00095 class DeletingStack : public Stack<Type>
00096   {
00097   // friends, classes, enums and types
00098   public:
00099     typedef typename std::vector<Type>::const_iterator ConstantIterator;
00100   private:
00101     typedef typename std::vector<Type>::iterator Iterator;
00102 
00103   // Constructors/destructors
00104   public:
00105     DeletingStack()
00106       {}
00107     virtual ~DeletingStack()
00108       {
00109       Clear();
00110       }
00111 
00112   // Operators
00113   // Methods
00114   public:
00115     virtual void Clear(void)
00116       {
00117       for(Iterator it = this->m_v.begin(); it != this->m_v.end(); it++)
00118         delete *it;
00119       
00120       int nCount = this->m_v.size();
00121       if(nCount > 0)
00122         this->m_v.clear();
00123       this->m_uiWaterline = 0;
00124       }
00125 
00126     virtual void Add(Type typ)
00127       {
00128       // Remove items above waterline
00129       for(Iterator it = this->m_v.begin() + this->m_uiWaterline; it != this->m_v.end(); it++)
00130         delete *it;
00131 
00132       // Clear all redo elements
00133       this->m_v.erase(this->m_v.begin() + this->m_uiWaterline, this->m_v.end());
00134       // Add the new element
00135       this->m_v.push_back(typ);
00136       this->m_uiWaterline++;
00137       }
00138 
00139     virtual void Replace(Type typFind, Type typReplace)
00140       {
00141       for(Iterator it = this->m_v.begin(); it != this->m_v.end(); it++)
00142         {
00143         if(*it == typFind)
00144           {
00145           delete *it;
00146           *it = typReplace;
00147           return;
00148           }
00149         }
00150 
00151       throw "DeletingStack::Replace() Find item is not in stack";
00152       }
00153   };
00154 
00155 } // namespace Undo
00156 
00157 #endif // ndef __Undo_h__

Generated on Wed Jan 25 08:14:45 2006 for Sherpa by doxygen 1.3.6