diff --git a/AppKit/CPArrayController.j b/AppKit/CPArrayController.j index 2dfda77f2..c6122214b 100644 --- a/AppKit/CPArrayController.j +++ b/AppKit/CPArrayController.j @@ -42,11 +42,24 @@ id _arrangedObjects; } ++ (void)initialize +{ + if (self !== [self class]) + return; + + [[self class] exposeBinding:@"contentArray"]; +} + + (CPSet)keyPathsForValuesAffectingValueForContentArray { return [CPSet setWithObjects:"content"]; } ++ (CPSet)keyPathsForValuesAffectingValueForArrangedObjects +{ + return [CPSet setWithObjects:"content", "contentArray", "filterPredicate", "sortDescriptors"]; +} + + (CPSet)keyPathsForValuesAffectingValueForSelection { return [CPSet setWithObjects:"content", "contentArray", "selectionIndexes"]; @@ -92,6 +105,26 @@ _preservesSelection = value; } +- (BOOL)selectsInsertedObjects +{ + return _selectsInsertedObjects; +} + +- (void)setSelectsInsertedObjects:(BOOL)value +{ + _selectsInsertedObjects = value; +} + +- (BOOL)avoidsEmptySelection +{ + return _avoidsEmptySelection; +} + +- (void)setAvoidsEmptySelection:(BOOL)value +{ + _avoidsEmptySelection = value; +} + - (void)setContent:(id)value { if(![value isKindOfClass:[CPArray class]]) @@ -103,8 +136,8 @@ if ([self preservesSelection]) oldSelection = [self selectedObjects]; - //FIXME: mutable copy? - [super setContent:[value copy]]; + //FIXME: copy? + [super setContent:value]; if(_clearsFilterPredicateOnInsertion) [self setFilterPredicate:nil]; @@ -231,7 +264,7 @@ - (CPArray)selectedObjects { - var objects = [_CPObservableArray arrayWithArray:[[self arrangedObjects] objectsAtIndexes:[self selectionIndexes]]]; + var objects = [[self arrangedObjects] objectsAtIndexes:[self selectionIndexes]]; return objects || [_CPObservableArray array]; } @@ -288,32 +321,33 @@ { if (![self canAdd]) return; - - [self willChangeValueForKey:@"content"]; - [_content addObject:object]; - [self didChangeValueForKey:@"content"]; - - if (_clearsFilterPredicateOnInsertion) + + [self willChangeValueForKey:@"content"]; + [_contentObject addObject:object]; + [self didChangeValueForKey:@"content"]; + + if (_clearsFilterPredicateOnInsertion) [self setFilterPredicate:nil]; - - if ([_filterPredicate evaluateWithObject:object]) - { + + if ([_filterPredicate evaluateWithObject:object]) + { [self willChangeValueForKey:@"selectionIndexes"]; var pos = [_arrangedObjects insertObject:object inArraySortedByDescriptors:_sortDescriptors]; [_selectionIndexes shiftIndexesStartingAtIndex:pos by:1]; [self didChangeValueForKey:@"selectionIndexes"]; - } + } + else + [self rearrangeObjects]; } - - (void)removeObject:(id)object { if (![self canRemove]) return; [self willChangeValueForKey:@"content"]; - [_content removeObject:object]; + [_contentObject removeObject:object]; [self didChangeValueForKey:@"content"]; if ([_filterPredicate evaluateWithObject:object]) diff --git a/AppKit/CPKeyValueBinding.j b/AppKit/CPKeyValueBinding.j index 89e46b949..70e46e350 100644 --- a/AppKit/CPKeyValueBinding.j +++ b/AppKit/CPKeyValueBinding.j @@ -23,6 +23,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +@import +@import +@import + var exposedBindingsMap = [CPDictionary new], bindingsMap = [CPDictionary new]; @@ -109,7 +113,6 @@ var CPBindingOperationAnd = 0, if (self) { - CPLog("creating CPKeyValueBinding with binding: "+aBinding+" name: "+aName+" to: "+aDestination+" keyPath: "+aKeyPath+" from: "+aSource); _source = aSource; _info = [CPDictionary dictionaryWithObjects:[aDestination, aKeyPath] forKeys:[CPObservedObjectKey, CPObservedKeyPathKey]]; @@ -161,13 +164,7 @@ var CPBindingOperationAnd = 0, if (!changes) return; - var options = [_info objectForKey:CPOptionsKey], - newValue = [changes objectForKey:CPKeyValueChangeNewKey]; - - newValue = [self transformValue:newValue withOptions:options]; - - if (![newValue isEqual:[_source valueForKey:context]]) - [_source setValue:newValue forKey:context]; + [self setValueFor:context]; } - (id)transformValue:(id)aValue withOptions:(CPDictionary)options @@ -260,7 +257,7 @@ var CPBindingOperationAnd = 0, return CPLog.error("Invalid object or path on "+self+" for "+aBinding); if (![[self exposedBindings] containsObject:aBinding]) - return CPLog.error("No binding exposed on "+self+" for "+aBinding); + CPLog.warn("No binding exposed on "+self+" for "+aBinding); [self unbind:aBinding]; [[CPKeyValueBinding alloc] initWithBinding:aBinding name:aBinding to:anObject keyPath:aKeyPath options:options from:self]; diff --git a/AppKit/CPObjectController.j b/AppKit/CPObjectController.j index b9884b63c..23169cbf0 100644 --- a/AppKit/CPObjectController.j +++ b/AppKit/CPObjectController.j @@ -19,6 +19,11 @@ [self exposeBinding:"contentObject"]; } ++ (CPSet)keyPathsForValuesAffectingValueForContentObject +{ + return [CPSet setWithObjects:"content"]; +} + + (BOOL)automaticallyNotifiesObserversForKey:(CPString)aKey { if (aKey === @"contentObject") @@ -89,7 +94,7 @@ - (void)setObjectClass:(Class)aClass { - _defaultClassName = [aClass name]; + _defaultClassName = [aClass className]; } - (Class)objectClass @@ -134,7 +139,7 @@ - (BOOL)isEditable { - return _isEditable; + return _editable; } - (void)setEditable:(BOOL)isEditable @@ -322,7 +327,7 @@ { if (aKeyPath.indexOf("@") === 0) { - var proxy = [[_CPObservationProxy alloc] initWithKeyPath:aKeyPath observer:anObsever object:self], + var proxy = [[_CPObservationProxy alloc] initWithKeyPath:aKeyPath observer:anObserver object:self], index = [_observationProxies indexOfObject:proxy]; proxy = [_observationProxies objectAtIndex:index]; diff --git a/Foundation/CPArray+KVO.j b/Foundation/CPArray+KVO.j index 40600410b..b5c918c41 100644 --- a/Foundation/CPArray+KVO.j +++ b/Foundation/CPArray+KVO.j @@ -246,7 +246,6 @@ - (id)valueForKey:(CPString)aKey { - if (aKey.indexOf("@") === 0) { if (aKey.indexOf(".") !== -1) @@ -280,7 +279,7 @@ - (id)valueForKeyPath:(CPString)aKeyPath { if (aKeyPath.indexOf("@") === 0) - { + { var dotIndex = aKeyPath.indexOf("."), operator = aKeyPath.substring(1, dotIndex), parameter = aKeyPath.substring(dotIndex+1); @@ -292,21 +291,7 @@ } else { - var newArray = [], - enumerator = [self objectEnumerator], - object; - - while ((object = [enumerator nextObject]) !== nil) - { - var value = [object valueForKeyPath:aKeyPath]; - - if (value === nil || value === undefined) - value = [CPNull null]; - - newArray.push(value); - } - - return newArray; + return [super valueForKeyPath:aKeyPath]; } } @@ -426,7 +411,7 @@ kvoOperators["sum"] = function sumOperator(self, _cmd, param) -(void)addObserver:(id)observer forKeyPath:(CPString)aKeyPath options:(unsigned)options context:(id)context { - CPLog.warn("adding observer to CPArray. observer: "+observer+" keypath: "+aKeyPath+" context: "+context); + //CPLog.warn("adding observer to CPArray. observer: "+observer+" keypath: "+aKeyPath+" context: "+context); if ([isa instanceMethodForSelector:_cmd]==[CPArray instanceMethodForSelector:_cmd]) [CPException raise:CPInvalidArgumentException reason:"Unsupported method on CPArray"]; else diff --git a/Foundation/CPKeyValueCoding.j b/Foundation/CPKeyValueCoding.j index ac1f09385..a6317c873 100644 --- a/Foundation/CPKeyValueCoding.j +++ b/Foundation/CPKeyValueCoding.j @@ -173,17 +173,15 @@ CPUnknownUserInfoKey = @"CPUnknownUserInfoKey"; - (id)valueForKeyPath:(CPString)aKeyPath { - var keys = aKeyPath.split("."), - - index = 0, - count = keys.length, - - value = self; + var dotIndex = aKeyPath.indexOf("."); - for(; index < count; ++index) - value = [value valueForKey:keys[index]]; + if (dotIndex === CPNotFound) + return [self valueForKey:aKeyPath]; - return value; + var firstPart = aKeyPath.substring(0, dotIndex), + secondPart = aKeyPath.substring(dotIndex+1); + + return [[self valueForKey:firstPart] valueForKeyPath:secondPart]; } - (CPDictionary)dictionaryWithValuesForKeys:(CPArray)keys