On Dec 6, 2009, at 5:53 AM, Graham Cox wrote: > > On 06/12/2009, at 8:12 PM, Uli Kusterer wrote: > >> I thought that was what undo groups were for? Open a group at the start of >> the drag manually, close it at the end, and everything in between gets >> lumped into one big action at the end. It may get "replayed" internally, but >> will all be triggered by one Cmd-Z. > > > Indeed, undo groups are great. Unfortunately, NSUndoManager has a bug where > if you open a group (on mouse down, say), do nothing (no drag), and close it > again (on mouse up), an empty Undo task appears in the Undo menu. It's > harmless, in that it does nothing, but it's also a nuisance, since the user > doesn't expect this and reports it as a bug with your app. It's working > around this bug that is horrible and surprisingly complicated (for two > reasons - one, you can't peek at the top of the undo stack to see what's > there and two, even if you could there's no way to tell whether the task > there is empty, because the 'tasks' are all private classes. Therefore you > have to come up with another way either to detect this case, or to prevent it > from happening. Either way, it's a complicated and nasty hack). Incidentally > I have reported this bug but it came back as a dupe. It's been there since I > started with Cocoa, on 10.2.
I ran into the same problem and my bug was also flagged as a duplicate. Here is my submission which includes my workaround: > 14-Aug-2008 09:31 AM Paul Bruneau: > * SUMMARY > When trying to utilize undo grouping using what seems to be the most > straightforward way, the undo group can be "empty" with no actions in it, yet > the system will still put this empty group into the undo stack. > > * STEPS TO REPRODUCE > In my case, I am dealing with user actions in an NSView subclass. I use > -mouseDown, -mouseDragged, and -mouseUp. > > The way that seemed at first to be best is to initiate an undo group in > -mouseDown, create undo actions during -mouseDragged, and finally to > terminate the undo grouping in -mouseUp. The user clicks objects in the view > and drags them around. This results in many operations over the course of the > dragging, all of which I want to be in one undo group. > > But if I implement my grouping code in mouseDown and mouseUp, I have the > problem where if the user just clicks on one of my objects without moving it, > the undo group is "empty", containing no actions. > > > * RESULTS > The results of this are that the empty undo group is put on the stack, and > the user can Undo it, but nothing happens (because there was no action to > undo). > > What I would like to see, is if an undo group has no actions in it, it should > be discarded. Surely this is what Cocoa does when it is doing its normal > "event loop" based grouping. It doesn't put an empty undo group into the > stack with every pass of the event loop--why does it put my empty undo group > into the stack? > > Or perhaps consider this a documentation enhancement request. Maybe there is > an easy solution for me that I don't know about. > > > * NOTES > In my particular case, I was able to perform a workaround by implementing the > -beginUndoGrouping message in my -mouseDragged method. > > By doing it this way, I am assured that the user is actually dragging around > one of the objects in my view rather that just clicking on one, or clicking a > blank area of the view. > > But it is kind of kludgy because -mouseDragged is repeatedly called while the > user is dragging. So I had to test to see if an undo group already exists > like so: > > - (void)mouseDragged:(NSEvent *)event > { > if ( dragging == YES ) > { > if ( [[myUndoManager] groupingLevel] == 0 ) > { > //start custom undo grouping > [[myUndoManager] setGroupsByEvent:NO]; > [[myUndoManager] beginUndoGrouping]; > > } > ... > > But I don't find this optimal. It would get a lot more complex if I did any > nested groups I think. _______________________________________________ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com