• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: NSUndoManager & NSTableView editing
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: NSUndoManager & NSTableView editing


  • Subject: Re: NSUndoManager & NSTableView editing
  • From: James DiPalma <email@hidden>
  • Date: Thu, 26 Sep 2002 17:35:08 -0400

From: Pete Yandell <email@hidden>

A problem occurs when you do this: double click a row to edit it, change the text, then click the button to add a row. The edited row is changed and a new row is added, but the undo events for both these things are grouped together because they both occur within the one runloop. Choosing Undo in the Edit menu will then undo both in one hit, whereas they should be separate undo events.

Tricky problem. You clearly don't have a problem getting your textfield to end editing since your problem is isolating these two undoable events. Without having tried Hannes's suggestion, I think it will work for your specific case.

However, a more general problem exists where a single event (like clicking a button) can cause a field editor in your application (may not even be in button's window) to end editing. I tried to solve this problem well over a year ago and never found a good general solution and don't remember much about how everything works.

Some observations:

1. If an undo event is registered, NSUndoManager's endUndoGrouping will always get called when returning to your runloop (even if groupingLevel == 0). If no undo grouping exists at this point (because you ended it somewhere like tableView:setObjectValue:forTableColumn:row:), you will raise an exception (*1).

2. NSUndoManager will only open 1 undo group for each loop of a run loop. This undo group actually opens when someone registers this loops first undo event (*2). Once this undo group is begun, registering new undo events will not open a new undo group even after an endUndoGrouping. An exception raises when registering undo operations with no open undo grouping (*3).

3. If you call endUndoGrouping for an undo group that has no registered undo events, you will end up with an undo on your stack that does nothing (verified on 10.2). NSUndoManager appears to have no public way of getting a notification when undo operations are registered, nor does it have any public way to detect if a current undo grouping has undo operations.

a) use setGroupsByEvent:NO on my NSUndoManager and do any event grouping manually? Seems like that could get painful pretty quickly, but I haven't written much code for the undo manager yet, so I'm not sure how painful.

This might be your solution. I have avoided this solution because I'm working on a framework and don't want to require all applications that use this framework to be burdened with grouping their own events because text editing can sometimes wrongly group action into one undo.

I would like to find some way to get NSUndoManager to begin a new undo grouping after an endUndoGrouping. Then to fix your problem a call to endUndoGrouping during any action message that handles endEditing of text will isolote related undo operations.

But, I can't figure out how to use a poseAs: to change this behavior given where/how NSUndoManager calls beginUndoGrouping (*2); there must be some state variable used to detect when registering an undo operation triggers a beginUndoGrouping. I've tried [undoManager setGroupsByEvent:NO];[undoManager setGroupsByEvent:YES]; which doesn't do anything.

I gave up trying to solve this problem; hope you have better luck...



-jim


(*1) Here is that exception: 2002-09-26 16:34:56.339 Number[3755] *** Uncaught exception: <NSInternalInconsistencyException> endUndoGrouping: NSUndoManager 0x1ca1b0 is in invalid state, endUndoGrouping called with no matching begin

(*2) I set a breakpoint at beginUndoGrouping. My test application stopped at this line:
[[self undoManager] registerUndoWithTarget:self selector:@selector(setNumber:) object:number];
and had this stack trace (I can't explain how registerUndoWithTarget turns into _registerUndoObject:):
#0 0x908368d4 in -[NSUndoManager beginUndoGrouping] ()
#1 0x908366cc in -[NSUndoManager(NSUndoManagerPrivate) _registerUndoObject:] ()
#2 0x000044d0 in -[NumberModel setNumber:] () at NumberModel.m:61

(*3) Here is that exception: 2002-09-26 16:34:56.337 Number[3755] _registerUndoObject:: NSUndoManager 0x1ca1b0 is in invalid state, must begin a group before registering undo
_______________________________________________
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.
References: 
 >NSUndoManager & NSTableView editing (From: Pete Yandell <email@hidden>)

  • Prev by Date: Re: nil messaging? Is it safe?
  • Next by Date: Re: NSUndoManager & NSTableView editing
  • Previous by thread: Re: NSUndoManager & NSTableView editing
  • Next by thread: Re: NSUndoManager & NSTableView editing
  • Index(es):
    • Date
    • Thread