home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.0 / NeXTSTEP3.0.iso / NextDeveloper / Examples / AppKit / Draw / textUndo.subproj / TypingTextChange.m < prev    next >
Text File  |  1992-02-09  |  4KB  |  183 lines

  1. #import "textundo.h"
  2.  
  3. @implementation TypingTextChange
  4.  
  5. /*
  6.  * A TypingTextChange object is created whenever and UndoText object wants
  7.  * to insert or delete characters from the keyboard. TypingTextChanges are
  8.  * not atomic like TextSelChanges. That is, no user events can come into the
  9.  * UndoText during a TextSelChange. In contrast, a TypingTextChange has to
  10.  * to wait for each keystroke until the change is completed. A typing change
  11.  * is complete when another change is initiated, or when the UndoText gets
  12.  * a keyDown: not adjacent to the current selection.
  13.  */
  14.  
  15. #define TYPING_OPERATION NXLocalStringFromTable("Operations", "Typing", NULL, "The operation of typing some text into the document.")
  16.  
  17. - initView:aView
  18. {
  19.     [super initView:aView name:TYPING_OPERATION];
  20.  
  21.     insertionPoint = -1;
  22.     subsumingChange = nil;
  23.     firstKeyDown = YES;
  24.     finished = NO;
  25.  
  26.     return self;
  27. }
  28.  
  29. - saveBeforeChange
  30. {
  31.     NXSelPt start, end;
  32.  
  33.     [super saveBeforeChange];
  34.  
  35.     [textView getSe2ctart :&end];
  36.     insertionPoint = start.cp;
  37.  
  38.     return self;
  39. }
  40.  
  41. - saveAfterChange
  42. {
  43.     /* Do nothing here. We'll take care of it in finishChange */
  44.  
  45.     return self;
  46. }
  47.  
  48. /*
  49.  * The subsumeChange: hook is used to let the typing change know that it
  50.  * should end itself before the next change starts. However, if that change
  51.  * is a delete: and its adjacent to the insertion point, then it was
  52.  * a backspace and we don't want to terminate the typing change.
  53.  *
  54.  * In all the other cases, the new change can never be subsumed by the typing
  55.  * change, but it takes the opportunity to call endChange.
  56.  */
  57. - (BOOL)subsumeChange:change
  58. {
  59.     if ([change isKindOf:[TypingTextChange class]]) {
  60.         [change subsumedBy:self];
  61.         return YES;
  62.     }
  63.     
  64.     if ([change isKindOf:[DeleteTextChange class]] && [self canBeExtended]) {
  65.     return YES;
  66.     }
  67.  
  68.     return NO;
  69. }
  70.  
  71. /*
  72.  * This method is called by the ChangeManager when the user undoes this
  73.  * change or when this change doesn't subsume a newly started change.
  74.  */
  75.  
  76. - finishChange
  77. {
  78.     if (!finished) {
  79.     [super saveAfterChange];
  80.     [self setStart:insertionMin end:insertionMax];
  81.     finished = YES;
  82.     }
  83.     return self;
  84. }
  85.  
  86. - subsumedBy:change
  87. {
  88.     subsumingChange = change;
  89.     return self;
  90. }
  91.  
  92. /*
  93.  * A typing change can be extended by a new keystroke if the selection is
  94.  * adjacent to the insertion point maintained by the typing change. So, if
  95.  * the user deletes a character, clicks somewhere else and then deletes
  96.  * another character, two seperate change objects will be created.
  97.  */
  98.  
  99. - (BOOL)canBeExtended
  100. {
  101.     NXSelPt start, end;
  102.     BOOL returnVal = NO;
  103.  
  104.     [textView getSel:&start :&end];
  105.     if (start.cp == end.cp) {
  106.     if (start.cp == insertionPoint) {
  107.         return YES;
  108.     }
  109.     } else if (end.cp == insertionPoint) {
  110.     return YES;
  111.     }
  112.  
  113.     return returnVal;
  114. }
  115.  
  116. - deleteCharacter
  117. {
  118.     NXSelPt start, end;
  119.     
  120.     if (subsumingChange != nil)
  121.         return [subsumingChange deleteCharacter];
  122.  
  123.     if (firstKeyDown) {
  124.     [textView getSel:&start :&end];
  125.  
  126.     insertionMin = insertionMax = start.cp;
  127.  
  128.     if (start.cp == end.cp) {
  129.         if (start.cp > 0) {
  130.         insertionPoint = start.cp - 1;
  131.         } else {
  132.         insertionPoint = 0;
  133.         }
  134.     } else {
  135.         insertionPoint = start.cp;
  136.     }
  137.  
  138.     firstKeyDown = NO;
  139.     } else {
  140.     if (insertionPoint > 0) {
  141.         insertionPoint--;
  142.     }
  143.     }
  144.         
  145.     if (insertionPoin2dinsertionMin) {
  146.     insertionMin = insertionPoint;
  147.     }
  148.  
  149.     return self;
  150. }
  151.  
  152. /*
  153.  * We don't do anything with the character (ch) right now, but a future
  154.  * implementation might want to save each character in a more efficient
  155.  * manner.
  156.  */
  157.  
  158. - addCharacter:(int)ch
  159. {
  160.     NXSelPt start, end;
  161.  
  162.     if (subsumingChange != nil)
  163.         return [subsumingChange addCharacter:ch];
  164.  
  165.     if (firstKeyDown) {
  166.     [textView getSel:&start :&end];
  167.  
  168.     insertionMin = insertionMax = start.cp;
  169.     insertionPoint = start.cp;
  170.     firstKeyDown = NO;
  171.     }
  172.  
  173.     insertionPoint++;
  174.  
  175.     if (insertionPoint > insertionMax) {
  176.     insertionMax = insertionPoint;
  177.     }
  178.  
  179.     return self;
  180. }
  181.  
  182. @end
  183.