}
- (void)setSelectedObject:(id)_obj {
- [self warnWithFormat:@"%s not implemented.", __PRETTY_FUNCTION__];
+ unsigned idx;
+ NSNumber *idxNumber;
+
+ // TODO: maybe we need to retain the selection array and just swap the first
+
+ idx = [self->objects indexOfObject:_obj];
+ idxNumber = (idx != NSNotFound) ? [NSNumber numberWithUnsignedInt:idx] : nil;
+
+ if (idxNumber != nil)
+ [self setSelectionIndexes:[NSArray arrayWithObjects:&idxNumber count:1]];
+ else
+ [self setSelectionIndexes:nil];
}
- (id)selectedObject {
- return nil;
+ unsigned int i, sCount;
+
+ if ((sCount = [self->selectionIndexes count]) == 0)
+ return nil;
+
+ i = [[self->selectionIndexes objectAtIndex:0] unsignedIntValue];
+ if (i >= [self->objects count])
+ return nil;
+
+ // TODO: need to ensure selection is in displayedObjects?
+ return [self->objects objectAtIndex:i];
}
- (void)setSelectedObjects:(NSArray *)_objs {
oCount = [self->objects count];
result = [NSMutableArray arrayWithCapacity:sCount];
- for (i=0; i<sCount; i++) {
+ for (i = 0; i < sCount; i++) {
unsigned int idx;
idx = [[self->selectionIndexes objectAtIndex:i] unsignedIntValue];
return result;
}
-/* returns YES if displayedObjects contains _obj otherwise NO */
- (BOOL)selectObject:(id)_obj {
+ /* returns YES if displayedObjects contains _obj otherwise NO */
NSNumber *idxNumber;
unsigned idx;
if (![self->displayObjects containsObject:_obj])
return NO;
+
+ idx = [self->objects indexOfObject:_obj];
+ idxNumber = (idx != NSNotFound) ? [NSNumber numberWithUnsignedInt:idx] : nil;
- idx = [self->displayObjects indexOfObject:_obj];
- idxNumber = [NSNumber numberWithUnsignedInt:idx];
+ // TODO: should we just exchange the first item and/or call
+ // -setSelectedObject: ?
+#if 0 /* this was wrong? */
if ([self->selectionIndexes containsObject:idxNumber])
+ /* already selected => could be many => move to top? */
return YES;
- else {
- NSMutableArray *tmp;
-
- tmp = [NSMutableArray arrayWithObjects:self->selectionIndexes];
- [tmp addObject:idxNumber];
- [self setSelectionIndexes:tmp];
- return YES;
- }
+
+ tmp = [NSMutableArray arrayWithObjects:self->selectionIndexes];
+ [tmp addObject:idxNumber];
+ [self setSelectionIndexes:tmp];
+#else
+ if (idxNumber != nil)
+ [self setSelectionIndexes:[NSArray arrayWithObjects:&idxNumber count:1]];
+ else
+ [self setSelectionIndexes:nil];
+#endif
+ return YES;
}
}
- (BOOL)selectObjectsIdenticalTo:(NSArray *)_objs
- selectFirstOnNoMatch:(BOOL)_flag
+ selectFirstOnNoMatch:(BOOL)_flag
{
if ([self selectObjectsIdenticalTo:_objs])
return YES;
- (id)fetch {
NSArray *objs;
- if ([self->delegate respondsToSelector:@selector(displayGroupShouldFetch:)]) {
+ if ([self->delegate respondsToSelector:@selector(displayGroupShouldFetch:)]){
if (![self->delegate displayGroupShouldFetch:self])
/* delegate rejected fetch-request */
return nil;
if ([objs count] > 0)
[self setSelectedObject:[objs objectAtIndex:0]];
- }
- return nil;
+ }
+
+ return nil /* stay on page */;
}
+
- (void)updateDisplayedObjects {
NSArray *darray; // display objects
NSArray *sarray; // selected objects
darray = [self->delegate displayGroup:self
displayArrayForObjects:[self allObjects]];
- darray = [darray copy];
- RELEASE(self->displayObjects);
- self->displayObjects = darray;
-
+ ASSIGNCOPY(self->displayObjects, darray);
return;
}
- else {
+
+ {
// EOQualifier *q;
NSArray *so, *ao;
operatorSelector:ops
value:value];
[quals addObject:q];
- RELEASE(q); q = nil;
+ [q release]; q = nil;
}
/* construct min qualifiers */
keys = [qmin keyEnumerator];
- while ((key = [keys nextObject])) {
+ while ((key = [keys nextObject]) != nil) {
EOQualifier *q;
id value;
operatorSelector:EOQualifierOperatorGreaterThan
value:value];
[quals addObject:q];
- RELEASE(q);
+ [q release];
}
/* construct max qualifiers */
keys = [qmax keyEnumerator];
- while ((key = [keys nextObject])) {
+ while ((key = [keys nextObject]) != nil) {
EOQualifier *q;
id value;
operatorSelector:EOQualifierOperatorLessThan
value:value];
[quals addObject:q];
- RELEASE(q);
+ [q release];
}
if ([quals count] == 0)
return nil;
- else if ([quals count] == 1)
+ if ([quals count] == 1)
return [quals objectAtIndex:0];
- else
- return AUTORELEASE([[EOAndQualifier alloc] initWithQualifierArray:quals]);
+
+ return [[[EOAndQualifier alloc] initWithQualifierArray:quals] autorelease];
}
- (NSMutableDictionary *)queryBindings {
if (self->_queryBindings == nil)
- self->_queryBindings = [[NSMutableDictionary alloc] init];
+ self->_queryBindings = [[NSMutableDictionary alloc] initWithCapacity:8];
return self->_queryBindings;
}
- (NSMutableDictionary *)queryMatch {
if (self->_queryMatch == nil)
- self->_queryMatch = [[NSMutableDictionary alloc] init];
+ self->_queryMatch = [[NSMutableDictionary alloc] initWithCapacity:8];
return self->_queryMatch;
}
- (NSMutableDictionary *)queryMin {
if (self->_queryMin == nil)
- self->_queryMin = [[NSMutableDictionary alloc] init];
+ self->_queryMin = [[NSMutableDictionary alloc] initWithCapacity:8];
return self->_queryMin;
}
- (NSMutableDictionary *)queryMax {
if (self->_queryMax == nil)
- self->_queryMax = [[NSMutableDictionary alloc] init];
+ self->_queryMax = [[NSMutableDictionary alloc] initWithCapacity:8];
return self->_queryMax;
}
- (NSMutableDictionary *)queryOperator {
if (self->_queryOperator == nil)
- self->_queryOperator = [[NSMutableDictionary alloc] init];
+ self->_queryOperator = [[NSMutableDictionary alloc] initWithCapacity:8];
return self->_queryOperator;
}
- (void)setDefaultStringMatchFormat:(NSString *)_tmp {
- ASSIGN(self->defaultStringMatchFormat, _tmp);
+ ASSIGNCOPY(self->defaultStringMatchFormat, _tmp);
}
- (NSString *)defaultStringMatchFormat {
return self->defaultStringMatchFormat;
}
- (void)setDefaultStringMatchOperator:(NSString *)_tmp {
- ASSIGN(self->defaultStringMatchOperator, _tmp);
+ ASSIGNCOPY(self->defaultStringMatchOperator, _tmp);
}
- (NSString *)defaultStringMatchOperator {
return self->defaultStringMatchOperator;
- (void)qualifyDisplayGroup {
EOQualifier *q;
- if ((q = [self qualifierFromQueryValues]))
+ if ((q = [self qualifierFromQueryValues]) != nil)
[self setQualifier:q];
[self updateDisplayedObjects];
ds = [self dataSource];
- if ((q = [self qualifierFromQueryValues]))
+ if ((q = [self qualifierFromQueryValues]) != nil)
[self setQualifier:q];
if ([ds respondsToSelector:@selector(setAuxiliaryQualifier:)])
[self setInQueryMode:NO];
}
+
+/* object creation */
+
+- (id)insert {
+ unsigned idx;
+
+ idx = [self->selectionIndexes count] > 0
+ ? ([[self->selectionIndexes objectAtIndex:0] unsignedIntValue] + 1)
+ : [self->objects count];
+
+ return [self insertObjectAtIndex:idx]; /* returns 'nil' */
+}
+
+- (id)insertObjectAtIndex:(unsigned)_idx {
+ id newObject;
+
+ if ((newObject = [[self dataSource] createObject]) == nil) {
+ [self errorWithFormat:@"Failed to create new object in datasource: %@",
+ [self dataSource]];
+
+ if ([self->delegate respondsToSelector:
+ @selector(displayGroup:createObjectFailedForDataSource:)]) {
+ [self->delegate displayGroup:self
+ createObjectFailedForDataSource:[self dataSource]];
+ }
+ return nil /* refresh page */;
+ }
+
+ /* apply default values */
+
+ [newObject takeValuesFromDictionary:[self insertedObjectDefaultValues]];
+
+ /* insert */
+
+ [self insertObject:newObject atIndex:_idx];
+
+ return nil /* refresh page */;
+}
+
+- (void)insertObject:(id)_o atIndex:(unsigned)_idx {
+ NSMutableArray *ma;
+
+ /* ask delegate whether we should insert */
+ if ([self->delegate respondsToSelector:
+ @selector(displayGroup:shouldInsertObject:atIndex:)]) {
+ if (![self->delegate displayGroup:self shouldInsertObject:_o atIndex:_idx])
+ return;
+ }
+
+ /* insert in datasource */
+
+ [[self dataSource] insertObject:_o];
+
+ /* update object-array (ignores qualifier for new objects!) */
+
+ ma = [self->objects mutableCopy];
+ if (_idx <= [ma count])
+ [ma insertObject:_o atIndex:_idx];
+ else
+ [ma addObject:_o];
+
+ [self setObjectArray:ma];
+ [ma release]; ma = nil;
+ [self updateDisplayedObjects];
+
+ /* select object */
+
+ [self selectObject:_o]; // TODO: or use setSelectedObject:?
+
+ /* let delegate know */
+ if ([self->delegate respondsToSelector:
+ @selector(displayGroup:didInsertObject:)])
+ [self->delegate displayGroup:self didInsertObject:_o];
+}
+
+
+/* object deletion */
+
+- (id)delete {
+ [self deleteSelection];
+ return nil;
+}
+
+- (BOOL)deleteSelection {
+ NSArray *objsToDelete;
+ unsigned i, count;
+
+ objsToDelete = [[[self selectedObjects] shallowCopy] autorelease];
+
+ for (i = 0, count = [objsToDelete count]; i < count; i++) {
+ unsigned idx;
+
+ idx = [self->objects indexOfObject:[objsToDelete objectAtIndex:i]];
+ if (idx == NSNotFound) {
+ [self errorWithFormat:@"Did not find object in selection: %@",
+ objsToDelete];
+ return NO;
+ }
+
+ if (![self deleteObjectAtIndex:idx])
+ return NO;
+ }
+ return YES;
+}
+
+- (BOOL)deleteObjectAtIndex:(unsigned)_idx {
+ NSMutableArray *ma;
+ id object;
+ BOOL ok;
+
+ /* find object */
+
+ object = (_idx < [self->objects count])
+ ? [[[self->objects objectAtIndex:_idx] retain] autorelease]
+ : nil;
+ // TODO: check for nil?
+
+ /* ask delegate */
+
+ if ([self->delegate respondsToSelector:
+ @selector(displayGroup:shouldDeleteObject:)]) {
+ if (![self->delegate displayGroup:self shouldDeleteObject:object])
+ return NO;
+ }
+
+ /* delete in datasource */
+
+ ok = YES;
+ NS_DURING
+ [[self dataSource] deleteObject:object];
+ NS_HANDLER
+ *(&ok) = NO;
+ NS_ENDHANDLER;
+
+ if (!ok)
+ return NO;
+
+ /* update array */
+
+ ma = [self->objects mutableCopy];
+ [ma removeObject:object];
+ [self setObjectArray:ma];
+ [ma release]; ma = nil;
+ [self updateDisplayedObjects];
+
+ /* notify delegate */
+
+ if ([self->delegate respondsToSelector:
+ @selector(displayGroup:didDeleteObject:)])
+ [self->delegate displayGroup:self didDeleteObject:object];
+ return YES;
+}
+
+
+/* master / detail */
+
+- (BOOL)hasDetailDataSource {
+ return [[self dataSource] isKindOfClass:[EODetailDataSource class]];
+}
+
+- (void)setDetailKey:(NSString *)_key {
+ // TODO: fix me, probably we want to store the key for later
+#if 0
+ EODataSource *ds;
+
+ if ([(ds = [self dataSource]) respondsToSelector:_cmd])
+ [(EODetailDataSource *)ds setDetailKey:_key];
+#endif
+}
+- (NSString *)detailKey {
+ EODataSource *ds;
+
+ return ([(ds = [self dataSource]) respondsToSelector:_cmd])
+ ? [(EODetailDataSource *)ds detailKey] : nil;
+}
+
+- (void)setMasterObject:(id)_object {
+ [[self dataSource] qualifyWithRelationshipKey:[self detailKey]
+ ofObject:_object];
+
+ if ([self fetchesOnLoad])
+ [self fetch];
+}
+- (id)masterObject {
+ EODataSource *ds;
+
+ return ([(ds = [self dataSource]) respondsToSelector:_cmd])
+ ? [(EODetailDataSource *)ds masterObject] : nil;
+}
+
+
/* KVC */
- (void)takeValue:(id)_value forKeyPath:(NSString *)_keyPath {
[self notImplemented:_cmd];
}
-/* description */
-
-- (NSString *)description {
- return [NSString stringWithFormat:@"<0x%08X %@: ds=%@>",
- self, NSStringFromClass([self class]),
- [self dataSource]];
-}
-
/* KVCArchiving */
- (id)initWithKeyValueUnarchiver:(EOKeyValueUnarchiver *)_unarchiver {
forKey:@"selectFirstAfterFetch"];
}
+- (void)awakeFromKeyValueUnarchiver:(EOKeyValueUnarchiver *)_unarchiver {
+ if ([self fetchesOnLoad])
+ [self fetch];
+}
+
/* EOEditorsImpl */
- (void)editingContextWillSaveChanges:(id)_ec {
return NO;
}
+/* description */
+
+- (NSString *)description {
+ return [NSString stringWithFormat:@"<0x%08X %@: ds=%@>",
+ self, NSStringFromClass([self class]),
+ [self dataSource]];
+}
+
@end /* WODisplayGroup */