Lazy undo for Arrays
Lazy undo for Arrays
- Subject: Lazy undo for Arrays
- From: Gordon Apple <email@hidden>
- Date: Sun, 23 Sep 2007 15:47:16 -0500
Using a subclass of NSArrayController for a NSTableView and wishing to
do the usual litany of edits on the array list, I was having trouble
wrapping my brain around all the possible undo scenarios. Being a strong
believer in using the same hammer to pound most nails, I came up with a
unified undo approach that may not be optimal, but seems to work quite well,
with one exception. For some reason, my attempt at restoring the undo
selection isn't working although it works for do/redo.
It works by first making two copies of the array which you want to edit
-- editArray and undoArray. You edit editArray, then replace all the
elements of the original array with those from editArray. For undo, you
replace all the original array elements with undoArray's elements. I also
pass the the old and new selections. Here is what I did:
@interface RTPArrayController : NSArrayController
{
(...)
NSArray* undoArray; // Temp array for undo memory
NSMutableArray* editArray; // Temp array to edit
// Note that these could have been locals for each method. It just
seemed more efficient to use ivars and the "prepareForUndoRedo" method.
}
(+Accesors)
@implementation RTPArrayController
(...)
- (void) prepareForUndoRedo
{
NSMutableArray* arrayToChange = (NSMutableArray*)[self arrangedObjects];
[self setUndoArray:[arrayToChange copy]]; // Temp array for undo
[self setEditArray:[arrayToChange mutableCopy]]; // Temp array
which we will edit
}
- (void)changeArray:(NSArray*)changeArray
withUndo:(NSArray*)memArray
usingName:(NSString*)name
newSelection:(NSIndexSet*)newSelects
oldSelection:(NSIndexSet*)oldSelects
{
NSUndoManager* undo = [tableView undoManager]; // There is an outlet
to tableView.
[[undo prepareWithInvocationTarget:self]changeArray:memArray
withUndo:changeArray
usingName:name
newSelection:oldSelects
oldSelection:newSelects];
[undo setActionName:name];
NSArray* arrayToChange = (NSArray*)[self arrangedObjects];
[self removeObjects:arrayToChange]; // Clear the array
[self addObjects:changeArray]; // Load new array
[self setSelectionIndexes:newSelects];
}
// This is a prototype for undoable methods
- (void)whateverEditMethod {
[self prepareForUndoRedo];
NSIndexSet* oldSelects = [self selectionIndexes];
// Do your worst to the editArray here
NSIndexSet* newSelects = whatever; // New selections
[self changeArray:editArray
withUndo:undoArray
usingName:@"Whatever"
newSelection:newSelects
oldSelection:oldSelects];
}
_______________________________________________
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