#include <ophist.h>
Inheritance diagram for OperationHistory:
Public Member Functions | |
OperationHistory () | |
OperationHistory (UINT32 MaximumSize) | |
Constructs an operationHistory object with a maximum size of MaximumSize bytes. | |
~OperationHistory () | |
OperationHistory destructor. | |
BOOL | SetNewMaxSize (UINT32 NewMaxSize) |
For setting a new maximum size for the operation history. | |
UINT32 | GetSize () |
For finding the current size of the operation history. | |
UINT32 | GetMaxSize () |
To find the maximum size of the operation history. | |
BOOL | ReduceSize (UINT32 MaxSize, BOOL ExcludeLastUndo, BOOL DeleteWhatYouCan=FALSE) |
Tries to Reduce the current size of the operation history so that it is at most MaxSize bytes long. The size is reduced by deleting undo operations (Oldest first), redo operations are never deleted!. If the Operation history would be larger than MaxSize bytes after deleting all undo operations, then no operations are deleted and the function returns FALSE. | |
UINT32 | GetNumUndoSteps () |
To return the number of undo steps stored in this history. | |
UINT32 | GetNumRedoSteps () |
To return the number of redo steps stored in this history. | |
BOOL | IsReduced () |
To discover if operations have been discared, reducing the number of undo/redo actions. | |
BOOL | UndoPrev () |
To UNDO the previous operation. | |
BOOL | RedoNext () |
BOOL | CanUndo () |
BOOL | CanRedo () |
void | GetUndoOpName (String_256 *OpName) |
To get the name of the currently undoable operation. | |
void | GetRedoOpName (String_256 *OpName) |
To get the name of the currently undoable operation. | |
Operation * | FindLastOp () |
This function returns a pointer to the last operation which was performed (but not undone). i.e. The NowPtr. It is provided to allow the merging of operations. NULL is returned if no such operation exists. | |
Operation * | FindPrevToLastOp () |
This function returns a pointer to the operation which was performed (and not undone) prior to the last operation. This is the op which will usually need to be changed/extended when we are merging operations. NULL is returned if no such operation exists. | |
void | DeleteLastOp (BOOL ReduceOpHistSize=TRUE) |
This function deletes the last operation which was performed. It is useful to do this after we have merged this last operation with the previous operation. The size of the Operation history is reduced by the size of this operation if the ReduceOpHistSize flag is TRUE. | |
void | DeletePrevToLastOp (BOOL ReduceOpHistSize=TRUE) |
This function deletes the previous to last operation which was performed. It is useful to do this after we have merged the last operation with the previous operation. The size of the Operation history is reduced by the size of this operation if the ReduceOpHistSize flag is TRUE. | |
void | DumpAll () |
This function displays debugging information on all the operations in the history list. | |
void | DumpLast () |
This function displays debugging information on the last operation in the operation history. This is the "current" one. | |
void | DeleteUndoableOps () |
If any undoable operations exist then the method deletes them all. | |
void | DeleteRedoableOps () |
If any redoable operations exist then the method deletes them all. | |
Private Member Functions | |
void | IncSize (UINT32 SizeIncrement) |
To increase the current size of the operation history. | |
void | DecSize (UINT32 SizeDecrement) |
To decrease the current size of the operation history. | |
void | Add (ListItem *Operation) |
To add operation Op to the operation history. At present this function also deletes all 'REDO' operations. | |
Private Attributes | |
UINT32 | MaxSize |
UINT32 | CurrentSize |
List | OpHistoryList |
ListItem * | NowPtr |
BOOL | Reduced |
Friends | |
class | ActionList |
class | Action |
class | Operation |
class | OpDeleteBitmap |
class | GlobalBitmapList |
Definition at line 141 of file ophist.h.
|
|
|
Constructs an operationHistory object with a maximum size of MaximumSize bytes.
Definition at line 204 of file ophist.cpp. 00205 { 00206 NowPtr = NULL; // History initially has no operations 00207 CurrentSize = 0; 00208 MaxSize = MaximumSize; 00209 Reduced = FALSE; 00210 }
|
|
OperationHistory destructor.
Definition at line 176 of file ophist.cpp. 00177 { 00178 //if (Action::LastDiscardableAction != NULL) 00179 // delete (Action::LastDiscardableAction); 00180 00181 // Delete all operations in the OpHistoryList 00182 // This is done using by calling the normal methods, to ensure deletion order 00183 // is correct 00184 DeleteUndoableOps(); 00185 DeleteRedoableOps(); 00186 }
|
|
To add operation Op to the operation history. At present this function also deletes all 'REDO' operations.
Definition at line 957 of file ophist.cpp. 00958 { 00959 if (NowPtr == NULL) 00960 { 00961 // There are currently no undo operations so add the new Op to the head of the 00962 // OpHistory list. 00963 NowPtr = Op; 00964 OpHistoryList.AddHead(Op); 00965 } 00966 else 00967 { 00968 // Insert the new operation after the current undoable operation 00969 OpHistoryList.InsertAfter(NowPtr, Op); 00970 // The new operation becomes the current undoable operation 00971 NowPtr = Op; 00972 } 00973 // Delete all REDOable operations for now (This may change if we start getting clever) 00974 DeleteRedoableOps(); 00975 //if (IsUserName("Simon")) 00976 //{ 00977 // TRACE( _T("Size of operation history = %lu"), CurrentSize); 00978 //} 00979 00980 }
|
|
Definition at line 684 of file ophist.cpp. 00685 { 00686 if (NowPtr == NULL) 00687 // If the NowPtr is NULL then the first redo operation will be found at the head of the 00688 // OpHistory list 00689 return (OpHistoryList.GetHead() != NULL); 00690 else 00691 // The first redo operation will be found at the node after NowPtr 00692 return ((OpHistoryList.GetNext(NowPtr)) != NULL); 00693 }
|
|
Definition at line 665 of file ophist.cpp.
|
|
To decrease the current size of the operation history.
Definition at line 333 of file ophist.cpp. 00334 { 00335 CurrentSize -= SizeDecrement; 00336 }
|
|
This function deletes the last operation which was performed. It is useful to do this after we have merged this last operation with the previous operation. The size of the Operation history is reduced by the size of this operation if the ReduceOpHistSize flag is TRUE.
Definition at line 1062 of file ophist.cpp. 01063 { 01064 Operation* pOpToDelete = FindLastOp(); 01065 01066 // The NowPtr needs to be set to the previous operation - if one exists 01067 // if not then NULL is an OK state for the NowPtr 01068 NowPtr = OpHistoryList.GetPrev(NowPtr); 01069 01070 if (ReduceOpHistSize) 01071 { 01072 DecSize(pOpToDelete->GetSize()); // Reduce history size 01073 } 01074 01075 OpHistoryList.RemoveItem((ListItem*)pOpToDelete); // Remove the operation from the 01076 // history list but don't delete it yet 01077 pOpToDelete->DeleteOnEnd(); // Mark it for deletion when it's safe 01078 // to do so. 01079 }
|
|
This function deletes the previous to last operation which was performed. It is useful to do this after we have merged the last operation with the previous operation. The size of the Operation history is reduced by the size of this operation if the ReduceOpHistSize flag is TRUE.
Definition at line 1103 of file ophist.cpp. 01104 { 01105 // find the previous operation 01106 Operation *pPrev = (Operation *)OpHistoryList.GetPrev(NowPtr); // get the PrevToLastOp 01107 01108 if (pPrev != NULL) 01109 { 01110 if (ReduceOpHistSize) 01111 { 01112 DecSize(pPrev->GetSize()); // Reduce history size 01113 } 01114 01115 // remove it from the list 01116 OpHistoryList.RemoveItem((ListItem*)pPrev); // Remove the operation from the 01117 // history list 01118 01119 // delete it 01120 delete pPrev; 01121 } 01122 }
|
|
If any redoable operations exist then the method deletes them all.
Definition at line 860 of file ophist.cpp. 00861 { 00862 #if FALSE 00863 // Removed by Jason 00864 // This was deleting backwards to the desired direction! 00865 // Direction of deletion has been reversed in the #else section below 00866 00867 /* 00868 ListItem* CurrentOp; 00869 00870 // Find the first redoable operation 00871 if (NowPtr == NULL) 00872 // If the NowPtr is NULL then the first redoable operation will be found at the 00873 // head of the OpHistoryList 00874 CurrentOp = OpHistoryList.GetHead(); // Head of list is first redoable 00875 else 00876 // The first redoable operation will be found at the node after NowPtr 00877 CurrentOp = OpHistoryList.GetNext(NowPtr); 00878 00879 // Loop while there are redo operations to delete 00880 while(CurrentOp != NULL) 00881 { 00882 ListItem* NextOp = OpHistoryList.GetNext(CurrentOp); 00883 // The size of the operation history is reduced by the size of the 00884 // deleted operation. 00885 DecSize(((Operation*)CurrentOp)->GetSize()); 00886 // Actually delete the operation 00887 delete( (Operation*)((OpHistoryList.RemoveItem(CurrentOp))) ); 00888 // Get the next op 00889 CurrentOp = NextOp; 00890 } 00891 */ 00892 #else 00893 ListItem* CurrentOp; 00894 ListItem* LastOp; 00895 00896 // Find the first redoable operation 00897 if (NowPtr == NULL) 00898 // If the NowPtr is NULL then the first redoable operation will be found at the 00899 // head of the OpHistoryList 00900 LastOp = OpHistoryList.GetHead(); // Head of list is first redoable 00901 else 00902 // The first redoable operation will be found at the node after NowPtr 00903 LastOp = OpHistoryList.GetNext(NowPtr); 00904 00905 if (LastOp == NULL) // No redo list at all 00906 return; 00907 00908 CurrentOp = OpHistoryList.GetTail(); 00909 00910 // Loop while there are redo operations to delete 00911 while(CurrentOp != LastOp) 00912 { 00913 ListItem* PrevOp = OpHistoryList.GetPrev(CurrentOp); 00914 // The size of the operation history is reduced by the size of the 00915 // deleted operation. 00916 DecSize(((Operation*)CurrentOp)->GetSize()); 00917 // Actually delete the operation 00918 delete( (Operation*)((OpHistoryList.RemoveItem(CurrentOp))) ); 00919 // Get the next op 00920 CurrentOp = PrevOp; 00921 } 00922 00923 // And also delete the last redoable op 00924 DecSize(((Operation*)LastOp)->GetSize()); 00925 delete( (Operation*)((OpHistoryList.RemoveItem(LastOp))) ); 00926 #endif 00927 }
|
|
If any undoable operations exist then the method deletes them all.
Definition at line 790 of file ophist.cpp. 00791 { 00792 #if FALSE 00793 // Removed by Jason 00794 // This was deleting backwards to the desired direction! 00795 // Direction of deletion has been reversed in the #else section below 00796 00797 /* 00798 if (NowPtr != NULL) // Undoable operations exist 00799 { 00800 ListItem* CurrentOp = NowPtr; // First undoable operation 00801 // Loop until all undoables have been deleted 00802 do 00803 { 00804 ListItem* PrevOp = OpHistoryList.GetPrev(CurrentOp); 00805 // The size of the operation history is reduced by the size of the 00806 // operation just about to be deleted. 00807 DecSize(((Operation*)CurrentOp)->GetSize()); 00808 // Actually delete the current operation 00809 delete((Operation*)(OpHistoryList.RemoveItem(CurrentOp))); 00810 // Get next op 00811 CurrentOp = PrevOp; 00812 } while (CurrentOp != NULL); 00813 NowPtr = NULL; // No undoable operations 00814 } 00815 */ 00816 #else 00817 if (NowPtr != NULL) // Undoable operations exist 00818 { 00819 ListItem* CurrentOp = OpHistoryList.GetHead(); // First undoable operation 00820 // Loop until all undoables have been deleted 00821 00822 if (CurrentOp == NULL) // No Undo records?! (Shouldn't happen if NowPtr != NULL) 00823 return; 00824 00825 do 00826 { 00827 ListItem* NextOp = OpHistoryList.GetNext(CurrentOp); 00828 // The size of the operation history is reduced by the size of the 00829 // operation just about to be deleted. 00830 DecSize(((Operation*)CurrentOp)->GetSize()); 00831 // Actually delete the current operation 00832 00833 delete((Operation*)(OpHistoryList.RemoveItem(CurrentOp))); 00834 if (CurrentOp == NowPtr) // Delete NowPtr item as well 00835 CurrentOp = NULL; // it is gone, so we MUST stop now 00836 else 00837 CurrentOp = NextOp; // Continue with the next Op 00838 00839 } while (CurrentOp != NULL); 00840 NowPtr = NULL; // No undoable operations 00841 } 00842 #endif 00843 }
|
|
This function displays debugging information on all the operations in the history list.
Definition at line 1141 of file ophist.cpp. 01142 { 01143 #if DEBUG_TREE 01144 // loop through all the ops in the history, calling their dump functions 01145 ListItem* CurrentOp = OpHistoryList.GetHead(); 01146 01147 TRACEALL( _T("******* Complete Operation history dump *******\n") ); 01148 01149 if (CurrentOp == NULL) 01150 TRACEALL( _T("No operations in history\n") ); 01151 else 01152 { 01153 do 01154 { 01155 ((Operation*)CurrentOp)->Dump(); 01156 01157 CurrentOp = OpHistoryList.GetNext(CurrentOp); 01158 } while (CurrentOp != NULL); 01159 } 01160 01161 TRACEALL( _T("******* End of history dump *******\n\n") ); 01162 01163 #endif 01164 }
|
|
This function displays debugging information on the last operation in the operation history. This is the "current" one.
Definition at line 1184 of file ophist.cpp. 01185 { 01186 #if DEBUG_TREE 01187 Operation* CurrentOp = FindLastOp(); 01188 01189 TRACEALL( _T("\n******* Dump of last operation *******\n") ); 01190 01191 if (CurrentOp == NULL) 01192 TRACE( _T("No operations in history\n") ); 01193 else 01194 CurrentOp->Dump(); 01195 01196 TRACEALL( _T("\n******* End of last operation dump *******\n\n") ); 01197 01198 #endif 01199 }
|
|
This function returns a pointer to the last operation which was performed (but not undone). i.e. The NowPtr. It is provided to allow the merging of operations. NULL is returned if no such operation exists.
Definition at line 1003 of file ophist.cpp.
|
|
This function returns a pointer to the operation which was performed (and not undone) prior to the last operation. This is the op which will usually need to be changed/extended when we are merging operations. NULL is returned if no such operation exists.
Definition at line 1029 of file ophist.cpp. 01030 { 01031 if (NowPtr != NULL) 01032 { 01033 return ((Operation*)(OpHistoryList.GetPrev(NowPtr))); 01034 } 01035 else 01036 { 01037 return NULL; 01038 } 01039 }
|
|
To find the maximum size of the operation history.
Definition at line 286 of file ophist.cpp. 00287 { 00288 return (MaxSize); 00289 }
|
|
To return the number of redo steps stored in this history.
Definition at line 389 of file ophist.cpp. 00390 { 00391 ListItem* pOp = NULL; 00392 00393 if (NowPtr == NULL) 00394 { 00395 // If Now is NULL then there are no undo operations 00396 pOp = OpHistoryList.GetHead(); 00397 } 00398 else 00399 { 00400 // Get the pointer to the operation following the NowPtr (which points at last undo op) 00401 pOp = OpHistoryList.GetNext(NowPtr); 00402 } 00403 00404 UINT32 count = 0; 00405 00406 while (pOp != NULL) 00407 { 00408 count ++; 00409 pOp = OpHistoryList.GetNext(pOp); 00410 } 00411 return count; 00412 }
|
|
To return the number of undo steps stored in this history.
Definition at line 355 of file ophist.cpp. 00356 { 00357 if (NowPtr == 0) 00358 return 0; 00359 00360 ListItem* pOp = OpHistoryList.GetHead(); 00361 00362 UINT32 count = 1; 00363 00364 while ((pOp != NowPtr) && (pOp != NULL)) 00365 { 00366 count ++; 00367 pOp = OpHistoryList.GetNext(pOp); 00368 } 00369 return count; 00370 }
|
|
To get the name of the currently undoable operation.
Definition at line 723 of file ophist.cpp. 00724 { 00725 if (NowPtr == NULL) 00726 // If the NowPtr is NULL then the first redo operation will be found at the head of the 00727 // OpHistory list 00728 ((Operation*) OpHistoryList.GetHead())->GetOpName(OpName); 00729 else 00730 // The first redo operation will be found at the node after NowPtr 00731 ((Operation*) OpHistoryList.GetNext(NowPtr))->GetOpName(OpName); 00732 }
|
|
For finding the current size of the operation history.
Definition at line 266 of file ophist.cpp. 00267 { 00268 return (CurrentSize); 00269 }
|
|
To get the name of the currently undoable operation.
Definition at line 707 of file ophist.cpp.
|
|
To increase the current size of the operation history.
Definition at line 310 of file ophist.cpp. 00311 { 00312 CurrentSize += SizeIncrement; 00313 }
|
|
To discover if operations have been discared, reducing the number of undo/redo actions.
Definition at line 432 of file ophist.cpp. 00433 { 00434 return Reduced; 00435 }
|
|
Definition at line 625 of file ophist.cpp. 00626 { 00627 ListItem* next; 00628 00629 if (NowPtr == NULL) 00630 // If the NowPtr is NULL then if there are any redo operations then the first will be 00631 // found at the head of the OpHistoryList 00632 next = OpHistoryList.GetHead(); 00633 else 00634 // The first redo operation will be found after the NowPtr 00635 next = OpHistoryList.GetNext(NowPtr); 00636 if ( next != NULL) 00637 { 00638 Operation* pOp = (Operation*)next; 00639 BROADCAST_TO_ALL(OpMsg(pOp,OpMsg::BEFORE_REDO)); 00640 // There is an operation to redo 00641 if (pOp->Redo()) // REDO the operation 00642 { 00643 NowPtr = next; 00644 BROADCAST_TO_ALL(OpMsg(((Operation*)NowPtr), OpMsg::AFTER_REDO)); 00645 return (TRUE); 00646 } 00647 } 00648 return (FALSE); // There are no operations to REDO 00649 }
|
|
Tries to Reduce the current size of the operation history so that it is at most MaxSize bytes long. The size is reduced by deleting undo operations (Oldest first), redo operations are never deleted!. If the Operation history would be larger than MaxSize bytes after deleting all undo operations, then no operations are deleted and the function returns FALSE.
DeleteWhatYouCan: If we cannot reduce the size of the operation history as low as MaxSize bytes, and this flag is TRUE, then as many ops as possible are deleted.
Definition at line 471 of file ophist.cpp. 00472 { 00473 // If the Current size of the operation history is less than or equal to MaxHistorySize then 00474 // there is no need to do anything. 00475 if ((CurrentSize <= MaxHistorySize)) 00476 return (TRUE); 00477 00478 // If The NowPtr is NULL then there are no undo operations to be deleted so return FALSE 00479 if (NowPtr == NULL) 00480 return (FALSE); 00481 00482 // Calculate how many bytes we need to reduce the size of the Operation history by 00483 UINT32 Reduction = (CurrentSize - MaxHistorySize); 00484 00485 //------------------------------------------------------------------------------- 00486 // Check if the operation history can be reduced to MaxHistorySize bytes or less 00487 00488 // The OpSize total is the count of the number of bytes we can reduce the Operation 00489 // history by. 00490 UINT32 OpSizeTotal = 0; 00491 00492 // We know that the NowPtr is not NULL so the oldest undo operation will be found at 00493 // the head of the OpHistoryList. 00494 ListItem* pOp = OpHistoryList.GetHead(); 00495 00496 // We are allowed to delete all operations from the head of the list 00497 // upto and excluding StopOp. StopOp is the last undo operation if the 00498 // ExcludeLastUndo flag is TRUE, else it is the first redo operation. 00499 ListItem* StopOp = (ExcludeLastUndo) ? NowPtr: OpHistoryList.GetNext(NowPtr); 00500 00501 00502 // Loop until we either hit StopOp or we have found enough operations to delete 00503 while ((pOp != StopOp) && (OpSizeTotal < Reduction)) 00504 { 00505 // In a sane world this should always be true 00506 ENSURE( pOp != NULL, 00507 "OperationHistory::ReduceSize: Pointer OperationHistory is NULL"); 00508 00509 // Increase the OpSizeTotal by the number of bytes of the current operation 00510 OpSizeTotal += ((Operation*)pOp)->GetSize(); 00511 00512 // Get the next operation 00513 pOp = OpHistoryList.GetNext(pOp); 00514 }; 00515 00516 //------------------------------------------------------------------------------- 00517 // Now if we can, reduce the operation history size 00518 00519 if ((OpSizeTotal >= Reduction) || (DeleteWhatYouCan && (OpSizeTotal != 0))) // The size can be reduced 00520 { 00521 // Start at the head of the OpHistoryList 00522 ListItem* pDeleteOp = OpHistoryList.GetHead(); 00523 00524 #ifdef _DEBUG 00525 UINT32 TotalChk = 0; 00526 #endif 00527 00528 while (pDeleteOp != pOp) 00529 { 00530 DecSize(((Operation*)pDeleteOp)->GetSize()); // Reduce history size 00531 00532 #ifdef _DEBUG 00533 TotalChk += ((Operation*)pDeleteOp)->GetSize(); 00534 #endif 00535 ListItem* pNextDeleteOp = OpHistoryList.GetNext(pDeleteOp); 00536 00537 // If the operation which is about to be deleted is the operation pointed to by the NowPtr 00538 // then it is the last undo operation, so set NowPtr to NULL. 00539 if (NowPtr == pDeleteOp) 00540 NowPtr = NULL; 00541 delete(OpHistoryList.RemoveItem(pDeleteOp)); // Delete the operation 00542 pDeleteOp = pNextDeleteOp; 00543 } 00544 00545 // Defensive programming 00546 00547 #ifdef _DEBUG // Required because of TotalChk variable 00548 ENSURE( OpSizeTotal == TotalChk, 00549 "OperationHistory::ReduceSize: OpSizeTotal != TotalChk"); 00550 #endif 00551 00552 00553 Reduced = TRUE; 00554 00555 return (TRUE); 00556 } 00557 else 00558 return (FALSE); // Cannot reduce size of history to MaxHistorySize bytes or less 00559 }
|
|
For setting a new maximum size for the operation history.
Definition at line 234 of file ophist.cpp. 00235 { 00236 00237 if (NewMaxSize < CurrentSize) 00238 { 00239 // We must try to reduce the current size of the OperationHistory to NewMaxSize 00240 // bytes or less. 00241 if (!ReduceSize(NewMaxSize, FALSE)) 00242 { 00243 return FALSE; 00244 } 00245 } 00246 MaxSize = NewMaxSize; 00247 return (TRUE); 00248 }
|
|
To UNDO the previous operation.
Definition at line 577 of file ophist.cpp. 00578 { 00579 //TRACE( _T("Called Undo\n")); 00580 if (NowPtr != NULL) // Check if there is an operation to UNDO 00581 { 00582 // Tell the world that the op is about to be undone 00583 BROADCAST_TO_ALL(OpMsg(((Operation*)NowPtr),OpMsg::BEFORE_UNDO)); 00584 Operation* pOp = (Operation*)NowPtr; 00585 00586 if (pOp->Undo()) // Undo the operation 00587 { 00588 ERROR3IF(NowPtr == NULL, "The operation which has just been undone has been deleted"); 00589 if (NowPtr != NULL) 00590 { 00591 // We used to find the prev op before the undo, this was wrong because it may have been deleted. 00592 NowPtr = OpHistoryList.GetPrev(NowPtr); 00593 } 00594 Operation* NextOp; 00595 if (NowPtr != NULL) 00596 { 00597 NextOp = ((Operation*)OpHistoryList.GetNext(NowPtr)); 00598 } 00599 else 00600 { 00601 NextOp = ((Operation*)OpHistoryList.GetHead()); 00602 } 00603 BROADCAST_TO_ALL(OpMsg(NextOp,OpMsg::AFTER_UNDO)); 00604 return (TRUE); 00605 } 00606 } 00607 return (FALSE); // There are no operations to UNDO, or the Operation failed to undo 00608 }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|