Re: Live editing an NSTextView
Re: Live editing an NSTextView
- Subject: Re: Live editing an NSTextView
- From: Arved von Brasch <email@hidden>
- Date: Sun, 28 Dec 2008 11:39:47 +1100
Just a follow up: I found that calling my function using
performSelector:withObject:afterDelay: allows live editing to work as
expected and allows the undo/redo operations to work as expected. It
seems the problems with the undo stack only occur if the editing
occurs in the same event loop as the typing that just occurred.
On 2008-11-27, at 08:58 , Arved von Brasch wrote:
On 2008-11-27, at 05:57 , Douglas Davidson wrote:
On Nov 26, 2008, at 4:14 AM, Arved von Brasch wrote:
I have this working almost perfectly by listening for the
NSTextDidChangeNotification and searching the text for the special
sequence. I've found this to be the best place to handle it, so
that cut and paste operations containing the special sequence are
converted properly as well. The only problem with this is that it
completely screws up the Undo / Redo of the text view. It doesn't
seem to be possible to use the standard shouldChangeTextInRange:
and textDidChange pair, because my parser acts in response to an
edit, and this would set up an infinite loop.
You need to use the should-change/did-change calls. You can
protect against the infinite regress by keeping track of which
changes your code is making, and not doing any work when you are
notified of those particular changes. For example, you could set a
flag noting that your change is in progress, and clear it when your
change is done.
Douglas Davidson
Thank you for your response.
The trouble with this is that if the length of the replacement
substring is different from what was typed, undo/redos still don't
work as expected. Indeed they are off by the difference in length.
That is if I type a number that is two digits longer than the number
that replaces it, when undoing, two extra characters are removed
from the displayed text.
My document format has numbered lists that should be in consecutive
order. I'm trying to make it easier for users by having the program
keep track of which number the user is up to when typing, and auto-
correct for any copy and paste operations the user may perform, if
they need to reorder the items. My code called on each the
notification has this loop which does the work:
NSInteger cumulativeOffset = 0;
NSUInteger index = 1;
do {
if ([scanner scanUpToCharactersFromSet: [NSCharacterSet
newlineCharacterSet] intoString: nil] && [scanner
scanCharactersFromSet: [NSCharacterSet newlineCharacterSet]
inotString: nil]) {
scanLocation = [scanner scanLocation];
if ([scanner scanCharactersFromSet: [NSCharacterSet
decimalDigitCharacterSet] intoString: &oldNumber] && [scanner
scanString: @":" intoString: nil]) {
if (index != [[NSDecimalNumber decimalNumberWithString:
oldNumber] integerValue]) {
newNumber = [NSString stringWithFormat: @"%d", index];
range = NSMakeRange(scanLocation + cumulativeOffset, [oldNumber
length]);
if ([textView shouldChangeTextInRange: range replacementString:
newNumber]) {
[textView replaceCharactersInRange: range withString: newNumber];
// Do something here to adjust position for undos?
[textView didChangeText];
cumulativeOffset += ([newNumber length] - [oldNumber length]);
}
}
}
index++;
}
} while (![scanner isAtEnd]);
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden