mirror of
https://github.com/darlinghq/darling-cocotron.git
synced 2024-11-27 14:00:22 +00:00
assorted controller behavior fixes
This commit is contained in:
parent
3c0f029d38
commit
418c3a5bd9
@ -9,7 +9,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
|
||||
#import <AppKit/NSObjectController.h>
|
||||
|
||||
@class NSPredicate,NSIndexSet;
|
||||
@class NSPredicate,NSIndexSet,NSMutableIndexSet;
|
||||
|
||||
@interface NSArrayController : NSObjectController {
|
||||
struct
|
||||
@ -21,7 +21,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
long selectsInsertedObjects:1;
|
||||
long alwaysUsesMultipleValuesMarker:1;
|
||||
} _flags;
|
||||
id _selectionIndexes;
|
||||
NSMutableIndexSet *_selectionIndexes;
|
||||
id _sortDescriptors;
|
||||
id _filterPredicate;
|
||||
id _arrangedObjects;
|
||||
|
@ -112,9 +112,9 @@ triggerChangeNotificationsForDependentKey:@"selectionIndex"];
|
||||
|
||||
-(void)setContent:(id)value
|
||||
{
|
||||
if(![value isKindOfClass:[NSArray class]])
|
||||
value=[NSArray arrayWithObject:value];
|
||||
|
||||
if(value!=nil && ![value isKindOfClass:[NSArray class]])
|
||||
value=[NSArray arrayWithObject:value];
|
||||
|
||||
id oldSelection=nil;
|
||||
id oldSelectionIndexes=[[[self selectionIndexes] copy] autorelease];
|
||||
if([self preservesSelection])
|
||||
@ -147,16 +147,19 @@ triggerChangeNotificationsForDependentKey:@"selectionIndex"];
|
||||
}
|
||||
|
||||
- (id)contentArray {
|
||||
return [self content];
|
||||
id result=[self content];
|
||||
return result;
|
||||
}
|
||||
|
||||
-(NSArray*)arrangeObjects:(NSArray*)objects
|
||||
{
|
||||
-(NSArray*)arrangeObjects:(NSArray*)objects {
|
||||
id sortedObjects=objects;
|
||||
|
||||
if([self filterPredicate])
|
||||
sortedObjects=[sortedObjects filteredArrayUsingPredicate:[self filterPredicate]];
|
||||
|
||||
if([self sortDescriptors])
|
||||
sortedObjects=[sortedObjects sortedArrayUsingDescriptors:[self sortDescriptors]];
|
||||
|
||||
return sortedObjects;
|
||||
}
|
||||
|
||||
@ -166,15 +169,11 @@ triggerChangeNotificationsForDependentKey:@"selectionIndex"];
|
||||
}
|
||||
|
||||
- (void)_setArrangedObjects:(id)value {
|
||||
if (_arrangedObjects != value)
|
||||
{
|
||||
[_arrangedObjects release];
|
||||
_arrangedObjects = [[_NSObservableArray alloc] initWithArray:value];
|
||||
}
|
||||
[_arrangedObjects autorelease];
|
||||
_arrangedObjects = [[_NSObservableArray alloc] initWithArray:value];
|
||||
}
|
||||
|
||||
-(id)arrangedObjects
|
||||
{
|
||||
-arrangedObjects {
|
||||
return _arrangedObjects;
|
||||
}
|
||||
|
||||
@ -221,23 +220,24 @@ triggerChangeNotificationsForDependentKey:@"selectionIndex"];
|
||||
}
|
||||
|
||||
- (NSIndexSet *)selectionIndexes {
|
||||
return [[_selectionIndexes retain] autorelease];
|
||||
return _selectionIndexes;
|
||||
}
|
||||
|
||||
- (BOOL)setSelectionIndexes:(NSIndexSet *)value {
|
||||
if(![value count] && _flags.avoidsEmptySelection && [[self arrangedObjects] count])
|
||||
value=[NSIndexSet indexSetWithIndex:0];
|
||||
|
||||
if(_flags.avoidsEmptySelection && [value count]==0 && [[self arrangedObjects] count])
|
||||
value=[NSIndexSet indexSetWithIndex:0];
|
||||
|
||||
value=[[value mutableCopy] autorelease];
|
||||
[(NSMutableIndexSet *)value removeIndexesInRange:NSMakeRange([[self arrangedObjects] count]+1, NSNotFound)];
|
||||
NSMutableIndexSet *mutableValue=[[value mutableCopy] autorelease];
|
||||
|
||||
[mutableValue removeIndexesInRange:NSMakeRange([[self arrangedObjects] count]+1, NSNotFound)];
|
||||
|
||||
// use isEqualToIndexSet: ?
|
||||
if (_selectionIndexes != value) {
|
||||
if (![_selectionIndexes isEqualToIndexSet: mutableValue]) {
|
||||
[self willChangeValueForKey:@"selectionIndexes"];
|
||||
[self _selectionWillChange];
|
||||
|
||||
[_selectionIndexes release];
|
||||
_selectionIndexes = [value copy];
|
||||
_selectionIndexes = [mutableValue retain];
|
||||
[self _selectionDidChange];
|
||||
|
||||
[self didChangeValueForKey:@"selectionIndexes"];
|
||||
@ -319,9 +319,6 @@ triggerChangeNotificationsForDependentKey:@"selectionIndex"];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark NSSet support
|
||||
|
||||
-(id)_contentSet
|
||||
{
|
||||
return [NSSet setWithArray:_content];
|
||||
@ -332,13 +329,8 @@ triggerChangeNotificationsForDependentKey:@"selectionIndex"];
|
||||
[self setContent:[set allObjects]];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Add/Remove
|
||||
|
||||
- (void)addObject:(id)object
|
||||
{
|
||||
if(![self canAdd])
|
||||
return;
|
||||
- (void)addObject:(id)object {
|
||||
// Don't check canAdd here as this can be used programmatically to add objects
|
||||
|
||||
[self willChangeValueForKey:@"content"];
|
||||
[_content addObject:object];
|
||||
@ -347,39 +339,44 @@ triggerChangeNotificationsForDependentKey:@"selectionIndex"];
|
||||
if(_flags.clearsFilterPredicateOnInsertion)
|
||||
[self setFilterPredicate:nil];
|
||||
|
||||
if([_filterPredicate evaluateWithObject:object])
|
||||
{
|
||||
[self willChangeValueForKey:@"selectionIndexes"];
|
||||
if([self filterPredicate]==nil || [_filterPredicate evaluateWithObject:object]){
|
||||
// FIXME: this should probably use arrangeObjects: to get subclass behavior
|
||||
[self willChangeValueForKey:@"arrangedObjects"];
|
||||
NSUInteger pos=[_arrangedObjects _insertObject:object inArraySortedByDescriptors:_sortDescriptors];
|
||||
[self didChangeValueForKey:@"arrangedObjects"];
|
||||
|
||||
[self willChangeValueForKey:@"selectionIndexes"];
|
||||
[_selectionIndexes shiftIndexesStartingAtIndex:pos by:1];
|
||||
[self didChangeValueForKey:@"selectionIndexes"];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void)removeObject:(id)object
|
||||
{
|
||||
if(![self canRemove])
|
||||
return;
|
||||
-(void)removeObject:(id)object {
|
||||
// Don't check canremove/editable here as this can be used programmatically to remove objects
|
||||
|
||||
[self willChangeValueForKey:@"content"];
|
||||
[_content removeObject:object];
|
||||
[self didChangeValueForKey:@"content"];
|
||||
|
||||
if([_filterPredicate evaluateWithObject:object])
|
||||
{
|
||||
if([self filterPredicate]==nil || [_filterPredicate evaluateWithObject:object]){
|
||||
// FIXME: this should probably use arrangeObjects: to get subclass behavior
|
||||
[self willChangeValueForKey:@"arrangedObjects"];
|
||||
NSUInteger pos=[_arrangedObjects indexOfObject:object];
|
||||
[self willChangeValueForKey:@"selectionIndexes"];
|
||||
[_arrangedObjects removeObject:object];
|
||||
[self didChangeValueForKey:@"arrangedObjects"];
|
||||
|
||||
[self willChangeValueForKey:@"selectionIndexes"];
|
||||
[_selectionIndexes shiftIndexesStartingAtIndex:pos by:-1];
|
||||
[self didChangeValueForKey:@"selectionIndexes"];
|
||||
}
|
||||
}
|
||||
|
||||
-(void)add:(id)sender
|
||||
{
|
||||
-(void)add:(id)sender {
|
||||
|
||||
if(![self canAdd])
|
||||
return;
|
||||
|
||||
[self insert:sender];
|
||||
}
|
||||
|
||||
@ -387,6 +384,7 @@ triggerChangeNotificationsForDependentKey:@"selectionIndex"];
|
||||
{
|
||||
if(![self canInsert])
|
||||
return;
|
||||
|
||||
id toAdd=nil;
|
||||
if([self automaticallyPreparesContent])
|
||||
toAdd=[[self newObject] autorelease];
|
||||
@ -395,22 +393,21 @@ triggerChangeNotificationsForDependentKey:@"selectionIndex"];
|
||||
[self addObject:toAdd];
|
||||
}
|
||||
|
||||
-(void)remove:(id)sender
|
||||
{
|
||||
-(void)remove:(id)sender {
|
||||
if(![self canRemove])
|
||||
return;
|
||||
|
||||
[self removeObjects:[[self contentArray] objectsAtIndexes:[self selectionIndexes]]];
|
||||
}
|
||||
|
||||
-(void)removeObjectsAtArrangedObjectIndexes:(NSIndexSet*)indexes
|
||||
{
|
||||
// FIXME: this should remove no matter what canRemove returns
|
||||
[self removeObjects:[[self contentArray] objectsAtIndexes:indexes]];
|
||||
-(void)removeObjectsAtArrangedObjectIndexes:(NSIndexSet*)indexes {
|
||||
[self removeObjects:[[self contentArray] objectsAtIndexes:indexes]];
|
||||
}
|
||||
|
||||
|
||||
- (void)addObjects:(NSArray *)objects
|
||||
{
|
||||
if(![self canAdd])
|
||||
return;
|
||||
- (void)addObjects:(NSArray *)objects {
|
||||
// Don't check canAdd/editable here as this can be used programmatically to add objects
|
||||
|
||||
id contentArray=[[[self contentArray] mutableCopy] autorelease];
|
||||
int count=[objects count];
|
||||
int i;
|
||||
@ -420,10 +417,8 @@ triggerChangeNotificationsForDependentKey:@"selectionIndex"];
|
||||
}
|
||||
|
||||
|
||||
- (void)removeObjects:(NSArray *)objects
|
||||
{
|
||||
if(![self canRemove])
|
||||
return;
|
||||
- (void)removeObjects:(NSArray *)objects {
|
||||
// Don't check canRemove here as this can be used programmatically to remove objects
|
||||
|
||||
id contentArray=[[[self contentArray] mutableCopy] autorelease];
|
||||
int count=[objects count];
|
||||
|
@ -164,7 +164,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
_NSObservationProxy *proxy=[[_NSObservationProxy alloc] initWithKeyPath:keyPath observer:observer object:self];
|
||||
int idx=[_observationProxies indexOfObject:proxy];
|
||||
if(idx==NSNotFound) {
|
||||
NSLog(@"%@ not found in %@", proxy, _observationProxies);
|
||||
}
|
||||
|
||||
[proxy release];
|
||||
|
@ -20,30 +20,27 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
@end
|
||||
|
||||
@implementation NSObjectController
|
||||
+(void)initialize
|
||||
{
|
||||
[self setKeys:[NSArray arrayWithObjects:@"editable", nil]
|
||||
triggerChangeNotificationsForDependentKey:@"canAdd"];
|
||||
[self setKeys:[NSArray arrayWithObjects:@"editable", nil]
|
||||
triggerChangeNotificationsForDependentKey:@"canInsert"];
|
||||
[self setKeys:[NSArray arrayWithObjects:@"editable", @"selection", nil]
|
||||
triggerChangeNotificationsForDependentKey:@"canRemove"];
|
||||
[self setKeys:[NSArray arrayWithObjects:@"content", nil]
|
||||
triggerChangeNotificationsForDependentKey:@"contentObject"];
|
||||
|
||||
+(void)initialize {
|
||||
[self setKeys:[NSArray arrayWithObjects:@"editable", nil] triggerChangeNotificationsForDependentKey:@"canAdd"];
|
||||
[self setKeys:[NSArray arrayWithObjects:@"editable", nil] triggerChangeNotificationsForDependentKey:@"canInsert"];
|
||||
[self setKeys:[NSArray arrayWithObjects:@"editable", @"selection", nil] triggerChangeNotificationsForDependentKey:@"canRemove"];
|
||||
[self setKeys:[NSArray arrayWithObjects:@"content", nil] triggerChangeNotificationsForDependentKey:@"contentObject"];
|
||||
}
|
||||
|
||||
-(id)initWithCoder:(NSCoder*)coder
|
||||
{
|
||||
if((self=[super init]))
|
||||
{
|
||||
_objectClassName=[[coder decodeObjectForKey:@"NSObjectClassName"] retain];
|
||||
_editable = [coder decodeBoolForKey:@"NSEditable"];
|
||||
_automaticallyPreparesContent = [coder decodeBoolForKey:@"NSAutomaticallyPreparesContent"];
|
||||
_observedKeys=[[NSCountedSet alloc] init];
|
||||
_selection=[[NSControllerSelectionProxy alloc] initWithController:self];
|
||||
}
|
||||
return self;
|
||||
-initWithCoder:(NSCoder*)coder {
|
||||
if((self=[super init])) {
|
||||
|
||||
_objectClassName=[[coder decodeObjectForKey:@"NSObjectClassName"] copy];
|
||||
if(_objectClassName==nil)
|
||||
_objectClassName=@"NSMutableDictionary";
|
||||
|
||||
_editable = [coder decodeBoolForKey:@"NSEditable"];
|
||||
_automaticallyPreparesContent = [coder decodeBoolForKey:@"NSAutomaticallyPreparesContent"];
|
||||
|
||||
_observedKeys=[[NSCountedSet alloc] init];
|
||||
_selection=[[NSControllerSelectionProxy alloc] initWithController:self];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)content {
|
||||
@ -73,7 +70,8 @@ triggerChangeNotificationsForDependentKey:@"contentObject"];
|
||||
|
||||
-(NSArray *)selectedObjects
|
||||
{
|
||||
return [NSArray arrayWithObject:_content];
|
||||
NSArray *result=[NSArray arrayWithObject:_content];
|
||||
return result;
|
||||
}
|
||||
|
||||
-(id)selection
|
||||
|
@ -15,7 +15,7 @@
|
||||
void* _context;
|
||||
NSKeyValueObservingOptions _options;
|
||||
}
|
||||
-(id)initWithKeyPath:(id)keyPath observer:(id)observer object:(id)object;
|
||||
-initWithKeyPath:(NSString *)keyPath observer:(id)observer object:(id)object;
|
||||
-(id)observer;
|
||||
-(id)keyPath;
|
||||
-(void)setNotifyObject:(BOOL)val;
|
||||
|
@ -1,46 +1,58 @@
|
||||
/* Copyright (c) 2007 Johannes Fortmann
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
#import "NSObservationProxy.h"
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSString.h>
|
||||
#import <Foundation/NSException.h>
|
||||
#import "NSStringKVCFunctions.h"
|
||||
#import <Foundation/NSKeyValueObserving.h>
|
||||
#import <Foundation/NSIndexSet.h>
|
||||
|
||||
@implementation _NSObservationProxy
|
||||
-(id)initWithKeyPath:(id)keyPath observer:(id)observer object:(id)object
|
||||
{
|
||||
if((self=[super init]))
|
||||
void NSStringKVCSplitOnDot(NSString *self,NSString **before,NSString **after){
|
||||
NSRange range=[self rangeOfString:@"."];
|
||||
if(range.location!=NSNotFound)
|
||||
{
|
||||
_keyPath=[keyPath retain];
|
||||
_observer=observer;
|
||||
_object=object;
|
||||
*before=[self substringToIndex:range.location];
|
||||
*after=[self substringFromIndex:range.location+1];
|
||||
}
|
||||
else
|
||||
{
|
||||
*before=self;
|
||||
*after=nil;
|
||||
}
|
||||
}
|
||||
|
||||
@implementation _NSObservationProxy
|
||||
|
||||
-initWithKeyPath:(NSString *)keyPath observer:(id)observer object:(id)object {
|
||||
_keyPath=[keyPath retain];
|
||||
_observer=observer;
|
||||
_object=object;
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)dealloc
|
||||
{
|
||||
[_keyPath release];
|
||||
[super dealloc];
|
||||
-(void)dealloc {
|
||||
[_keyPath release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
-(id)observer
|
||||
{
|
||||
-observer {
|
||||
return _observer;
|
||||
}
|
||||
|
||||
-(id)keyPath
|
||||
{
|
||||
return _keyPath;
|
||||
-keyPath {
|
||||
return _keyPath;
|
||||
}
|
||||
|
||||
-(void*)context
|
||||
{
|
||||
-(void *)context {
|
||||
return _context;
|
||||
}
|
||||
|
||||
-(NSKeyValueObservingOptions)options
|
||||
{
|
||||
-(NSKeyValueObservingOptions)options {
|
||||
return _options;
|
||||
}
|
||||
|
||||
@ -60,76 +72,54 @@
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath
|
||||
ofObject:(id)object
|
||||
change:(NSDictionary *)change
|
||||
context:(void *)context
|
||||
{
|
||||
if(_notifyObject)
|
||||
{
|
||||
[_object observeValueForKeyPath:_keyPath
|
||||
ofObject:_object
|
||||
change:change
|
||||
context:_context];
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
|
||||
if(_notifyObject) {
|
||||
[_object observeValueForKeyPath:_keyPath ofObject:_object change:change context:_context];
|
||||
}
|
||||
|
||||
[_observer observeValueForKeyPath:_keyPath
|
||||
ofObject:_object
|
||||
change:change
|
||||
context:_context];
|
||||
[_observer observeValueForKeyPath:_keyPath ofObject:_object change:change context:_context];
|
||||
}
|
||||
|
||||
-(NSString*)description
|
||||
{
|
||||
-(NSString *)description {
|
||||
return [NSString stringWithFormat:@"observation proxy for %@ on key path %@", _observer, _keyPath];
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation _NSObservableArray
|
||||
|
||||
-(id)objectAtIndex:(NSUInteger)idx
|
||||
{
|
||||
return [_array objectAtIndex:idx];
|
||||
-objectAtIndex:(NSUInteger)idx {
|
||||
return [_array objectAtIndex:idx];
|
||||
}
|
||||
|
||||
-(NSUInteger)count
|
||||
{
|
||||
-(NSUInteger)count {
|
||||
return [_array count];
|
||||
}
|
||||
|
||||
-(id)init {
|
||||
-init {
|
||||
return [self initWithObjects:NULL count:0];
|
||||
}
|
||||
|
||||
-initWithObjects:(id *)objects count:(NSUInteger)count;
|
||||
{
|
||||
if((self=[super init]))
|
||||
{
|
||||
_array=[[NSMutableArray alloc] initWithObjects:objects count:count];
|
||||
_observationProxies=[NSMutableArray new];
|
||||
}
|
||||
-initWithObjects:(id *)objects count:(NSUInteger)count {
|
||||
_array=[[NSMutableArray alloc] initWithObjects:objects count:count];
|
||||
_observationProxies=[NSMutableArray new];
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)dealloc
|
||||
{
|
||||
if([_observationProxies count]>0)
|
||||
[NSException raise:NSInvalidArgumentException
|
||||
format:@"_NSObservableArray still being observed by %@ on %@",
|
||||
[[_observationProxies objectAtIndex:0] observer],
|
||||
[[_observationProxies objectAtIndex:0] keyPath]];
|
||||
[_observationProxies release];
|
||||
[_array release];
|
||||
-(void)dealloc {
|
||||
if([_observationProxies count]>0)
|
||||
[NSException raise:NSInvalidArgumentException format:@"_NSObservableArray still being observed by %@ on %@",
|
||||
[[_observationProxies objectAtIndex:0] observer],[[_observationProxies objectAtIndex:0] keyPath]];
|
||||
|
||||
[_observationProxies release];
|
||||
[_array release];
|
||||
[_roi release];
|
||||
[super dealloc];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
-(void)addObserver:(id)observer forKeyPath:(NSString*)keyPath options:(NSKeyValueObservingOptions)options context:(void*)context;
|
||||
{
|
||||
-(void)addObserver:(id)observer forKeyPath:(NSString*)keyPath options:(NSKeyValueObservingOptions)options context:(void*)context {
|
||||
// init the proxy
|
||||
_NSObservationProxy *proxy=[[_NSObservationProxy alloc] initWithKeyPath:keyPath
|
||||
observer:observer
|
||||
object:self];
|
||||
_NSObservationProxy *proxy=[[_NSObservationProxy alloc] initWithKeyPath:keyPath observer:observer object:self];
|
||||
|
||||
proxy->_options=options;
|
||||
proxy->_context=context;
|
||||
[_observationProxies addObject:proxy];
|
||||
@ -149,10 +139,7 @@
|
||||
NSStringKVCSplitOnDot(keyPath,&firstPart,&rest);
|
||||
|
||||
// observe ourselves
|
||||
[super addObserver:observer
|
||||
forKeyPath:keyPath
|
||||
options:options
|
||||
context:context];
|
||||
[super addObserver:observer forKeyPath:keyPath options:options context:context];
|
||||
|
||||
// if there's anything the operator depends on, observe _all_ objects for that path
|
||||
keyPath=rest;
|
||||
@ -161,20 +148,13 @@
|
||||
|
||||
// add observer proxy for all relevant indexes
|
||||
if([_array count] && keyPath) {
|
||||
[_array addObserver:proxy
|
||||
toObjectsAtIndexes:idxs
|
||||
forKeyPath:keyPath
|
||||
options:options
|
||||
context:context];
|
||||
[_array addObserver:proxy toObjectsAtIndexes:idxs forKeyPath:keyPath options:options context:context];
|
||||
}
|
||||
}
|
||||
|
||||
-(void)removeObserver:(id)observer forKeyPath:(NSString*)keyPath;
|
||||
{
|
||||
-(void)removeObserver:(id)observer forKeyPath:(NSString*)keyPath {
|
||||
// find the proxy again
|
||||
_NSObservationProxy *proxy=[[_NSObservationProxy alloc] initWithKeyPath:keyPath
|
||||
observer:observer
|
||||
object:self];
|
||||
_NSObservationProxy *proxy=[[_NSObservationProxy alloc] initWithKeyPath:keyPath observer:observer object:self];
|
||||
int idx=[_observationProxies indexOfObject:proxy];
|
||||
[proxy release];
|
||||
proxy=[[[_observationProxies objectAtIndex:idx] retain] autorelease];
|
||||
@ -194,17 +174,14 @@
|
||||
NSString* firstPart, *rest;
|
||||
NSStringKVCSplitOnDot(keyPath,&firstPart,&rest);
|
||||
|
||||
[super removeObserver:observer
|
||||
forKeyPath:keyPath];
|
||||
[super removeObserver:observer forKeyPath:keyPath];
|
||||
|
||||
// remove dependent key path from all children
|
||||
keyPath=rest;
|
||||
idxs=[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [_array count])];
|
||||
}
|
||||
if([_array count] && keyPath) {
|
||||
[_array removeObserver:proxy
|
||||
fromObjectsAtIndexes:idxs
|
||||
forKeyPath:keyPath];
|
||||
[_array removeObserver:proxy fromObjectsAtIndexes:idxs forKeyPath:keyPath];
|
||||
}
|
||||
}
|
||||
|
||||
@ -263,14 +240,13 @@
|
||||
NSString* firstPart, *rest;
|
||||
NSStringKVCSplitOnDot(keyPath,&firstPart,&rest);
|
||||
|
||||
if(rest)
|
||||
[obj removeObserver:proxy
|
||||
forKeyPath:rest];
|
||||
if(rest) {
|
||||
[obj removeObserver:proxy forKeyPath:rest];
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(!_roi || [_roi containsIndex:idx]) {
|
||||
[obj removeObserver:proxy
|
||||
forKeyPath:keyPath];
|
||||
[obj removeObserver:proxy forKeyPath:keyPath];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -288,13 +264,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
-(void)addObject:(id)obj
|
||||
{
|
||||
-(void)addObject:(id)obj {
|
||||
[self insertObject:obj atIndex:[self count]];
|
||||
}
|
||||
|
||||
-(void)removeLastObject
|
||||
{
|
||||
-(void)removeLastObject {
|
||||
[self removeObjectAtIndex:[self count]-1];
|
||||
}
|
||||
|
||||
@ -311,8 +285,7 @@
|
||||
NSStringKVCSplitOnDot(keyPath,&firstPart,&rest);
|
||||
|
||||
if(rest) {
|
||||
[old removeObserver:proxy
|
||||
forKeyPath:[proxy keyPath]];
|
||||
[old removeObserver:proxy forKeyPath:[proxy keyPath]];
|
||||
|
||||
[obj addObserver:proxy
|
||||
forKeyPath:rest
|
||||
@ -322,8 +295,7 @@
|
||||
}
|
||||
else {
|
||||
if(!_roi || [_roi containsIndex:idx]) {
|
||||
[old removeObserver:proxy
|
||||
forKeyPath:[proxy keyPath]];
|
||||
[old removeObserver:proxy forKeyPath:[proxy keyPath]];
|
||||
|
||||
[obj addObserver:proxy
|
||||
forKeyPath:[proxy keyPath]
|
||||
|
@ -1,23 +0,0 @@
|
||||
/* Copyright (c) 2007 Johannes Fortmann
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
|
||||
#import <Foundation/NSString.h>
|
||||
|
||||
void NSStringKVCSplitOnDot(NSString *self,NSString **before,NSString **after){
|
||||
NSRange range=[self rangeOfString:@"."];
|
||||
if(range.location!=NSNotFound)
|
||||
{
|
||||
*before=[self substringToIndex:range.location];
|
||||
*after=[self substringFromIndex:range.location+1];
|
||||
}
|
||||
else
|
||||
{
|
||||
*before=self;
|
||||
*after=nil;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user