1#import "Testing.h" 2#import <Foundation/NSAutoreleasePool.h> 3#import <Foundation/NSUndoManager.h> 4#import <Foundation/NSNotification.h> 5#import <Foundation/NSString.h> 6 7static NSUndoManager *um; 8 9unsigned openGroupCount; 10unsigned groupingLevels[32] = {0}; 11unsigned checkPointCounter = 0; 12 13BOOL shouldBeUndoing; 14BOOL shouldBeRedoing; 15 16BOOL checkPoint; 17BOOL openUndoGroup; 18BOOL willdidUndo; 19BOOL willdidRedo; 20BOOL closeUndoGroup; 21 22BOOL gotCheckPoint; 23BOOL gotOpenUndoGroup; 24BOOL gotDidUndo; 25BOOL gotWillUndo; 26BOOL gotDidRedo; 27BOOL gotWillRedo; 28BOOL gotCloseUndoGroup; 29 30@interface Foo : NSObject 31{ 32 NSString *_foo; 33 int _number; 34} 35@end 36 37@implementation Foo 38- (id) init 39{ 40 NSNotificationCenter *nc; 41 self = [super init]; 42 um = [NSUndoManager new]; 43 nc = [NSNotificationCenter defaultCenter]; 44 [nc addObserver:self selector:@selector(checkPoint:) 45 name:NSUndoManagerCheckpointNotification object:um]; 46 [nc addObserver:self selector:@selector(openUndoGroup:) 47 name:NSUndoManagerDidOpenUndoGroupNotification object:um]; 48 [nc addObserver:self selector:@selector(didUndo:) 49 name:NSUndoManagerDidUndoChangeNotification object:um]; 50 [nc addObserver:self selector:@selector(willUndo:) 51 name:NSUndoManagerWillUndoChangeNotification object:um]; 52 [nc addObserver:self selector:@selector(didRedo:) 53 name:NSUndoManagerDidRedoChangeNotification object:um]; 54 [nc addObserver:self selector:@selector(willRedo:) 55 name:NSUndoManagerWillRedoChangeNotification object:um]; 56 [nc addObserver:self selector:@selector(closeUndoGroup:) 57 name:NSUndoManagerWillCloseUndoGroupNotification object:um]; 58 59 return self; 60} 61- (void) checkPoint:(NSNotification *)notif 62{ 63NSLog(@"%@ %d", notif, [um groupingLevel]); 64 if (checkPointCounter<sizeof(groupingLevels)) 65 groupingLevels[checkPointCounter++] = [um groupingLevel]; 66 gotCheckPoint = (checkPoint == YES); 67} 68- (void) openUndoGroup:(NSNotification *)notif 69{ 70NSLog(@"%@ %d", notif, [um groupingLevel]); 71 gotOpenUndoGroup = (openUndoGroup == YES); 72 openGroupCount++; 73} 74- (void) didUndo:(NSNotification *)notif 75{ 76 gotDidUndo = (willdidUndo == YES); 77} 78- (void) willUndo:(NSNotification *)notif 79{ 80 gotWillUndo = (willdidUndo == YES); 81} 82- (void) didRedo:(NSNotification *)notif 83{ 84 gotDidRedo = (willdidRedo == YES); 85} 86- (void) willRedo:(NSNotification *)notif 87{ 88 gotWillRedo = (willdidRedo == YES); 89} 90- (void) closeUndoGroup:(NSNotification *)notif 91{ 92NSLog(@"%@ %d", notif, [um groupingLevel]); 93 gotCloseUndoGroup = (closeUndoGroup == YES); 94 openGroupCount--; 95} 96- (void) setFooReg:(id)newFoo 97{ 98 [um registerUndoWithTarget:self selector:@selector(setFooReg:) object:_foo]; 99 _foo = newFoo; 100} 101- (void) setFooPrep:(id)newFoo 102{ 103 [[um prepareWithInvocationTarget:self] setFooPrep:_foo]; 104 ASSIGN(_foo,newFoo); 105} 106@end 107 108int main() 109{ 110 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 111 id obj = [Foo new]; 112 id one, two, three, four, five, six, seven, eight; 113 114 one = @"one"; 115 two = @"two"; 116 three = @"three"; 117 four = @"four"; 118 five = @"five"; 119 six = @"six"; 120 seven = @"seven"; 121 eight = @"eight"; 122 123 openGroupCount = 0; 124 PASS([um groupingLevel] == 0, "start at top level"); 125 [um beginUndoGrouping]; 126 PASS(groupingLevels[0] == 1, "grouping level during 1. check point"); 127 PASS(checkPointCounter == 1, "beginUndoGrouping causes one check point"); 128 PASS(openGroupCount == 2 && [um groupingLevel] == 2, 129 "implicit open when grouping by events"); 130 [um endUndoGrouping]; 131 PASS(openGroupCount == 1 && [um groupingLevel] == 1, 132 "no implicit close when grouping by events"); 133 [um endUndoGrouping]; 134 PASS(openGroupCount == 0 && [um groupingLevel] == 0, 135 "grouping level matched notifications"); 136 137 [um setGroupsByEvent: NO]; 138 139 PASS(([um groupingLevel] == 0), "level 0 before any grouping"); 140 [um beginUndoGrouping]; 141 [obj setFooReg:one]; 142 [um endUndoGrouping]; 143 144 gotWillUndo = NO; 145 willdidUndo = YES; 146 [um undo]; 147 PASS((gotWillUndo == YES), 148 "-undo posts NSUndoManagerWillUndoChangeNotification"); 149 willdidUndo = NO; 150 151 gotWillRedo = NO; 152 willdidRedo = YES; 153 [um redo]; 154 PASS((gotWillRedo == YES), 155 "-undo posts NSUndoManagerWillRedoChangeNotification"); 156 willdidRedo = NO; 157 158 gotDidUndo = NO; 159 willdidUndo = YES; 160 [um undo]; 161 PASS((gotDidUndo == YES), 162 "-undo posts NSUndoManagerDidUndoChangeNotification"); 163 willdidUndo = NO; 164 165 gotDidRedo = YES; 166 willdidRedo = YES; 167 [um redo]; 168 PASS((gotDidRedo == YES), 169 "-undo posts NSUndoManagerDidRedoChangeNotification"); 170 willdidRedo = NO; 171 172 gotOpenUndoGroup = NO; 173 openUndoGroup = YES; 174 [um beginUndoGrouping]; 175 openUndoGroup = NO; 176 PASS((gotOpenUndoGroup == YES), 177 "-beginUndoGroup sends a NSUndoManagerDidOpenUndoGroupNotification"); 178 179 [obj setFooReg:two]; 180 181 closeUndoGroup = YES; 182 gotCloseUndoGroup = NO; 183 [um endUndoGrouping]; 184 PASS((gotCloseUndoGroup == YES), 185 "-endUndoGroup sends a NSUndoManagerDidCloseUndoGroupNotification"); 186 187 PASS([um groupingLevel] == 0,"we are at level zero"); 188 189 gotCheckPoint = NO; 190 checkPoint = YES; 191 [um beginUndoGrouping]; 192 PASS(gotCheckPoint == YES,"-beginUndoGroup sends a NSUndoManagerCheckPointNotification"); 193 [obj setFooReg:three]; 194 gotCheckPoint = NO; 195 [um endUndoGrouping]; 196 PASS(gotCheckPoint == YES,"-endUndoGroup sends a NSUndoManagerCheckPointNotification"); 197 198 [pool release]; pool = nil; 199 return 0; 200} 201