Making undo work with complicated NSTextView subclass
Making undo work with complicated NSTextView subclass
- Subject: Making undo work with complicated NSTextView subclass
- From: "Micah Wylde" <email@hidden>
- Date: Sun, 6 Jan 2008 02:12:55 -0800
I have been trying to make this work for weeks now without avail, and I now
turn to the world at large hoping someone has dealt with the same issues.
I'm working on a core data document-based application. For it I have created
a very complicated NSTextView subclass (about 700 lines of code), which
allows for proper outlining (i.e., nested lists). The most complicated part
of this subclass is the keyDown method, which changes the NSTextStore
primarily by changing the selection and calling [super keyDown], setting
attributes using setAttributes:range: on the text store, using several
string changing methods on the NSTextStore's mutableString method and in a
few cases setting a new NSAttributedString using the text store's
setAttributedString method.
All of these modifications muck with the text view's undo system, and I've
been unable to make it act nicely with them, with the result that some undos
throw errors (generally -[NSBigMutableString characterAtIndex:]: Range or
index out of bounds) while others proceed but restore the text completely
wrong. The apple documentation on subclassing
NSTextView<http://developer.apple.com/documentation/Cocoa/Conceptual/TextEditing/Tasks/Subclassing.html>says:
> In actually making changes to the text, you must ensure that the changes
> are properly performed and recorded by different parts of the text system.
> You do this by bracketing each batch of potential changes with
> shouldChangeTextInRange:replacementString: and didChangeText messages.
> These methods ensure that the appropriate delegate messages are sent and
> notifications posted. The first method asks the delegate for permission to
> begin editing with a textShouldBeginEditing: message. If the delegate
> returns NO<http://developer.apple.com/documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html#//apple_ref/doc/c_ref/NO>
> , shouldChangeTextInRange:replacementString: in turn returns NO<http://developer.apple.com/documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html#//apple_ref/doc/c_ref/NO>,
> in which case your subclass should disallow the change. If the delegate
> returns YES<http://developer.apple.com/documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html#//apple_ref/doc/c_ref/YES>,
> the text view posts an NSTextDidBeginEditingNotification, and
> shouldChangeTextInRange:replacementString: in turn returns YES<http://developer.apple.com/documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html#//apple_ref/doc/c_ref/YES>.
> In this case you can make your changes to the text, and follow up by
> invoking didChangeText. This method concludes the changes by posting an
> NSTextDidChangeNotification, which results in the delegate receiving a
> textDidChange: message.
however calling these methods doesn't seem to fix my issues.
My basic question is this: is there a way I can make NSTextView's built-in
undo manager work for me, or am I doomed to the unpleasant task of handling
it manually?
Thanks for any help.
--
Micah Wylde
_______________________________________________
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