• 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
Confused by grouping with NSUndoManager
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Confused by grouping with NSUndoManager


  • Subject: Confused by grouping with NSUndoManager
  • From: Chris Trainor <email@hidden>
  • Date: Thu, 27 Sep 2007 23:29:34 -0400

I am having trouble getting NSUndoManager to behave the way I want it to. I want to group some actions together so that when the user selects Undo, all those actions are undone at the same time. However, it isn't as easy as just wrapping the set of actions in calls to beginUndoGrouping and endUndoGrouping, since the set of actions is not fixed. What I want to do is analogous to how most text editors work. (My app has nothing to do with editing text. This is just a convenient analogy to use.)

Undo works on word boundaries in most text editors. For example, if I type "foo bar" then Undo, the word "bar" will be removed. Undoing again will remove the entire word "foo." However, editors can also undo partial words. If I type "foo ba" then Undo, the partial word "ba" will be removed. My thinking was that the code for that would work something like this:

User types "f" - beginUndoGrouping is called to start a new group. prepareWithInvocationTarget is called with a selector to remove the letter
User types "o" - prepareWithInvocationTarget is called with a selector to remove the letter
User types "o" - prepareWithInvocationTarget is called with a selector to remove the letter
User types a space - prepareWithInvocationTarget is called with a selector to remove the letter. This is a word boundary, so endUndoGrouping is called to group the entire word together.


User types "b" - there is no open group, so beginUndoGrouping is called to start a new group. prepareWithInvocationTarget is called with a selector to remove the letter
User types "a" - prepareWithInvocationTarget is called with the selector to remove a letter
User selects Undo - here is where the trouble starts.


Apparently because the group wasn't closed, I am getting this error:

NSUndoManager 0x3ef3b0 is in invalid state, undo was called with too many nested undo groups

The documentation (which I just updated to be sure) has this description for the NSUndoManager undo method, "Closes the top-level undo group if necessary and invokes undoNestedGroup." The Discussion section for the method says "This method also invokes endUndoGrouping if the nesting level is 1."

The setGroupsByEvent: method says this, "The default is YES. If you turn automatic grouping off, you must close groups explicitly before invoking either undo or undoNestedGroup." I am not changing the default setting and I have verified that it is set to YES.

The documentation seems to be saying that what I did in the pseudo- code above should work. I can open a group, do some things, then the undo method should close the group for me. This does not appear to be what is happening.

I have tried several ways to work around this. I registered for NSUndoManagerWillUndoChangeNotification, hoping to close the group just before the undo method was called. Unfortunately, the exception happens before the notification is posted and I still get the error.

I derived my own class from NSUndoManager and overrode the undo and undoNestedGroup methods so that they closed any open groups by calling endUndoGrouping. This got rid of the error I was getting, but I ran into another problem. My document no longer accurately kept track of its dirty state. Even after undoing all the actions that were done, the document still said it needed to be saved.

If the NSUndoManager subclass is the right way to go, then I will try to fix the dirty flag problem. However, it doesn't seem like I should have to do this, since the documentation explicitly says that it is already doing it.

Either I am misunderstanding the documentation or missing something else.

Any ideas?

Thanks
_______________________________________________

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


  • Prev by Date: Re: Popup vs pull down menu item missing
  • Next by Date: Re: (NSURLDownload)The control never reaches downloadDidFinish:
  • Previous by thread: Re: NSPopUpButton in NSMatrix
  • Next by thread: Memory leak if alloc succeeds but init fails?
  • Index(es):
    • Date
    • Thread