PDA

View Full Version : Question about UndoManager




mdeh
Jul 8, 2009, 11:09 PM
I hope the word "Raiseman" does not cause too many eyes to roll ( :) ) but this is continuing the quest for Cocoa.
For those unfamiliar with Raiseman, the app is document-based, with an TableView, each of whose columns is bound to an attribute of an object in an MutableArray, all through an ArrayController.

One of the methods in MyDocument.m is this.

-(void) insertObject: (Person *) p inEmployeesAtIndex: (int) index
{
NSLog(@"Adding %@ to %@", p, employees);
NSUndoManager *undo = [ self undoManager];
[[undo prepareWithInvocationTarget:self] removeObjectFromEmployeesAtIndex:index];

if ( ![undo isUndoing])
[undo setActionName:@"Insert Person"];

[employees insertObject: p atIndex:index];
NSLog(@"Done adding person");
}

One of the things that I am puzzled about is the line if ( ![undo isUndoing])......

Hillegass says that this method is called automatically when NSArrayController wishes to insert or remove (Person) objects. (The app has an "Insert New Employee" and "Delete Employee" button, which target the controllArray's add and remove actions).

So, please excuse the very dumb question. When is this method called such that the ![undo isUndoing] returns TRUE and when does it return FALSE. I suspect the reason I am asking this is a lack of a complete conceptual understanding of how this is working.
Thanks in advance.



petron
Jul 9, 2009, 07:15 AM
Hello MDEH,
I do run through the same book and i am doing the same examples. I wondered about the same thing but have not got any good solution. I even removed lots of code from the undoing methods just to see what is going on and to understund the situation.

My assumption, not need to be right, is that this section of code blocks "reising conditions" since the operation is not atomic.

Just my reflection

/petron

Cinder6
Jul 9, 2009, 09:02 PM
Unless my understanding is completely off...

[undo isUndoing] checks to see if the NSUndoManager is currently going through the undo process--that is, if insertObject:inEmployeesAtIndex: got called by the user hitting the Undo button.

So, ![undo isUndoing] will equate to TRUE if the user inserted an employee by normal means (entering the value into the table). It'll be FALSE if the user hit undo.

What this means for you...

If you're inserting an employee the normal way, the undo manager is going to keep track of who you inserted. Since you're not undoing a removal, it'll change the NSMenuItem "undo" text to "Undo Insert Person". It won't do this if you're performing an undo.

Hope that helps.

mdeh
Jul 9, 2009, 09:09 PM
What this means for you...

If you're inserting an employee the normal way, the undo manager is going to keep track of who you inserted. Since you're not undoing a removal, it'll change the NSMenuItem "undo" text to "Undo Insert Person". It won't do this if you're performing an undo.

Hope that helps.

Yes...I think that is correct. Since posting this, I looked at the stack in the debugger, and I think it's a lot simpler than I realized. If UndoManager calls the method, it will be sent the "isUndoing" message and will answer in the affirmative.

Thanks for your answer