diff options
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tkUndo.c | 463 |
1 files changed, 262 insertions, 201 deletions
diff --git a/generic/tkUndo.c b/generic/tkUndo.c index e543cac..64143f1 100644 --- a/generic/tkUndo.c +++ b/generic/tkUndo.c @@ -8,131 +8,154 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkUndo.c,v 1.2 2003/05/19 13:04:24 vincentdarley Exp $ + * RCS: @(#) $Id: tkUndo.c,v 1.3 2003/10/30 23:35:14 dkf Exp $ */ #include "tkUndo.h" static int UndoScriptsEvaluate _ANSI_ARGS_ ((Tcl_Interp *interp, - Tcl_Obj *objPtr, TkUndoAtomType type)); + Tcl_Obj *objPtr, TkUndoAtomType type)); /* - * TkUndoPushStack - * Push elem on the stack identified by stack. + *---------------------------------------------------------------------- + * + * TkUndoPushStack -- + * Push elem on the stack identified by stack. * * Results: - * None + * None. * * Side effects: - * None. + * None. + * + *---------------------------------------------------------------------- */ - -void TkUndoPushStack ( stack, elem ) - TkUndoAtom ** stack; - TkUndoAtom * elem; + +void +TkUndoPushStack(stack, elem) + TkUndoAtom **stack, *elem; { elem->next = *stack; *stack = elem; } /* + *---------------------------------------------------------------------- + * * TkUndoPopStack -- - * Remove and return the top element from the stack identified by - * stack. + * Remove and return the top element from the stack identified by + * stack. * * Results: - * None + * None. * * Side effects: - * None. + * None. + * + *---------------------------------------------------------------------- */ - -TkUndoAtom * TkUndoPopStack ( stack ) - TkUndoAtom ** stack ; + +TkUndoAtom * +TkUndoPopStack(stack) + TkUndoAtom **stack; { - TkUndoAtom * elem = NULL; - if (*stack != NULL ) { - elem = *stack; - *stack = elem->next; + TkUndoAtom *elem = NULL; + if (*stack != NULL) { + elem = *stack; + *stack = elem->next; } return elem; } /* + *---------------------------------------------------------------------- + * * TkUndoInsertSeparator -- - * insert a separator on the stack, indicating a border for - * an undo/redo chunk. + * Insert a separator on the stack, indicating a border for + * an undo/redo chunk. * * Results: - * None + * None. * * Side effects: - * None. + * None. + * + *---------------------------------------------------------------------- */ - -int TkUndoInsertSeparator ( stack ) - TkUndoAtom ** stack; + +int +TkUndoInsertSeparator(stack) + TkUndoAtom **stack; { - TkUndoAtom * separator; + TkUndoAtom *separator; - if ( *stack != NULL && (*stack)->type != TK_UNDO_SEPARATOR ) { - separator = (TkUndoAtom *) ckalloc(sizeof(TkUndoAtom)); - separator->type = TK_UNDO_SEPARATOR; - TkUndoPushStack(stack,separator); - return 1; - } else { - return 0; + if (*stack!=NULL && (*stack)->type!=TK_UNDO_SEPARATOR) { + separator = (TkUndoAtom *) ckalloc(sizeof(TkUndoAtom)); + separator->type = TK_UNDO_SEPARATOR; + TkUndoPushStack(stack,separator); + return 1; } + return 0; } /* + *---------------------------------------------------------------------- + * * TkUndoClearStack -- - * Clear an entire undo or redo stack and destroy all elements in it. + * Clear an entire undo or redo stack and destroy all elements in it. * * Results: - * None + * None. * * Side effects: - * None. + * None. + * + *---------------------------------------------------------------------- */ -void TkUndoClearStack ( stack ) - TkUndoAtom ** stack; /* An Undo or Redo stack */ +void +TkUndoClearStack(stack) + TkUndoAtom **stack; /* An Undo or Redo stack */ { - TkUndoAtom * elem; - - while ( (elem = TkUndoPopStack(stack)) ) { - if ( elem->type != TK_UNDO_SEPARATOR ) { - Tcl_DecrRefCount(elem->apply); - Tcl_DecrRefCount(elem->revert); - } - ckfree((char *)elem); + TkUndoAtom *elem; + + while ((elem = TkUndoPopStack(stack)) != NULL) { + if (elem->type != TK_UNDO_SEPARATOR) { + Tcl_DecrRefCount(elem->apply); + Tcl_DecrRefCount(elem->revert); + } + ckfree((char *)elem); } *stack = NULL; } /* + *---------------------------------------------------------------------- + * * TkUndoPushAction - * Push a new elem on the stack identified by stack. - * action and revert are given through Tcl_Obj's to which - * we will retain a reference. (So they can be passed in - * with a zero refCount if desired). + * Push a new elem on the stack identified by stack. + * action and revert are given through Tcl_Obj's to which + * we will retain a reference. (So they can be passed in + * with a zero refCount if desired). * * Results: - * None + * None. * * Side effects: - * None. + * None. + * + *---------------------------------------------------------------------- */ - -void TkUndoPushAction ( stack, actionScript, revertScript, isList ) - TkUndoRedoStack *stack; /* An Undo or Redo stack */ - Tcl_Obj *actionScript; /* The script to get the action (redo) */ - Tcl_Obj *revertScript; /* The script to revert the action (undo) */ - int isList; /* Are the given objects lists of scripts? */ + +void +TkUndoPushAction(stack, actionScript, revertScript, isList) + TkUndoRedoStack *stack; /* An Undo or Redo stack */ + Tcl_Obj *actionScript; /* The script to get the action (redo) */ + Tcl_Obj *revertScript; /* The script to revert the action (undo) */ + int isList; /* Are the given objects lists of scripts? */ { - TkUndoAtom * atom; + TkUndoAtom *atom; atom = (TkUndoAtom *) ckalloc(sizeof(TkUndoAtom)); if (isList) { @@ -150,24 +173,29 @@ void TkUndoPushAction ( stack, actionScript, revertScript, isList ) TkUndoPushStack(&(stack->undoStack), atom); TkUndoClearStack(&(stack->redoStack)); } - /* + *---------------------------------------------------------------------- + * * TkUndoInitStack - * Initialize a new undo/redo stack + * Initialize a new undo/redo stack. * * Results: - * un Undo/Redo stack pointer + * An Undo/Redo stack pointer. * * Side effects: - * None. + * None. + * + *---------------------------------------------------------------------- */ - -TkUndoRedoStack * TkUndoInitStack ( interp, maxdepth ) - Tcl_Interp * interp; /* The interpreter */ - int maxdepth; /* The maximum stack depth */ + +TkUndoRedoStack * +TkUndoInitStack(interp, maxdepth) + Tcl_Interp *interp; /* The interpreter */ + int maxdepth; /* The maximum stack depth */ { - TkUndoRedoStack * stack; /* An Undo/Redo stack */ + TkUndoRedoStack *stack; /* An Undo/Redo stack */ + stack = (TkUndoRedoStack *) ckalloc(sizeof(TkUndoRedoStack)); stack->undoStack = NULL; stack->redoStack = NULL; @@ -176,153 +204,178 @@ TkUndoRedoStack * TkUndoInitStack ( interp, maxdepth ) stack->depth = 0; return stack; } - /* + *---------------------------------------------------------------------- + * * TkUndoInitStack - * Initialize a new undo/redo stack + * Initialize a new undo/redo stack. * * Results: - * un Undo/Redo stack pointer + * An Undo/Redo stack pointer. * * Side effects: - * None. + * None. + * + *---------------------------------------------------------------------- */ - -void TkUndoSetDepth ( stack, maxdepth ) - TkUndoRedoStack * stack; /* An Undo/Redo stack */ - int maxdepth; /* The maximum stack depth */ + +void +TkUndoSetDepth(stack, maxdepth) + TkUndoRedoStack *stack; /* An Undo/Redo stack */ + int maxdepth; /* The maximum stack depth */ { - TkUndoAtom * elem; - TkUndoAtom * prevelem; + TkUndoAtom *elem, *prevelem; int sepNumber = 0; - + stack->maxdepth = maxdepth; - if ((stack->maxdepth > 0) && (stack->depth > stack->maxdepth)) { - /* Maximum stack depth exceeded. We have to remove the last compound - elements on the stack */ - elem = stack->undoStack; - prevelem = NULL; - while ( sepNumber <= stack->maxdepth ) { - if (elem != NULL && (elem->type == TK_UNDO_SEPARATOR) ) { - sepNumber++; - } - prevelem = elem; - elem = elem->next; - } - prevelem->next = NULL; - while ( elem ) { - prevelem = elem; - elem = elem->next; - ckfree((char *) elem); - } - stack->depth = stack->maxdepth; + if (stack->maxdepth>0 && stack->depth>stack->maxdepth) { + /* + * Maximum stack depth exceeded. We have to remove the last + * compound elements on the stack + */ + + elem = stack->undoStack; + prevelem = NULL; + while (sepNumber <= stack->maxdepth) { + if (elem!=NULL && elem->type==TK_UNDO_SEPARATOR) { + sepNumber++; + } + prevelem = elem; + elem = elem->next; + } + prevelem->next = NULL; + while (elem != NULL) { + prevelem = elem; + elem = elem->next; + ckfree((char *) elem); + } + stack->depth = stack->maxdepth; } } - /* + *---------------------------------------------------------------------- + * * TkUndoClearStacks - * Clear both the undo and redo stack + * Clear both the undo and redo stack. * * Results: - * None + * None. * * Side effects: - * None. + * None. + * + *---------------------------------------------------------------------- */ - -void TkUndoClearStacks ( stack ) - TkUndoRedoStack * stack; /* An Undo/Redo stack */ + +void +TkUndoClearStacks(stack) + TkUndoRedoStack *stack; /* An Undo/Redo stack */ { TkUndoClearStack(&(stack->undoStack)); TkUndoClearStack(&(stack->redoStack)); stack->depth = 0; } - /* + *---------------------------------------------------------------------- + * * TkUndoFreeStack - * Clear both the undo and redo stack - * also free the memory allocated to the u/r stack pointer + * Clear both the undo and redo stack and free the memory + * allocated to the u/r stack pointer. * * Results: - * None + * None. * * Side effects: - * None. + * None. + * + *---------------------------------------------------------------------- */ - -void TkUndoFreeStack ( stack ) - TkUndoRedoStack * stack; /* An Undo/Redo stack */ + +void +TkUndoFreeStack(stack) + TkUndoRedoStack *stack; /* An Undo/Redo stack */ { TkUndoClearStacks(stack); -/* ckfree((TkUndoRedoStack *) stack); */ + /* ckfree((TkUndoRedoStack *) stack); */ ckfree((char *) stack); } - /* + *---------------------------------------------------------------------- + * * TkUndoInsertUndoSeparator -- - * insert a separator on the undo stack, indicating a border for - * an undo/redo chunk. + * Insert a separator on the undo stack, indicating a border for + * an undo/redo chunk. * * Results: - * None + * None. * * Side effects: - * None. + * None. + * + *---------------------------------------------------------------------- */ - -void TkUndoInsertUndoSeparator ( stack ) - TkUndoRedoStack * stack; + +void +TkUndoInsertUndoSeparator(stack) + TkUndoRedoStack *stack; { -/* TkUndoAtom * elem; - TkUndoAtom * prevelem; - int sepNumber = 0; -*/ - - if ( TkUndoInsertSeparator(&(stack->undoStack)) ) { - ++(stack->depth); - TkUndoSetDepth(stack,stack->maxdepth); -/* if ((stack->maxdepth > 0) && (stack->depth > stack->maxdepth)) { - elem = stack->undoStack; - prevelem = NULL; - while ( sepNumber < stack->depth ) { - if (elem != NULL && (elem->type == TK_UNDO_SEPARATOR) ) { - sepNumber++; - } - prevelem = elem; - elem = elem->next; - } - prevelem->next = NULL; - while ( elem ) { - prevelem = elem; - elem = elem->next; - ckfree((char *) elem); - } - stack->depth; - } */ + /* + * TkUndoAtom * elem; + * TkUndoAtom * prevelem; + * int sepNumber = 0; + */ + + if (TkUndoInsertSeparator(&(stack->undoStack))) { + stack->depth++; + TkUndoSetDepth(stack, stack->maxdepth); +#if 0 + if (stack->maxdepth>0 && stack->depth>stack->maxdepth) { + elem = stack->undoStack; + prevelem = NULL; + while (sepNumber < stack->depth) { + if (elem!=NULL && elem->type==TK_UNDO_SEPARATOR) { + sepNumber++; + } + prevelem = elem; + elem = elem->next; + } + prevelem->next = NULL; + while (elem) { + prevelem = elem; + elem = elem->next; + ckfree((char *) elem); + } + stack->depth; + } +#endif } } - /* + *---------------------------------------------------------------------- + * * TkUndoRevert -- - * Undo a compound action on the stack. + * Undo a compound action on the stack. * * Results: - * A TCL status code + * A Tcl status code * * Side effects: - * None. + * None. + * + *---------------------------------------------------------------------- */ - -int TkUndoRevert ( stack ) - TkUndoRedoStack * stack; + +int +TkUndoRevert(stack) + TkUndoRedoStack *stack; { - TkUndoAtom * elem; + TkUndoAtom *elem; /* insert a separator on the undo and the redo stack */ @@ -333,44 +386,49 @@ int TkUndoRevert ( stack ) elem = TkUndoPopStack(&(stack->undoStack)); - if ( elem == NULL ) { - return TCL_ERROR; + if (elem == NULL) { + return TCL_ERROR; } - if ( ( elem != NULL ) && ( elem->type == TK_UNDO_SEPARATOR ) ) { - ckfree((char *) elem); - elem = TkUndoPopStack(&(stack->undoStack)); + if (elem!=NULL && elem->type==TK_UNDO_SEPARATOR) { + ckfree((char *) elem); + elem = TkUndoPopStack(&(stack->undoStack)); } - - while ( elem && (elem->type != TK_UNDO_SEPARATOR) ) { + + while (elem!=NULL && elem->type!=TK_UNDO_SEPARATOR) { UndoScriptsEvaluate(stack->interp,elem->revert,elem->type); - - TkUndoPushStack(&(stack->redoStack),elem); - elem = TkUndoPopStack(&(stack->undoStack)); + + TkUndoPushStack(&(stack->redoStack),elem); + elem = TkUndoPopStack(&(stack->undoStack)); } - + /* insert a separator on the redo stack */ - + TkUndoInsertSeparator(&(stack->redoStack)); - - --(stack->depth); - + + stack->depth--; + return TCL_OK; } /* + *---------------------------------------------------------------------- + * * TkUndoApply -- - * Redo a compound action on the stack. + * Redo a compound action on the stack. * * Results: - * A TCL status code + * A Tcl status code * * Side effects: - * None. + * None. + * + *---------------------------------------------------------------------- */ - -int TkUndoApply ( stack ) - TkUndoRedoStack * stack; + +int +TkUndoApply(stack) + TkUndoRedoStack *stack; { TkUndoAtom *elem; @@ -382,42 +440,46 @@ int TkUndoApply ( stack ) elem = TkUndoPopStack(&(stack->redoStack)); - if ( elem == NULL ) { - return TCL_ERROR; + if (elem == NULL) { + return TCL_ERROR; } - if ( ( elem != NULL ) && ( elem->type == TK_UNDO_SEPARATOR ) ) { - ckfree((char *) elem); - elem = TkUndoPopStack(&(stack->redoStack)); + if (elem!=NULL && elem->type==TK_UNDO_SEPARATOR) { + ckfree((char *) elem); + elem = TkUndoPopStack(&(stack->redoStack)); } - while ( elem && (elem->type != TK_UNDO_SEPARATOR) ) { + while (elem!=NULL && elem->type!=TK_UNDO_SEPARATOR) { UndoScriptsEvaluate(stack->interp,elem->apply,elem->type); - - TkUndoPushStack(&(stack->undoStack), elem); - elem = TkUndoPopStack(&(stack->redoStack)); + + TkUndoPushStack(&(stack->undoStack), elem); + elem = TkUndoPopStack(&(stack->redoStack)); } /* insert a separator on the undo stack */ - + TkUndoInsertSeparator(&(stack->undoStack)); - ++(stack->depth); - + stack->depth++; + return TCL_OK; } - /* + *---------------------------------------------------------------------- + * * UndoScriptsEvaluate -- - * Execute either a single script, or a set of scripts + * Execute either a single script, or a set of scripts * * Results: - * A TCL status code + * A Tcl status code * * Side effects: - * None. + * None. + * + *---------------------------------------------------------------------- */ + static int UndoScriptsEvaluate(interp, objPtr, type) Tcl_Interp *interp; @@ -428,19 +490,18 @@ UndoScriptsEvaluate(interp, objPtr, type) int objc; Tcl_Obj **objv; int res, i; + res = Tcl_ListObjGetElements(interp, objPtr, &objc, &objv); if (res != TCL_OK) { return res; } - for (i=0;i<objc;i++) { + for (i=0 ; i<objc ; i++) { res = Tcl_EvalObjEx(interp, objv[i], TCL_EVAL_GLOBAL); if (res != TCL_OK) { - return res; + return res; } } return res; - } else { - return Tcl_EvalObjEx(interp, objPtr, TCL_EVAL_GLOBAL); } + return Tcl_EvalObjEx(interp, objPtr, TCL_EVAL_GLOBAL); } - |