Unlimited Undos For Text Fields
Mac OS 9 Mac OS X Windows Linux

For those who like unlimited undos (or is it ram limited undos?) an undo framework starter for text in fields.

This script can be placed in a stack script and will act on all (editable) fields.

Drag-dropping text from one field to the other is supported.

It is functional and tested on OS X. But for the other platforms I don't know yet.

global gHistory
local lSC,lData

on rawkeydown x
   writeHistory x
   pass rawkeydown
end rawkeydown

on dragstart
   put the selectedchunk into lSC
   pass dragstart
end dragstart

on dragend
   put the dragData["text"] into lData
   send "checkdragdata" to me in 20 millisecs
   pass dragend
end dragend

on checkdragdata
   put the selectedchunk into tSC
   get word -2 to -1 of lSC
   put word 1 to 7 of the long id of it into tFNameOrig
   get word -2 to -1 of tSC
   put word 1 to 7 of the long id of it into tFNameDest
   if tFNameOrig = tFNameDest and not (word 2 of tSC > word 4 of tSC) 
then
       put "d",lSC,tSC,hexadize(lData) & cr after gHistory[tFNameDest]
   else if tFNameOrig <> tFNameDest then
     delete word 3 to 4 of lSC
     put "x",lSC,hexadize(lData) & cr after gHistory[tFNameOrig]
     put "v",tSC,hexadize(lData) & cr after gHistory[tFNameDest]
   end if
   put "" into lSC
   put "" into lData
end checkdragdata

### first item indicates the action
### w = write
### v = paste
### x = cut
### b = backspace
### d = dragplaced

on writeHistory x
   put the selectedchunk into tSC
   get word -2 to -1 of tSC
   put word 1 to 7 of the long id of it into tFName
   if the commandkey is down then
     switch x
     case "122"  ### z
       reverseHistory
       break
     case "118"  ### v
       put clipboardData["text"] into x
       put "v",tSC,hexadize(x) & cr after gHistory[tFName]
       break
     case "120"  ###   x
       put the value of tSC into x
       if x <> "" then
         delete word 3 to 4 of tSC
         put "x",tSC,hexadize(x) & cr after gHistory[tFName]
       end if
       break
     end switch
   else
     switch x
     case "65421" ### enter in field
     case "65307" ### escape key
     case "65308" ### scrollwheel up and down
     case "65309"
     case "65361" ### arrowkeys
     case "65363"
     case "65362"
     case "65364"
       -- do nothing
       break
     case "65288"  ### backspace
       if word 4 of tSC <> 0 then
         if word 2 of tSC < word 4 of tSC then
           get the value of tSC
           delete word 3 to 4 of tsC
         else if word 2 of tSC > word 4 of tSC then
           delete word 2 to 3 of tSC
           get the value of tsC
         end if
         put hexadize(it) into x
         put "b",tSC,x & cr after gHistory[tFName]  ## b = backspace
       end if
       break
     case "65293"  ### return in field
       delete word 3 to 4 of tSC
       put "w",tSC,hexadize(return) & cr after gHistory[tFName]
       break
     default
       delete word 3 to 4 of tSC
       put "w",tSC,hexadize(numtochar(x)) & cr after gHistory[tFName]
       break
     end switch
   end if
end writeHistory

on reverseHistory
   put word 1 to 7 of the the focusedobject into tFName
   if gHistory[tFName] = "" then
     beep
     exit reverseHistory
   end if
   get line -1 of gHistory[tFName]
   delete line - 1 of gHistory[tFName]
   switch item 1 of it
   case "b"
     put dehexadize(last item of it) into x
     if x = return then put "cr" into x
     else if x = space then put "space" into x
     else if x = tab then put "tab" into x
     else
       replace quote with quote & ""e&" & quote in x
       replace cr with quote&"&cr&"& quote in x
       put quote & x & quote into x
     end if
     do "put" &&  x  && "before" && item 2 of it
     break
   case "w"
     do "delete" && item 2 of it
     break
   case "v"
     put dehexadize(last item of it) into x
     put the num of chars in x into y
     put word 2 of item 2 of it + y - 1 into word 4 of item 2 of it
     do " delete" &&  item 2 of it
     break
   case "x"
     put dehexadize(last item of it) into x
     if x = return then put "cr" into x
     else if x = space then put "space" into x
     else if x = tab then put "tab" into x
     else
       replace quote with quote & ""e&" & quote in x
       replace cr with quote&"&cr&"& quote in x
       put quote & x & quote into x
     end if
     do " put" && x && "before" &&  item 2 of it
     break
   case "d"
     put dehexadize(last item of it) into x
     if last char of x = cr then add 1 to word 4 of item 3 of it
     if the num of lines in x > 1 then delete last char of x
     if x = return then put "cr" into x
     else if x = space then put "space" into x
     else if x = tab then put "tab" into x
     else
       replace quote with quote & ""e&" & quote in x
       replace cr with quote&"&cr&"& quote in x
       put quote & x & quote into x
     end if
     do "delete" && item 3 of it
     delete word 3 to 4 of item 2 of it
     do " put" && x && "before" &&  item 2 of it
     break
   end switch
end reverseHistory

### Big Endian BinaryDecode ###
function hexadize sx
   get binarydecode("H*", sx, x1)
   return x1
end hexadize

### Big Endian Binary Encode ###
function deHexadize sx
   replace space with "" in sx
   try
     get binaryEncode("H*", sx, x1)
   catch errornum
     put "no hex value" into it
   finally
     return it
   end try
end deHexadize

###################
## for test purposes ##
###################

on emptyHistory
   delete global  gHistory
end emptyHistory

on putHistory
   put word 1 to 7 of the the focusedobject into tFName
   if the optionkey is down then put the keys of gHistory
   else put gHistory[tFName]
end putHistory

Posted 2/24/2005 by Wouter Abraham to the Use Revolution List