On 03/07/2012, at 3:26 AM, Conrad Shultz wrote:

> I'll take a look at GCUndoManager. I'd heard of it being used in the context 
> of Core Data, but maybe I should consider it here too. (I hate to introduce 
> third-party dependencies unless absolutely necessary.)

It wasn't written with Core Data in mind, but some later fixes were made to 
ensure it did work with Core Data.


> I could set the action name in the model too, but that feels icky. (Do you 
> set the action name or just register undo operations in the model? I don't 
> see why action names would be needed for scripting, but then again I don't 
> really know AppleScript.)


I think your original approach is close to optimal practice; I follow this 
pattern almost always:


- (IBAction)            someAction:(id) sender
{
        [self dotheActualActionWithUndo];

        [[self undoManager] setActionName:[sender title]];
}



There's no reason to check whether the undo manager is undoing - at this point 
it can't possibly be. All the interaction with the undo manager takes place in 
the internals of the controller or data model - the undo manager will never (or 
should never) invoke an action method. Undo is never invoked on a thread other 
than main.

The undo manager is given the various tasks to do first, then the action name 
is set last. This takes care of ensuring that the undo manager has something it 
can attach the name to. I think this is the only reason you are having problems.

The action name is taken from the title of the sender (e.g. button or menu 
item). Why do this? Because it's one less bit of text to localize and the 
action appearing in Undo is fully consistent with the text in the interface. 
There are sometimes exceptions to this approach that mean you have to 
explicitly set an action name, but they shouldn't be common.

The action name should be set at the end of the highest level method that 
causes the undoable work to happen. Then, if the operation consists of several 
steps, each of which has some undoable component, the action name is attached 
to the entire group of operations. In the NSUndoManager, groups are marked 
internally using sentinel objects rather than an actual container of some sort, 
and the 'group open' marker is not added until there is a task ready to put in 
it. That means that if you try to set the action name first, there's nothing 
available to attach it to (NSUndoManager will attach it to the current group, 
but if there are no tasks, there's nothing there, and if there are, the group 
in question is the wrong one).

--Graham



_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to