Trouble overriding text editing methods
Trouble overriding text editing methods
- Subject: Trouble overriding text editing methods
- From: Gideon King <email@hidden>
- Date: Mon, 19 Apr 2004 18:04:33 +1000
I'm having a couple of problems with overriding the default text
behavior in a text view. The problem is that I need to adjust both the
range that the change is happening over, and the text that is put in
its place under certain circumstances. I found that just overriding it
at the text storage level didn't work because if the text storage
changed a different range than that "approved" by the text view (by
shouldChangeTextInRange...), the undo system would get all out of sync.
What I am doing is that I am overriding the following items in my
textview subclass:
insertText:
setString:
deleteBackward:
deleteForward:
These methods essentially do the following sort of behavior (this
example taken from insertText: and modified to show the behind the
scenes stuff that I actually do in the text storage)
NSRange selRange = [self selectedRange];
NSDictionary *attrs;
if (selRange.location == NSNotFound ||
(selRange.length == 0 && selRange.location == [[self
textStorage] length])) {
// We need to use the typing attributes
attrs = [self typingAttributes];
} else {
attrs = [[self textStorage] attributesAtIndex:selRange.location
effectiveRange:NULL];
}
replacementRange = // Calculate the actual range for the text
replace
replacementString = // Work out what the actual replacement string
has to be
// We know that this will be approved, so don't need to take notice
of the result, but
// it appears to have to be done so that undo works properly
[self shouldChangeTextInRange:replacementRange
replacementString:replacementString];
[[self textStorage] beginEditing];
[[self textStorage] replaceCharactersInRange:replacementRange
withString:replacementString];
(which calls edited:NSTextStorageEditedCharacters
range:replacementRange changeInLength:[contents length] - origLen];
[[self textStorage] endEditing];
[tv didChangeText];
NSRange newRange = NSMakeRange(replacementRange, [replacementString
length]);
if (!attrs) {
attrs = // some standard formatting attributes
}
[self shouldChangeTextInRange:newRange replacementString:nil];
[[self textStorage] beginEditing];
[[self textStorage] setAttributes:attrs range:newRange];
[[self textStorage] endEditing];
[self didChangeText];
[self setTypingAttributes:attrs];
[self scrollRangeToVisible:[self selectedRange]];
Now this approach seems to work in most cases and most respects, but
there are a few problems I have come across:
1. When I undo the changes, they are not globbed together as they
normally would be for text edits - each character change is undone
individually. Does anyone know what triggers the text system to begin a
new undo group? I know it is triggered when a non-text undo operation
is entered on to the undo stack, but that would not seem to be the case
in this instance.
2. When I do a deleteForward, and my behind the scenes stuff extends
the range and replacement characters, the internals of the text editing
system seem to go into an endless loop in
[NSMutableAttributedString(NSMutableAttributedStringKitAdditions)
fixFontAttributeInRange:]. This occurs when the new selection crosses a
paragraph boundary.
3. This is used in a multi-page document (using the TextEdit model),
and when it wraps on to another page, it throws an exception ***
NSRunStorage, _NSBlockNumberForIndex(): index (361) beyond array bounds
(0), which I presume is because the affected textview is now the new
one - does this mean that I need to use textViewForBeginningOfSelection
to do the end editing even if I did the begin editing on the previous
text view?
4. Occasionally I get an out of range type error (but that may be
somewhere else in my code that is triggering that one)
All this means that what I thought would be a fairly straightforward
way of accomplishing what I needed to do has turned out to be more
difficult and error prone than I had thought.
Can anyone help with any of the above items, or suggest a different
approach which would be better? This is one of the few remaining bugs I
need to fix before a new release, so any help would be appreciated.
Thanks
Gideon.
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.