|
|
1.1 root 1: /* SelectionInsertionAssocation.m created by cfeder on Tue 08-Nov-1994 */
2:
3: #import "SelectionInsertionAssociation.h"
4:
5: @interface NSArray (_arrayWithObjectsNotInArray)
6: - (NSArray *)arrayWithObjectsNotInArray:other;
7: - (NSArray *)arrayOfSelectionIndexesForObjects:other;
8: @end
9:
10: @implementation NSArray (_arrayWithObjectsNotInArray)
11: - (NSArray *)arrayWithObjectsNotInArray:other
12: {
13: // Tremendously inefficient brain-dead implementation
14: NSMutableArray *result = [NSMutableArray array];
15: int i, count = [self count];
16: for(i=0; i<count; i++) {
17: id object = [self objectAtIndex:i];
18: if ([other indexOfObjectIdenticalTo:object] == NSNotFound)
19: [result addObject:object];
20: }
21: return result;
22: }
23:
24: - (NSArray *)arrayOfSelectionIndexesForObjects:other
25: {
26: // look up each of objects in other and return their indices in our array
27: NSMutableArray *result = [NSMutableArray array];
28: int i, count = [other count];
29: for(i=0; i<count; i++) {
30: id object = [other objectAtIndex:i];
31: unsigned idx = [self indexOfObjectIdenticalTo:object];
32: if ( idx != NSNotFound)
33: [result addObject:[NSNumber numberWithUnsignedInt:idx]];
34: }
35: return result;
36: }
37: @end
38:
39:
40: // silly association to tell us about changes in the destination
41: @interface _SIMessager : EOAssociation
42: {
43: }
44: - initWithController:(EOController *)aController
45: key: (NSString *)aKey destination: aDest;
46: @end
47:
48: @implementation SelectionInsertionAssociation
49: // Our controller is the one we perform insert and delete operations on.
50: // Our destination is the controller that provides us with selected objects
51:
52: - initWithController:(EOController *)aController
53: key: (NSString *)aKey destination: aDest
54: {
55: [super initWithController:aController key: aKey destination:aDest];
56:
57: // Our destination is a controller and we want to know when it changes.
58: // We use another association to pass on relevant events from it.
59: [destination addAssociation:[[[_SIMessager alloc] initWithController:destination key:nil destination:self] autorelease]];
60: return self;
61: }
62:
63: - (void)updateSelection
64: {
65: NSArray *allObjects = [destination allObjects];
66: NSArray *destinationObjects = [controller allObjects];
67:
68: [destination setSelectionIndexes:[allObjects arrayOfSelectionIndexesForObjects:destinationObjects]];
69: }
70:
71: - (void)contentsDidChange
72: {
73: if (!ignoreNotifications)
74: [self updateSelection];
75: }
76:
77: - (void)selectionDidChange
78: {
79: if (!ignoreNotifications)
80: [self updateSelection];
81: }
82:
83: - (void)contentsDidChangeInController:(EOController *)aController
84: {
85: // who cares
86: }
87:
88: - (void)selectionDidChangeInController:(EOController *)aController
89: {
90: // Our selection changed. Perform relevant insertions and deletions in our
91: // destination.
92: NSArray *selectedObjects = [destination selectedObjects];
93: NSArray *destinationObjects = [controller allObjects];
94: NSArray *added = [selectedObjects arrayWithObjectsNotInArray:destinationObjects];
95: NSArray *removed = [destinationObjects arrayWithObjectsNotInArray:selectedObjects];
96: int i, count;
97:
98: ignoreNotifications = YES;
99:
100: // We do deletions before insertions so that the right thing happens for
101: // to-one detail relationships (insert before delete would, for a moment,
102: // put two objects at the destination of a to-one)
103: for(i=0,count=[removed count]; i<count; i++) {
104: id object = [removed objectAtIndex:i];
105: unsigned idx = [[controller allObjects] indexOfObjectIdenticalTo:object];
106: if (idx != NSNotFound)
107: [controller deleteObjectAtIndex:idx];
108: }
109:
110: for(i=0,count=[added count]; i<count; i++) {
111: id object = [added objectAtIndex:i];
112: [controller insertObject:object atIndex:0];
113: }
114:
115: ignoreNotifications = NO;
116: }
117: @end
118:
119:
120: @implementation _SIMessager
121: - initWithController:(EOController *)aController
122: key: (NSString *)aKey destination: aDest
123: // destination is object we forward association messages to
124: // key is not used
125: {
126: return [super initWithController:aController key: aKey destination:aDest];
127: }
128:
129: - (void)selectionDidChange
130: {
131: [destination selectionDidChangeInController:[self controller]];
132: }
133: - (void)contentsDidChange
134: {
135: [destination contentsDidChangeInController:[self controller]];
136: }
137: @end
138:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.