Question

I've been implimenting undo features for my cocoa app (OS 10.9), and I have successfully implemented an instance of an undo feature using NSUndoManager. However, I cannot get the "Undo" text to change under the edit menu! I am using the setActionName method as detailed in Apple's docs. My relevant method:

- (void)FinishEditingName {

[[self UndoManager] registerUndoWithTarget:[self TestObject] selector:@selector(setName:) object:[NSString stringWithFormat:@"Testing Undo!"]];
[[self UndoManager] setActionName:@"Edit Name"];

[[self TestObject] setName:[NSString stringWithFormat:@"New Name"]];

NSLog([NSString stringWithFormat:@"%@",[[self UndoManager] undoActionName]]);

}

Again, the undo works perfectly, i.e. [[self TestObject] Name] is set "New Name" on calling this method, selecting Edit -> Undo changes this to "Testing Undo!". However, the Edit menu's first entry should change to the text "Undo Edit Name", but it doesn't, it just stays as "Undo". As you can see, I've confirmed that the text should change by spitting it out with NSLog(), which works just fine (i.e. it gives "Edit Name"). What am am missing here? Do I need to link the NSUndoManager to the NSMenu somehow? If so, this is missing from the docs!

Thanks in advance!

Was it helpful?

Solution

The problem is I am not using NSDocument, in which case the link between the menu and the NSUndoManager is not set up automatically - you need to handle it yourself. This appears to be in the NSDocument docs, but not in the NSUndoManager docs, where, IMO, it should be noted. Thanks for trying to help!

OTHER TIPS

Ok, I’m not actually sure what the issue is here, but there are two relevant things you should know about NSUndoManager:

⑴ There can be multiple undoManagers in a single app, and in fact usually there are. For instance, when the user is editing text in a textField, the textField normally uses its own personal undoManager for undoing typing and editing, and not the document’s undoManager. This is so that, after the user accepts her entry, there aren’t a bunch of spurious undo actions on the document undo stack. (e.g.: “undo type one letter” “undo type another letter” “undo type the third letter”), instead there’s just a nice “undo changes to that text field.”

So if you’re setting the name of, say, the final event in the textField’s undoManager, it won’t show up in the document’s undoManager—they aren’t linked in any way.

⑵ Undos can be nested in subgroups within the undoManager, and it may be the case if you set the name in a nested group the name doesn’t automatically bubble up to the top level at the end of the event (but I’m not positive of this). I don’t see any nesting here but it’s worth mentioning. There’s an implicit undo group started at the beginning of every event and closed at the end, so if you ever create another group then that’s a nest.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top