|
|
Sample Programs from NeXSTEP 3.3
#import "ValidatingDelegate.h"
#import "KeyValueValidation.h"
@implementation ValidatingDelegate
- (void)setValidatesImmediately:(BOOL)yn
{
validatesImmediately = yn;
}
- (BOOL)validatesImmediately
{
return validatesImmediately;
}
- (void)reportValidationError:(NSString *)message forKey:(NSString *)key ofObject:object inController:(EOController *)controller
{
NSString *title;
title = [NSString stringWithFormat:@"Invalid input for: %@", key];
// Let's make sure that the object with the error is selected
[controller setSelectionIndexes:[NSArray arrayWithObject:
[NSNumber numberWithInt:[[controller allObjects] indexOfObjectIdenticalTo:object]]]];
NXRunAlertPanel([title cString], [message cString], "OK", NULL, NULL);
// we could tell the controller to select the invalid object and
// run through the associations and restore focus to the one
// matching the key
}
- (void)reportValidationErrors:(NSDictionary *)errors forObject:object inController:(EOController *)controller
{
// pick one of the errors and display it
NSEnumerator *errorEnum = [errors keyEnumerator];
NSString *badValueKey, *errorMessage;
badValueKey = [errorEnum nextObject];
errorMessage = [errors objectForKey:badValueKey];
[self reportValidationError:errorMessage forKey:badValueKey ofObject:object
inController:controller];
}
- (NSDictionary *)controller:(EOController *)controller willSaveEdits: (NSDictionary *)edits toObject:object;
{
if (validatesImmediately) {
NSMutableDictionary *converted = [NSMutableDictionary dictionaryWithCapacity:[edits count]];
NSEnumerator *editEnum = [edits keyEnumerator];
NSString *key;
NSDictionary *errors;
while (key = [editEnum nextObject]) {
// construct a selector and see if the have a validation method
id value = [[controller dataSource] coerceValue:[edits objectForKey:key] forKey:key];
if (!value) {
[self reportValidationError:@"Value entered is not of correct type"
forKey:key ofObject:object inController:controller];
return nil;
}
[converted setObject:value forKey:key];
}
errors = [object validateValuesInDictionary:converted];
if([errors count]) {
[self reportValidationErrors:errors forObject:object inController:controller];
// [controller discardEdits]; // throw away the bad values
return nil;
}
return converted;
}
return edits;
}
- (EODataSourceOperationDelegateResponse)controller:(EOController *)controller
willInsertObject:object
inDataSource:dataSource
{
if ([object respondsToSelector:@selector(validForInsertInDataSource:)]) {
NSDictionary *errors = [object validForInsertInDataSource:dataSource];
if (errors) {
[self reportValidationErrors:errors forObject:object inController:controller];
return EORollbackDataSourceOperation;
}
}
return EOPerformDataSourceOperation;
}
- (EODataSourceOperationDelegateResponse)controller:(EOController *)controller
willUpdateObject:object
inDataSource:dataSource
{
if ([object respondsToSelector:@selector(validForUpdateInDataSource:)]) {
NSDictionary *errors = [object validForUpdateInDataSource:dataSource];
if (errors) {
[self reportValidationErrors:errors forObject:object inController:controller];
return EORollbackDataSourceOperation;
}
}
return EOPerformDataSourceOperation;
}
- (EODataSourceOperationDelegateResponse)controller:(EOController *)controller
willDeleteObject:object
inDataSource:dataSource
{
if ([object respondsToSelector:@selector(validForDeleteInDataSource:)]) {
NSDictionary *errors = [object validForDeleteInDataSource:dataSource];
if (errors) {
[self reportValidationErrors:errors forObject:object inController:controller];
return EORollbackDataSourceOperation;
}
}
return EOPerformDataSourceOperation;
}
@end
@implementation NSObject (ValidationProtocols)
// An EO can implement some or all of these methods to play a roll in its validation
- (NSArray *)keysToValidate
{
return [NSArray array];
}
- (NSDictionary *)validForDataSource:(id <EODataSources>)dataSource;
{
return [self validateValuesInDictionary:[self valuesForKeys:[self keysToValidate]]];
}
- (NSDictionary *)validForInsertInDataSource:(id <EODataSources>)dataSource;
{
return [self validForDataSource:dataSource];
}
- (NSDictionary *)validForUpdateInDataSource:(id <EODataSources>)dataSource;
{
return [self validForDataSource:dataSource];
}
- (NSDictionary *)validForDeleteInDataSource:(id <EODataSources>)dataSource;
{
return nil;
}
@end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.