Document
1
//
2 // MyDocument.m
3 // RaiseMan
4 //
5 // Created by b1mobile on 2/14/11.
6 // Copyright 2011 __MyCompanyName__. All rights reserved.
7 //
8
9 #import " MyDocument.h "
10 #import " Person.h "
11
12 @implementation MyDocument
13
14 - (id)init
15 {
16 self = [super init];
17 employees = [[NSMutableArray alloc] init];
18 return self;
19 }
20
21 - ( void )dealloc
22 {
23 [super setEmployees:nil];
24 [super dealloc];
25 }
26
27 - ( void )setEmployees:(NSMutableArray * )a
28 {
29 if (a == employees)
30 {
31 return ;
32 }
33
34 for (Person * person in employees)
35 {
36 [self stopObservingPerson:person];
37 }
38
39 [a retain];
40 [employees release];
41 employees = a;
42
43 for (Person * person in employees)
44 {
45 [self startObservingPerson:person];
46 }
47 }
48
49 - ( void )insertObject:(Person * )p inEmployeesAtIndex:( int )index
50 {
51 NSLog( @" adding %@ to %@ " , p, employees);
52 NSUndoManager * undo = [self undoManager];
53 [[undo prepareWithInvocationTarget:self] removeObjectFromEmployeesAtIndex:index];
54 if ( ! [undo isUndoing])
55 {
56 [undo setActionName: @" Insert Person " ];
57 }
58 [self startObservingPerson:p];
59 [employees insertObject:p atIndex:index];
60 }
61
62 - ( void )removeObjectFromEmployeesAtIndex:( int )index
63 {
64 Person * p = [employees objectAtIndex:index];
65 NSLog( @" removing %@ from %@ " , p, employees);
66 NSUndoManager * undo = [self undoManager];
67 [[undo prepareWithInvocationTarget:self] insertObject:p inEmployeesAtIndex:index];
68
69 if ( ! [undo isUndoing])
70 {
71 [undo setActionName: @" Delete Person " ];
72 }
73 [self stopObservingPerson:p];
74 [employees removeObjectAtIndex:index];
75 }
76
77 - ( void )startObservingPerson:(Person * )person
78 {
79 [person addObserver:self forKeyPath: @" personName " options:NSKeyValueObservingOptionOld context:NULL];
80 [person addObserver:self forKeyPath: @" expectedRaise " options:NSKeyValueObservingOptionOld context:NULL];
81 }
82
83 - ( void )stopObservingPerson:(Person * )person
84 {
85 [person removeObserver:self forKeyPath: @" personName " ];
86 [person removeObserver:self forKeyPath: @" expectedRaise " ];
87 }
88
89 - ( void )changeKeyPath:(NSString * )keyPath ofObject:(id)obj toValue:(id)newValue
90 {
91 [obj setValue:newValue forKeyPath:keyPath];
92 }
93
94 - ( void )observeValueForKeyPath:(NSString * )keyPath ofObject:(id) object change:(NSDictionary * )change context:( void * )context
95 {
96 NSUndoManager * undo = [self undoManager];
97 id oldValue = [change objectForKey:NSKeyValueChangeOldKey];
98
99 if (oldValue == [NSNull null ])
100 {
101 oldValue = nil;
102 }
103
104 NSLog( @" oldValue = %@ " , oldValue);
105 [[undo prepareWithInvocationTarget:self] changeKeyPath:keyPath ofObject: object toValue:oldValue];
106 [undo setActionName: @" Edit " ];
107 }
108
109 - (IBAction)createEmployee:(id)sender
110 {
111 NSWindow * w = [tableView window];
112
113 BOOL editingEnded = [w makeFirstResponder:w];
114 if ( ! editingEnded)
115 {
116 NSLog( @" Unable to end editing " );
117 return ;
118 }
119
120 NSUndoManager * undo = [self undoManager];
121 if ([undo groupingLevel])
122 {
123 [undo endUndoGrouping];
124 [undo beginUndoGrouping];
125 }
126 Person * p = [employeeController newObject];
127 [employeeController addObject:p];
128 [p release];
129 [employeeController rearrangeObjects];
130
131 NSArray * a = [employeeController arrangedObjects];
132 int row = [a indexOfObjectIdenticalTo:p];
133 NSLog( @" starting edit of %@ in row %@ " , p, row);
134 [tableView editColumn: 0 row:row withEvent:nil select:YES];
135 }
136
137 - (NSString * )windowNibName
138 {
139 // Override returning the nib file name of the document
140 // If you need to use a subclass of NSWindowController or if your document supports multiple NSWindowControllers, you should remove this method and override -makeWindowControllers instead.
141 return @" MyDocument " ;
142 }
143
144 - ( void )windowControllerDidLoadNib:(NSWindowController * ) aController
145 {
146 [super windowControllerDidLoadNib:aController];
147 // Add any code here that needs to be executed once the windowController has loaded the document's window.
148 }
149
150 - (NSData * )dataOfType:(NSString * )typeName error:(NSError ** )outError
151 {
152 // Insert code here to write your document to data of the specified type. If the given outError != NULL, ensure that you set *outError when returning nil.
153
154 // You can also choose to override -fileWrapperOfType:error:, -writeToURL:ofType:error:, or -writeToURL:ofType:forSaveOperation:originalContentsURL:error: instead.
155
156 // For applications targeted for Panther or earlier systems, you should use the deprecated API -dataRepresentationOfType:. In this case you can also choose to override -fileWrapperRepresentationOfType: or -writeToFile:ofType: instead.
157
158 if ( outError != NULL ) {
159 * outError = [NSError errorWithDomain:NSOSStatusErrorDomain code:unimpErr userInfo:NULL];
160 }
161 return nil;
162 }
163
164 - (BOOL)readFromData:(NSData * )data ofType:(NSString * )typeName error:(NSError ** )outError
165 {
166 // Insert code here to read your document from the given data of the specified type. If the given outError != NULL, ensure that you set *outError when returning NO.
167
168 // You can also choose to override -readFromFileWrapper:ofType:error: or -readFromURL:ofType:error: instead.
169
170 // For applications targeted for Panther or earlier systems, you should use the deprecated API -loadDataRepresentation:ofType. In this case you can also choose to override -readFromFile:ofType: or -loadFileWrapperRepresentation:ofType: instead.
171
172 if ( outError != NULL ) {
173 * outError = [NSError errorWithDomain:NSOSStatusErrorDomain code:unimpErr userInfo:NULL];
174 }
175 return YES;
176 }
177
178 @end
179
2 // MyDocument.m
3 // RaiseMan
4 //
5 // Created by b1mobile on 2/14/11.
6 // Copyright 2011 __MyCompanyName__. All rights reserved.
7 //
8
9 #import " MyDocument.h "
10 #import " Person.h "
11
12 @implementation MyDocument
13
14 - (id)init
15 {
16 self = [super init];
17 employees = [[NSMutableArray alloc] init];
18 return self;
19 }
20
21 - ( void )dealloc
22 {
23 [super setEmployees:nil];
24 [super dealloc];
25 }
26
27 - ( void )setEmployees:(NSMutableArray * )a
28 {
29 if (a == employees)
30 {
31 return ;
32 }
33
34 for (Person * person in employees)
35 {
36 [self stopObservingPerson:person];
37 }
38
39 [a retain];
40 [employees release];
41 employees = a;
42
43 for (Person * person in employees)
44 {
45 [self startObservingPerson:person];
46 }
47 }
48
49 - ( void )insertObject:(Person * )p inEmployeesAtIndex:( int )index
50 {
51 NSLog( @" adding %@ to %@ " , p, employees);
52 NSUndoManager * undo = [self undoManager];
53 [[undo prepareWithInvocationTarget:self] removeObjectFromEmployeesAtIndex:index];
54 if ( ! [undo isUndoing])
55 {
56 [undo setActionName: @" Insert Person " ];
57 }
58 [self startObservingPerson:p];
59 [employees insertObject:p atIndex:index];
60 }
61
62 - ( void )removeObjectFromEmployeesAtIndex:( int )index
63 {
64 Person * p = [employees objectAtIndex:index];
65 NSLog( @" removing %@ from %@ " , p, employees);
66 NSUndoManager * undo = [self undoManager];
67 [[undo prepareWithInvocationTarget:self] insertObject:p inEmployeesAtIndex:index];
68
69 if ( ! [undo isUndoing])
70 {
71 [undo setActionName: @" Delete Person " ];
72 }
73 [self stopObservingPerson:p];
74 [employees removeObjectAtIndex:index];
75 }
76
77 - ( void )startObservingPerson:(Person * )person
78 {
79 [person addObserver:self forKeyPath: @" personName " options:NSKeyValueObservingOptionOld context:NULL];
80 [person addObserver:self forKeyPath: @" expectedRaise " options:NSKeyValueObservingOptionOld context:NULL];
81 }
82
83 - ( void )stopObservingPerson:(Person * )person
84 {
85 [person removeObserver:self forKeyPath: @" personName " ];
86 [person removeObserver:self forKeyPath: @" expectedRaise " ];
87 }
88
89 - ( void )changeKeyPath:(NSString * )keyPath ofObject:(id)obj toValue:(id)newValue
90 {
91 [obj setValue:newValue forKeyPath:keyPath];
92 }
93
94 - ( void )observeValueForKeyPath:(NSString * )keyPath ofObject:(id) object change:(NSDictionary * )change context:( void * )context
95 {
96 NSUndoManager * undo = [self undoManager];
97 id oldValue = [change objectForKey:NSKeyValueChangeOldKey];
98
99 if (oldValue == [NSNull null ])
100 {
101 oldValue = nil;
102 }
103
104 NSLog( @" oldValue = %@ " , oldValue);
105 [[undo prepareWithInvocationTarget:self] changeKeyPath:keyPath ofObject: object toValue:oldValue];
106 [undo setActionName: @" Edit " ];
107 }
108
109 - (IBAction)createEmployee:(id)sender
110 {
111 NSWindow * w = [tableView window];
112
113 BOOL editingEnded = [w makeFirstResponder:w];
114 if ( ! editingEnded)
115 {
116 NSLog( @" Unable to end editing " );
117 return ;
118 }
119
120 NSUndoManager * undo = [self undoManager];
121 if ([undo groupingLevel])
122 {
123 [undo endUndoGrouping];
124 [undo beginUndoGrouping];
125 }
126 Person * p = [employeeController newObject];
127 [employeeController addObject:p];
128 [p release];
129 [employeeController rearrangeObjects];
130
131 NSArray * a = [employeeController arrangedObjects];
132 int row = [a indexOfObjectIdenticalTo:p];
133 NSLog( @" starting edit of %@ in row %@ " , p, row);
134 [tableView editColumn: 0 row:row withEvent:nil select:YES];
135 }
136
137 - (NSString * )windowNibName
138 {
139 // Override returning the nib file name of the document
140 // If you need to use a subclass of NSWindowController or if your document supports multiple NSWindowControllers, you should remove this method and override -makeWindowControllers instead.
141 return @" MyDocument " ;
142 }
143
144 - ( void )windowControllerDidLoadNib:(NSWindowController * ) aController
145 {
146 [super windowControllerDidLoadNib:aController];
147 // Add any code here that needs to be executed once the windowController has loaded the document's window.
148 }
149
150 - (NSData * )dataOfType:(NSString * )typeName error:(NSError ** )outError
151 {
152 // Insert code here to write your document to data of the specified type. If the given outError != NULL, ensure that you set *outError when returning nil.
153
154 // You can also choose to override -fileWrapperOfType:error:, -writeToURL:ofType:error:, or -writeToURL:ofType:forSaveOperation:originalContentsURL:error: instead.
155
156 // For applications targeted for Panther or earlier systems, you should use the deprecated API -dataRepresentationOfType:. In this case you can also choose to override -fileWrapperRepresentationOfType: or -writeToFile:ofType: instead.
157
158 if ( outError != NULL ) {
159 * outError = [NSError errorWithDomain:NSOSStatusErrorDomain code:unimpErr userInfo:NULL];
160 }
161 return nil;
162 }
163
164 - (BOOL)readFromData:(NSData * )data ofType:(NSString * )typeName error:(NSError ** )outError
165 {
166 // Insert code here to read your document from the given data of the specified type. If the given outError != NULL, ensure that you set *outError when returning NO.
167
168 // You can also choose to override -readFromFileWrapper:ofType:error: or -readFromURL:ofType:error: instead.
169
170 // For applications targeted for Panther or earlier systems, you should use the deprecated API -loadDataRepresentation:ofType. In this case you can also choose to override -readFromFile:ofType: or -loadFileWrapperRepresentation:ofType: instead.
171
172 if ( outError != NULL ) {
173 * outError = [NSError errorWithDomain:NSOSStatusErrorDomain code:unimpErr userInfo:NULL];
174 }
175 return YES;
176 }
177
178 @end
179