|
|
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.