home *** CD-ROM | disk | FTP | other *** search
/ NeXT Enterprise Objects Framework 1.1 / NeXT Enterprise Objects Framework 1.1.iso / NextDeveloper / Examples / EnterpriseObjects / MasteringDetails / EOFExtensions.subproj / SelectionInsertionAssociation.m < prev    next >
Encoding:
Text File  |  1995-02-18  |  4.2 KB  |  139 lines

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