35 BOOL _avoidsEmptySelection;
36 BOOL _clearsFilterPredicateOnInsertion;
37 BOOL _filterRestrictsInsertion;
38 BOOL _preservesSelection;
39 BOOL _selectsInsertedObjects;
40 BOOL _alwaysUsesMultipleValuesMarker;
42 BOOL _automaticallyRearrangesObjects;
45 CPArray _sortDescriptors;
46 CPPredicate _filterPredicate;
47 CPArray _arrangedObjects;
49 BOOL _disableSetContent;
63 return [CPSet setWithObjects:@"content"];
69 return [CPSet setWithObjects:@"content", @"sortDescriptors"];
74 return [CPSet setWithObjects:@"selectionIndexes"];
79 return [CPSet setWithObjects:@"selectionIndexes"];
86 return [CPSet setWithObjects:@"arrangedObjects"];
92 return [CPSet setWithObjects:@"selectionIndexes"];
97 return [CPSet setWithObjects:@"selectionIndexes"];
102 return [CPSet setWithObjects:@"selectionIndexes"];
107 return [CPSet setWithObjects:@"selectionIndexes"];
117 _preservesSelection = YES;
118 _selectsInsertedObjects = YES;
119 _avoidsEmptySelection = YES;
120 _clearsFilterPredicateOnInsertion = YES;
121 _alwaysUsesMultipleValuesMarker = NO;
122 _automaticallyRearrangesObjects = NO;
124 _filterRestrictsInsertion = YES;
134 _sortDescriptors = [CPArray array];
135 _filterPredicate = nil;
137 [
self __setArrangedObjects:[CPArray array]];
142 [
self _setContentArray:[[
self newObject]]];
150 return _preservesSelection;
158 - (void)setPreservesSelection:(BOOL)value
160 _preservesSelection = value;
168 return _selectsInsertedObjects;
175 - (void)setSelectsInsertedObjects:(BOOL)value
177 _selectsInsertedObjects = value;
185 return _avoidsEmptySelection;
192 - (void)setAvoidsEmptySelection:(BOOL)value
194 _avoidsEmptySelection = value;
204 return _clearsFilterPredicateOnInsertion;
212 - (void)setClearsFilterPredicateOnInsertion:(BOOL)aFlag
214 _clearsFilterPredicateOnInsertion = aFlag;
225 return _alwaysUsesMultipleValuesMarker;
234 - (void)setAlwaysUsesMultipleValuesMarker:(BOOL)aFlag
236 _alwaysUsesMultipleValuesMarker = aFlag;
250 return _automaticallyRearrangesObjects;
262 - (void)setAutomaticallyRearrangesObjects:(BOOL)aFlag
264 _automaticallyRearrangesObjects = aFlag;
272 - (void)setContent:(
id)value
277 if (_disableSetContent)
283 if (![value isKindOfClass:[CPArray
class]])
286 var oldSelectedObjects = nil,
287 oldSelectionIndexes = nil;
306 if (_clearsFilterPredicateOnInsertion)
313 _contentObject = value;
315 if (_clearsFilterPredicateOnInsertion && _filterPredicate != nil)
316 [
self __setFilterPredicate:nil];
318 [
self _rearrangeObjects];
321 [
self __setSelectedObjects:oldSelectedObjects];
323 [
self __setSelectionIndexes:oldSelectionIndexes];
325 if (_clearsFilterPredicateOnInsertion)
332 - (void)_setContentArray:(
id)anArray
340 - (void)_setContentSet:(
id)aSet
361 return [CPSet setWithArray:[
self content]];
370 - (CPArray)arrangeObjects:(CPArray)objects
377 var sortedObjects = [objects filteredArrayUsingPredicate:filterPredicate];
378 [sortedObjects sortUsingDescriptors:sortDescriptors];
379 return sortedObjects;
382 return [objects filteredArrayUsingPredicate:filterPredicate];
384 return [objects sortedArrayUsingDescriptors:sortDescriptors];
386 return [objects copy];
395 [
self _rearrangeObjects];
403 - (void)_rearrangeObjects
409 var oldSelectedObjects = nil,
410 oldSelectionIndexes = nil;
420 [
self __setSelectedObjects:oldSelectedObjects];
422 [
self __setSelectionIndexes:oldSelectionIndexes];
428 - (void)__setArrangedObjects:(
id)value
430 if (_arrangedObjects === value)
433 _arrangedObjects = [[_CPObservableArray alloc] initWithArray:value];
442 return _arrangedObjects;
451 return _sortDescriptors;
459 - (void)setSortDescriptors:(CPArray)value
461 if (_sortDescriptors === value)
464 _sortDescriptors = [value copy];
467 [
self _rearrangeObjects];
478 return _filterPredicate;
487 - (void)setFilterPredicate:(CPPredicate)value
489 if (_filterPredicate === value)
495 [
self __setFilterPredicate:value];
503 - (void)__setFilterPredicate:(CPPredicate)value
505 if (_filterPredicate === value)
508 _filterPredicate = value;
510 [
self _rearrangeObjects];
519 return _alwaysUsesMultipleValuesMarker;
529 return [_selectionIndexes firstIndex];
538 - (BOOL)setSelectionIndex:(
unsigned)index
550 return _selectionIndexes;
561 [
self _selectionWillChange]
562 var r = [
self __setSelectionIndexes:indexes avoidEmpty:NO];
563 [
self _selectionDidChange];
571 - (BOOL)__setSelectionIndex:(
int)theIndex
580 - (BOOL)__setSelectionIndexes:(
CPIndexSet)indexes
582 return [
self __setSelectionIndexes:indexes avoidEmpty:_avoidsEmptySelection];
585 - (BOOL)__setSelectionIndexes:(
CPIndexSet)indexes avoidEmpty:(BOOL)avoidEmpty
587 var newIndexes = indexes;
592 if (![newIndexes count])
604 newIndexes = [newIndexes copy];
607 [newIndexes removeIndexesInRange:CPMakeRange(objectsCount, [newIndexes lastIndex] + 1)];
609 if (![newIndexes count] && avoidEmpty && objectsCount)
613 if ([_selectionIndexes isEqualToIndexSet:newIndexes])
618 _selectionIndexes = indexes === newIndexes ? [indexes
copy] : newIndexes;
622 var binderClass = [[
self class] _binderClassForBinding:@"selectionIndexes"];
623 [[binderClass getBinding:@"selectionIndexes" forObject:self] reverseSetValueFor:@"selectionIndexes"];
636 return [_CPObservableArray arrayWithArray:(objects || [])];
645 - (BOOL)setSelectedObjects:(CPArray)objects
648 [
self _selectionWillChange];
650 var r = [
self __setSelectedObjects:objects avoidEmpty:NO];
653 [
self _selectionDidChange];
661 - (BOOL)__setSelectedObjects:(CPArray)objects
663 [
self __setSelectedObjects:objects avoidEmpty:_avoidsEmptySelection];
666 - (BOOL)__setSelectedObjects:(CPArray)objects avoidEmpty:(BOOL)avoidEmpty
669 count = [objects count],
672 for (var i = 0; i < count; i++)
677 [set addIndex:index];
680 [
self __setSelectionIndexes:set avoidEmpty:avoidEmpty];
699 - (void)selectPrevious:(
id)sender
721 - (void)selectNext:(
id)sender
736 - (void)addObject:(
id)object
741 var willClearPredicate = NO;
743 if (_clearsFilterPredicateOnInsertion && _filterPredicate)
746 willClearPredicate = YES;
758 _disableSetContent = YES;
759 [_contentObject addObject:object];
764 _disableSetContent = NO;
766 if (willClearPredicate)
769 _filterPredicate = nil;
770 [
self _rearrangeObjects];
772 else if (_filterPredicate === nil || [_filterPredicate evaluateWithObject:
object])
775 var pos = [_arrangedObjects insertObject:object inArraySortedByDescriptors:_sortDescriptors];
779 if (_selectsInsertedObjects)
780 [
self __setSelectionIndex:pos];
782 [_selectionIndexes shiftIndexesStartingAtIndex:pos by:1];
792 var proxy = [_CPKVOProxy proxyForObject:self];
793 [proxy setAdding:YES];
798 if (willClearPredicate)
802 [proxy setAdding:NO];
812 - (void)insertObject:(
id)anObject atArrangedObjectIndex:(
int)anIndex
817 var willClearPredicate = NO;
819 if (_clearsFilterPredicateOnInsertion && _filterPredicate)
822 willClearPredicate = YES;
830 _disableSetContent = YES;
835 [_contentObject addObject:anObject];
839 _disableSetContent = NO;
841 if (willClearPredicate)
842 [
self __setFilterPredicate:nil];
849 [
self __setSelectionIndex:anIndex];
856 var proxy = [_CPKVOProxy proxyForObject:self];
857 [proxy setAdding:YES];
861 if (willClearPredicate)
864 [proxy setAdding:NO];
872 - (void)removeObject:(
id)object
877 _disableSetContent = YES;
879 [_contentObject removeObject:object];
883 _disableSetContent = NO;
885 if (_filterPredicate === nil || [_filterPredicate evaluateWithObject:
object])
889 var pos = [_arrangedObjects indexOfObject:object];
891 [_arrangedObjects removeObjectAtIndex:pos];
892 [_selectionIndexes shiftIndexesStartingAtIndex:pos by:-1];
895 [
self __setSelectionIndexes:_selectionIndexes];
906 - (void)add:(
id)sender
920 - (void)insert:(
id)sender
926 lastSelectedIndex = [_selectionIndexes lastIndex];
938 - (void)remove:(
id)sender
947 - (void)removeObjectAtArrangedObjectIndex:(
int)index
956 - (void)removeObjectsAtArrangedObjectIndexes:(
CPIndexSet)anIndexSet
963 _disableSetContent = YES;
967 newSelectionIndexes = [_selectionIndexes copy];
975 if ([_contentObject objectAtIndex:anIndex] === object)
976 [_contentObject removeObjectAtIndex:anIndex];
984 var contentIndex = [_contentObject indexOfObjectIdenticalTo:object];
985 [_contentObject removeObjectAtIndex:contentIndex];
989 if (!_avoidsEmptySelection || [newSelectionIndexes count] > 1)
991 [newSelectionIndexes removeIndex:anIndex];
992 [newSelectionIndexes shiftIndexesStartingAtIndex:anIndex by:-1];
994 else if ([newSelectionIndexes lastIndex] !== anIndex)
995 [newSelectionIndexes shiftIndexesStartingAtIndex:anIndex by:-1];
1000 _disableSetContent = NO;
1003 [
self __setSelectionIndexes:newSelectionIndexes];
1013 - (void)addObjects:(CPArray)objects
1019 count = [objects count];
1021 for (var i = 0; i < count; i++)
1033 - (void)removeObjects:(CPArray)objects
1035 [
self _removeObjects:objects];
1041 - (void)_removeObjects:(CPArray)objects
1046 _disableSetContent = YES;
1048 [_contentObject removeObjectsInArray:objects];
1052 _disableSetContent = NO;
1055 position = [arrangedObjects indexOfObject:[objects objectAtIndex:0]];
1057 [arrangedObjects removeObjectsInArray:objects];
1059 var objectsCount = [arrangedObjects count],
1067 if (objectsCount <= 0)
1093 + (Class)_binderClassForBinding:(
CPString)aBinding
1095 if (aBinding ==
@"contentArray")
1096 return [_CPArrayControllerContentBinder class];
1098 return [
super _binderClassForBinding:aBinding];
1102 @implementation _CPArrayControllerContentBinder :
CPBinder 1107 - (void)setValueFor:(
CPString)aBinding
1109 var destination = [_info objectForKey:CPObservedObjectKey],
1110 keyPath = [_info objectForKey:CPObservedKeyPathKey],
1111 options = [_info objectForKey:CPOptionsKey],
1112 isCompound = [
self handlesContentAsCompoundValue],
1113 dotIndex = keyPath.lastIndexOf(
"."),
1114 firstPart = dotIndex !==
CPNotFound ? keyPath.substring(0, dotIndex) : nil,
1115 isSelectionProxy = firstPart && [[destination valueForKeyPath:firstPart] isKindOfClass:CPControllerSelectionProxy],
1118 if (!isCompound && !isSelectionProxy)
1120 newValue = [destination mutableArrayValueForKeyPath:keyPath];
1132 newValue = [destination valueForKeyPath:keyPath];
1142 reason:@"can't transform non applicable key on: " + _source + " value: " + newValue];
1145 newValue = [
self _placeholderForMarker:newValue];
1152 newValue = [
self transformValue:newValue withOptions:options];
1158 newValue = [newValue mutableCopy];
1161 [_source setValue:newValue forKey:aBinding];
1164 - (void)_contentArrayDidChange
1173 if ([
self handlesContentAsCompoundValue])
1175 var destination = [_info objectForKey:CPObservedObjectKey],
1176 keyPath = [_info objectForKey:CPObservedKeyPathKey];
1178 [
self suppressSpecificNotificationFromObject:destination keyPath:keyPath];
1179 [
self reverseSetValueFor:@"contentArray"];
1180 [
self unsuppressSpecificNotificationFromObject:destination keyPath:keyPath];
1202 _avoidsEmptySelection = [aCoder decodeBoolForKey:CPArrayControllerAvoidsEmptySelection];
1203 _clearsFilterPredicateOnInsertion = [aCoder decodeBoolForKey:CPArrayControllerClearsFilterPredicateOnInsertion];
1204 _filterRestrictsInsertion = [aCoder decodeBoolForKey:CPArrayControllerFilterRestrictsInsertion];
1205 _preservesSelection = [aCoder decodeBoolForKey:CPArrayControllerPreservesSelection];
1206 _selectsInsertedObjects = [aCoder decodeBoolForKey:CPArrayControllerSelectsInsertedObjects];
1207 _alwaysUsesMultipleValuesMarker = [aCoder decodeBoolForKey:CPArrayControllerAlwaysUsesMultipleValuesMarker];
1208 _automaticallyRearrangesObjects = [aCoder decodeBoolForKey:CPArrayControllerAutomaticallyRearrangesObjects];
1209 _sortDescriptors = [CPArray array];
1214 [
self _setContentArray:[]];
1224 [aCoder encodeBool:_avoidsEmptySelection forKey:CPArrayControllerAvoidsEmptySelection];
1225 [aCoder encodeBool:_clearsFilterPredicateOnInsertion forKey:CPArrayControllerClearsFilterPredicateOnInsertion];
1226 [aCoder encodeBool:_filterRestrictsInsertion forKey:CPArrayControllerFilterRestrictsInsertion];
1227 [aCoder encodeBool:_preservesSelection forKey:CPArrayControllerPreservesSelection];
1228 [aCoder encodeBool:_selectsInsertedObjects forKey:CPArrayControllerSelectsInsertedObjects];
1229 [aCoder encodeBool:_alwaysUsesMultipleValuesMarker forKey:CPArrayControllerAlwaysUsesMultipleValuesMarker];
1230 [aCoder encodeBool:_automaticallyRearrangesObjects forKey:CPArrayControllerAutomaticallyRearrangesObjects];
1235 [
self _selectionWillChange];
1236 [
self _selectionDidChange];
Used to implement exception handling (creating & raising).
CPArray arrangeObjects:(CPArray objects)
void enumerateIndexesWithOptions:usingBlock:(CPEnumerationOptions options, [usingBlock] Function/*(int idx,@ref BOOL stop)*/aFunction)
unsigned selectionIndex()
CPSet keyPathsForValuesAffectingSelectionIndexes()
void willChangeValueForKey:(CPString aKey)
BOOL selectsInsertedObjects()
BOOL automaticallyPreparesContent()
CPSet keyPathsForValuesAffectingArrangedObjects()
BOOL preservesSelection()
CPRaisesForNotApplicableKeysBindingOption
CPSet keyPathsForValuesAffectingCanSelectPrevious()
void raise:reason:(CPString aName, [reason] CPString aReason)
A collection of unique integers.
CPSet keyPathsForValuesAffectingSelectedObjects()
BOOL avoidsEmptySelection()
var CPArrayControllerAvoidsEmptySelection
void setContent:(id value)
CPArray sortDescriptors()
id initWithCoder:(CPCoder aCoder)
CPSet keyPathsForValuesAffectingSelectionIndex()
An immutable string (collection of characters).
CPSet keyPathsForValuesAffectingCanRemove()
void encodeWithCoder:(CPCoder aCoder)
void shiftIndexesStartingAtIndex:by:(CPInteger anIndex, [by] int aDelta)
void removeObjectsAtArrangedObjectIndexes:(CPIndexSet anIndexSet)
void insertObject:atArrangedObjectIndex:(id anObject, [atArrangedObjectIndex] int anIndex)
CPPredicate filterPredicate()
CPBinder getBinding:forObject:(CPString aBinding, [forObject] id anObject)
BOOL clearsFilterPredicateOnInsertion()
var CPArrayControllerSelectsInsertedObjects
var CPArrayControllerFilterRestrictsInsertion
void exposeBinding:(CPString aBinding)
void didChangeValueForKey:(CPString aKey)
BOOL automaticallyRearrangesObjects()
Defines methods for use when archiving & restoring (enc/decoding).
BOOL alwaysUsesMultipleValuesMarker()
CPSet keyPathsForValuesAffectingSelection()
CPSet keyPathsForValuesAffectingCanSelectNext()
BOOL setSelectionIndexes:(CPIndexSet indexes)
var CPArrayControllerAlwaysUsesMultipleValuesMarker
CPArray selectedObjects()
CPSet keyPathsForValuesAffectingContentArray()
var CPArrayControllerPreservesSelection
id indexSetWithIndex:(int anIndex)
void addObject:(id object)
CPIndexSet selectionIndexes()
var CPArrayControllerAutomaticallyRearrangesObjects
var CPArrayControllerClearsFilterPredicateOnInsertion