CPArrayController works simply with bindings and arrangedObjects

This commit is contained in:
Ross Boucher
2009-02-19 01:29:39 -08:00
parent 4de3a34a3e
commit 9bbe51fa64
5 changed files with 73 additions and 54 deletions
+49 -15
View File
@@ -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])
+6 -9
View File
@@ -23,6 +23,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPArray.j>
@import <Foundation/CPDictionary.j>
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];
+8 -3
View File
@@ -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];
+3 -18
View File
@@ -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
+7 -9
View File
@@ -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