Re: Live editing an NSTextView
Re: Live editing an NSTextView
- Subject: Re: Live editing an NSTextView
- From: Arved von Brasch <email@hidden>
- Date: Thu, 27 Nov 2008 08:58:16 +1100
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