|
|
Sample Programs from NeXSTEP 3.3
/* SelectionInsertionAssocation.m created by cfeder on Tue 08-Nov-1994 */
#import "SelectionInsertionAssociation.h"
@interface NSArray (_arrayWithObjectsNotInArray)
- (NSArray *)arrayWithObjectsNotInArray:other;
- (NSArray *)arrayOfSelectionIndexesForObjects:other;
@end
@implementation NSArray (_arrayWithObjectsNotInArray)
- (NSArray *)arrayWithObjectsNotInArray:other
{
// Tremendously inefficient brain-dead implementation
NSMutableArray *result = [NSMutableArray array];
int i, count = [self count];
for(i=0; i<count; i++) {
id object = [self objectAtIndex:i];
if ([other indexOfObjectIdenticalTo:object] == NSNotFound)
[result addObject:object];
}
return result;
}
- (NSArray *)arrayOfSelectionIndexesForObjects:other
{
// look up each of objects in other and return their indices in our array
NSMutableArray *result = [NSMutableArray array];
int i, count = [other count];
for(i=0; i<count; i++) {
id object = [other objectAtIndex:i];
unsigned idx = [self indexOfObjectIdenticalTo:object];
if ( idx != NSNotFound)
[result addObject:[NSNumber numberWithUnsignedInt:idx]];
}
return result;
}
@end
// silly association to tell us about changes in the destination
@interface _SIMessager : EOAssociation
{
}
- initWithController:(EOController *)aController
key: (NSString *)aKey destination: aDest;
@end
@implementation SelectionInsertionAssociation
// Our controller is the one we perform insert and delete operations on.
// Our destination is the controller that provides us with selected objects
- initWithController:(EOController *)aController
key: (NSString *)aKey destination: aDest
{
[super initWithController:aController key: aKey destination:aDest];
// Our destination is a controller and we want to know when it changes.
// We use another association to pass on relevant events from it.
[destination addAssociation:[[[_SIMessager alloc] initWithController:destination key:nil destination:self] autorelease]];
return self;
}
- (void)updateSelection
{
NSArray *allObjects = [destination allObjects];
NSArray *destinationObjects = [controller allObjects];
[destination setSelectionIndexes:[allObjects arrayOfSelectionIndexesForObjects:destinationObjects]];
}
- (void)contentsDidChange
{
if (!ignoreNotifications)
[self updateSelection];
}
- (void)selectionDidChange
{
if (!ignoreNotifications)
[self updateSelection];
}
- (void)contentsDidChangeInController:(EOController *)aController
{
// who cares
}
- (void)selectionDidChangeInController:(EOController *)aController
{
// Our selection changed. Perform relevant insertions and deletions in our
// destination.
NSArray *selectedObjects = [destination selectedObjects];
NSArray *destinationObjects = [controller allObjects];
NSArray *added = [selectedObjects arrayWithObjectsNotInArray:destinationObjects];
NSArray *removed = [destinationObjects arrayWithObjectsNotInArray:selectedObjects];
int i, count;
ignoreNotifications = YES;
// We do deletions before insertions so that the right thing happens for
// to-one detail relationships (insert before delete would, for a moment,
// put two objects at the destination of a to-one)
for(i=0,count=[removed count]; i<count; i++) {
id object = [removed objectAtIndex:i];
unsigned idx = [[controller allObjects] indexOfObjectIdenticalTo:object];
if (idx != NSNotFound)
[controller deleteObjectAtIndex:idx];
}
for(i=0,count=[added count]; i<count; i++) {
id object = [added objectAtIndex:i];
[controller insertObject:object atIndex:0];
}
ignoreNotifications = NO;
}
@end
@implementation _SIMessager
- initWithController:(EOController *)aController
key: (NSString *)aKey destination: aDest
// destination is object we forward association messages to
// key is not used
{
return [super initWithController:aController key: aKey destination:aDest];
}
- (void)selectionDidChange
{
[destination selectionDidChangeInController:[self controller]];
}
- (void)contentsDidChange
{
[destination contentsDidChangeInController:[self controller]];
}
@end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.