home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
NeXTSTEP 3.0
/
NeXTSTEP3.0.iso
/
NextDeveloper
/
Examples
/
AppKit
/
Draw
/
textUndo.subproj
/
TypingTextChange.m
< prev
next >
Wrap
Text File
|
1992-02-09
|
4KB
|
183 lines
#import "textundo.h"
@implementation TypingTextChange
/*
* A TypingTextChange object is created whenever and UndoText object wants
* to insert or delete characters from the keyboard. TypingTextChanges are
* not atomic like TextSelChanges. That is, no user events can come into the
* UndoText during a TextSelChange. In contrast, a TypingTextChange has to
* to wait for each keystroke until the change is completed. A typing change
* is complete when another change is initiated, or when the UndoText gets
* a keyDown: not adjacent to the current selection.
*/
#define TYPING_OPERATION NXLocalStringFromTable("Operations", "Typing", NULL, "The operation of typing some text into the document.")
- initView:aView
{
[super initView:aView name:TYPING_OPERATION];
insertionPoint = -1;
subsumingChange = nil;
firstKeyDown = YES;
finished = NO;
return self;
}
- saveBeforeChange
{
NXSelPt start, end;
[super saveBeforeChange];
[textView getSe2ctart :&end];
insertionPoint = start.cp;
return self;
}
- saveAfterChange
{
/* Do nothing here. We'll take care of it in finishChange */
return self;
}
/*
* The subsumeChange: hook is used to let the typing change know that it
* should end itself before the next change starts. However, if that change
* is a delete: and its adjacent to the insertion point, then it was
* a backspace and we don't want to terminate the typing change.
*
* In all the other cases, the new change can never be subsumed by the typing
* change, but it takes the opportunity to call endChange.
*/
- (BOOL)subsumeChange:change
{
if ([change isKindOf:[TypingTextChange class]]) {
[change subsumedBy:self];
return YES;
}
if ([change isKindOf:[DeleteTextChange class]] && [self canBeExtended]) {
return YES;
}
return NO;
}
/*
* This method is called by the ChangeManager when the user undoes this
* change or when this change doesn't subsume a newly started change.
*/
- finishChange
{
if (!finished) {
[super saveAfterChange];
[self setStart:insertionMin end:insertionMax];
finished = YES;
}
return self;
}
- subsumedBy:change
{
subsumingChange = change;
return self;
}
/*
* A typing change can be extended by a new keystroke if the selection is
* adjacent to the insertion point maintained by the typing change. So, if
* the user deletes a character, clicks somewhere else and then deletes
* another character, two seperate change objects will be created.
*/
- (BOOL)canBeExtended
{
NXSelPt start, end;
BOOL returnVal = NO;
[textView getSel:&start :&end];
if (start.cp == end.cp) {
if (start.cp == insertionPoint) {
return YES;
}
} else if (end.cp == insertionPoint) {
return YES;
}
return returnVal;
}
- deleteCharacter
{
NXSelPt start, end;
if (subsumingChange != nil)
return [subsumingChange deleteCharacter];
if (firstKeyDown) {
[textView getSel:&start :&end];
insertionMin = insertionMax = start.cp;
if (start.cp == end.cp) {
if (start.cp > 0) {
insertionPoint = start.cp - 1;
} else {
insertionPoint = 0;
}
} else {
insertionPoint = start.cp;
}
firstKeyDown = NO;
} else {
if (insertionPoint > 0) {
insertionPoint--;
}
}
if (insertionPoin2dinsertionMin) {
insertionMin = insertionPoint;
}
return self;
}
/*
* We don't do anything with the character (ch) right now, but a future
* implementation might want to save each character in a more efficient
* manner.
*/
- addCharacter:(int)ch
{
NXSelPt start, end;
if (subsumingChange != nil)
return [subsumingChange addCharacter:ch];
if (firstKeyDown) {
[textView getSel:&start :&end];
insertionMin = insertionMax = start.cp;
insertionPoint = start.cp;
firstKeyDown = NO;
}
insertionPoint++;
if (insertionPoint > insertionMax) {
insertionMax = insertionPoint;
}
return self;
}
@end