From 05b0abacd4d786cea65d253a7716db87338194f0 Mon Sep 17 00:00:00 2001 From: Randall Luecke Date: Fri, 22 Apr 2011 12:53:49 -0400 Subject: [PATCH 1/5] When dragging horizontally we need to update the location of the header view too --- AppKit/CPDragServer.j | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/AppKit/CPDragServer.j b/AppKit/CPDragServer.j index 9d3344b09..bc67ee490 100644 --- a/AppKit/CPDragServer.j +++ b/AppKit/CPDragServer.j @@ -270,10 +270,10 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0, { if ([scrollView hasVerticalScroller]) { - if (eventLocation.y < CGRectGetMinY(insetBounds)) - deltaY = CGRectGetMinY(insetBounds) - eventLocation.y; - else if (eventLocation.y > CGRectGetMaxY(insetBounds)) - deltaY = CGRectGetMaxY(insetBounds) - eventLocation.y; + if (eventLocation.y < _CGRectGetMinY(insetBounds)) + deltaY = _CGRectGetMinY(insetBounds) - eventLocation.y; + else if (eventLocation.y > _CGRectGetMaxY(insetBounds)) + deltaY = _CGRectGetMaxY(insetBounds) - eventLocation.y; if (deltaY < -insetBounds.size.height) deltaY = -insetBounds.size.height; if (deltaY > insetBounds.size.height) @@ -282,17 +282,21 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0, if ([scrollView hasHorizontalScroller]) { - if (eventLocation.x < CGRectGetMinX(insetBounds)) - deltaX = CGRectGetMinX(insetBounds) - eventLocation.x; - else if (eventLocation.x > CGRectGetMaxX(insetBounds)) - deltaX = CGRectGetMaxX(insetBounds) - eventLocation.x; + if (eventLocation.x < _CGRectGetMinX(insetBounds)) + deltaX = _CGRectGetMinX(insetBounds) - eventLocation.x; + else if (eventLocation.x > _CGRectGetMaxX(insetBounds)) + deltaX = _CGRectGetMaxX(insetBounds) - eventLocation.x; if (deltaX < -insetBounds.size.width) deltaX = -insetBounds.size.width; if (deltaX > insetBounds.size.width) deltaX = insetBounds.size.width; } - [contentView scrollToPoint:CGPointMake(bounds.origin.x - deltaX, bounds.origin.y - deltaY)]; + var scrollPoint = _CGPointMake(bounds.origin.x - deltaX, bounds.origin.y - deltaY); + + [contentView scrollToPoint:scrollPoint]; + [[scrollView _headerView] scrollPoint:scrollPoint]; + } } } From 26afe7c0d84c8e448dd2628c2f98aebbb924c42b Mon Sep 17 00:00:00 2001 From: Randall Luecke Date: Sun, 24 Apr 2011 22:28:41 -0400 Subject: [PATCH 2/5] Fix return type on sortUsingDescriptors in CPMutableArray. --- Foundation/CPArray/CPMutableArray.j | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Foundation/CPArray/CPMutableArray.j b/Foundation/CPArray/CPMutableArray.j index bf0874224..e9588dd51 100644 --- a/Foundation/CPArray/CPMutableArray.j +++ b/Foundation/CPArray/CPMutableArray.j @@ -332,7 +332,7 @@ [self replaceObjectAtIndex:otherIndex withObject:temporary]; } -- (CPArray)sortUsingDescriptors:(CPArray)descriptors +- (void)sortUsingDescriptors:(CPArray)descriptors { [self sortUsingFunction:compareObjectsUsingDescriptors context:descriptors]; } From 03e7d81ffa79887d2f45adefdadd427e9d7ec7f6 Mon Sep 17 00:00:00 2001 From: Klaas Pieter Annema Date: Tue, 26 Apr 2011 11:16:36 +0200 Subject: [PATCH 3/5] fail more gracefully when attempting to remove the same observer twice Before this commit we would fail gracefully for single keys. For key paths an application would crash because we would try to get the forwarder property of an undefined object. This commit makes sure we don't attempt any removal and logs a warning (just like Cocoa) about the attempt to remove an unregistered observer. --- Foundation/CPKeyValueObserving.j | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Foundation/CPKeyValueObserving.j b/Foundation/CPKeyValueObserving.j index fbac24c09..ee72d91fc 100644 --- a/Foundation/CPKeyValueObserving.j +++ b/Foundation/CPKeyValueObserving.j @@ -678,6 +678,14 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti { var observers = _observersForKey[aPath]; + if (!observers) + { + CPLog.warn(@"Cannot remove an observer %@ for the key path \"%@\" from %@ because it is not registered as an observer.", + _targetObject, aPath, anObserver); + + return; + } + if (aPath.indexOf('.') != CPNotFound) { var forwarder = [observers objectForKey:[anObserver UID]].forwarder; From 0ee304058d397d25502853c76abdd48ab09ad7e5 Mon Sep 17 00:00:00 2001 From: Klaas Pieter Annema Date: Tue, 26 Apr 2011 11:20:47 +0200 Subject: [PATCH 4/5] consolidate both CPKeyValueObservingTests into one --- Tests/AppKit/CPKeyValueObservingTest.j | 106 --------------------- Tests/Foundation/CPKeyValueObservingTest.j | 95 ++++++++++++++++++ 2 files changed, 95 insertions(+), 106 deletions(-) delete mode 100644 Tests/AppKit/CPKeyValueObservingTest.j diff --git a/Tests/AppKit/CPKeyValueObservingTest.j b/Tests/AppKit/CPKeyValueObservingTest.j deleted file mode 100644 index 67e3cd07b..000000000 --- a/Tests/AppKit/CPKeyValueObservingTest.j +++ /dev/null @@ -1,106 +0,0 @@ -@import - -@implementation CPKeyValueObservingTest : OJTestCase -{ - CPString _lastKeyPath; - id _lastObject; - CPDictionary _lastChange; - id _lastContext; -} - -- (void)setup -{ - _lastKeyPath = _lastObject = _lastChange = _lastContext = nil; -} - -- (void)testInitialObserving -{ - var tester = [ObservingTester testerWithCheese:@"CHEESE!"]; - [tester addObserver:self forKeyPath:@"cheese" options:CPKeyValueObservingOptionNew | CPKeyValueObservingOptionInitial context:nil]; - - [self assert:@"cheese" equals:_lastKeyPath]; - [self assert:tester equals:_lastObject]; - [self assert:[CPDictionary dictionaryWithObject:@"CHEESE!" forKey:CPKeyValueChangeNewKey] equals:_lastChange]; - [self assert:nil equals:_lastContext]; -} - -- (void)observeValueForKeyPath:(CPString)aKeyPath - ofObject:(id)anObject - change:(CPDictionary)aChange - context:(id)aContext -{ - _lastKeyPath = aKeyPath; - _lastObject = anObject; - _lastChange = aChange; - _lastContext = aContext; -} - -- (void)testSendNotificationsForDependantKeyPaths -{ - var observingTester = [ObservingTester testerWithCheese:@"cheese"], - dependantKeyPathTester = [DependantKeyPathsTester testerWithObservingTester:observingTester]; - - [dependantKeyPathTester addObserver:self forKeyPath:@"observedCheese" options:CPKeyValueObservingOptionNew context:nil]; - [observingTester setCheese:@"changed cheese"]; - - [self assert:@"observedCheese" equals:_lastKeyPath] - [self assert:dependantKeyPathTester equals:_lastObject]; -} - -@end - -@implementation ObservingTester : CPObject -{ - id cheese; -} - -+ (id)testerWithCheese:(id)aCheese -{ - var tester = [[self alloc] init]; - [tester setCheese:aCheese]; - return tester; -} - -- (void)setCheese:(id)aCheese -{ - cheese = aCheese; -} - -- (id)cheese -{ - return cheese; -} - -@end - -@implementation DependantKeyPathsTester: CPObject -{ - ObservingTester _observingTester @accessors(property=observingTester); -} - -+ (CPSet)keyPathsForValuesAffectingObservedCheese -{ - return [CPSet setWithObjects:@"observingTester.cheese"]; -} - -+ (id)testerWithObservingTester:(ObservingTester)theObservingTester -{ - return [[self alloc] initWithObservingTester:theObservingTester]; -} - -- (id)initWithObservingTester:(ObservingTester)theObservingTester -{ - if (self = [super init]) - { - _observingTester = theObservingTester; - } - - return self; -} - -- (CPString)observedCheese -{ - return [[self observingTester] cheese]; -} - -@end diff --git a/Tests/Foundation/CPKeyValueObservingTest.j b/Tests/Foundation/CPKeyValueObservingTest.j index 5d43fc8da..2d409618f 100644 --- a/Tests/Foundation/CPKeyValueObservingTest.j +++ b/Tests/Foundation/CPKeyValueObservingTest.j @@ -22,6 +22,45 @@ return [theClass new]; } +- (void)setup +{ + _lastKeyPath = _lastObject = _lastChange = _lastContext = nil; +} + +- (void)testInitialObserving +{ + var tester = [ObservingTester testerWithCheese:@"CHEESE!"]; + [tester addObserver:self forKeyPath:@"cheese" options:CPKeyValueObservingOptionNew | CPKeyValueObservingOptionInitial context:nil]; + + [self assert:@"cheese" equals:_lastKeyPath]; + [self assert:tester equals:_lastObject]; + [self assert:[CPDictionary dictionaryWithObject:@"CHEESE!" forKey:CPKeyValueChangeNewKey] equals:_lastChange]; + [self assert:nil equals:_lastContext]; +} + +- (void)observeValueForKeyPath:(CPString)aKeyPath + ofObject:(id)anObject + change:(CPDictionary)aChange + context:(id)aContext +{ + _lastKeyPath = aKeyPath; + _lastObject = anObject; + _lastChange = aChange; + _lastContext = aContext; +} + +- (void)testSendNotificationsForDependantKeyPaths +{ + var observingTester = [ObservingTester testerWithCheese:@"cheese"], + dependantKeyPathTester = [DependantKeyPathsTester testerWithObservingTester:observingTester]; + + [dependantKeyPathTester addObserver:self forKeyPath:@"observedCheese" options:CPKeyValueObservingOptionNew context:nil]; + [observingTester setCheese:@"changed cheese"]; + + [self assert:@"observedCheese" equals:_lastKeyPath] + [self assert:dependantKeyPathTester equals:_lastObject]; +} + - (void)testOnlyInsertObject_AtKeyIndex_Implemented { var insertSelector = @selector(insertObject:inObjectsAtIndex:), @@ -155,3 +194,59 @@ } @end + +@implementation ObservingTester : CPObject +{ + id cheese; +} + ++ (id)testerWithCheese:(id)aCheese +{ + var tester = [[self alloc] init]; + [tester setCheese:aCheese]; + return tester; +} + +- (void)setCheese:(id)aCheese +{ + cheese = aCheese; +} + +- (id)cheese +{ + return cheese; +} + +@end + +@implementation DependantKeyPathsTester: CPObject +{ + ObservingTester _observingTester @accessors(property=observingTester); +} + ++ (CPSet)keyPathsForValuesAffectingObservedCheese +{ + return [CPSet setWithObjects:@"observingTester.cheese"]; +} + ++ (id)testerWithObservingTester:(ObservingTester)theObservingTester +{ + return [[self alloc] initWithObservingTester:theObservingTester]; +} + +- (id)initWithObservingTester:(ObservingTester)theObservingTester +{ + if (self = [super init]) + { + _observingTester = theObservingTester; + } + + return self; +} + +- (CPString)observedCheese +{ + return [[self observingTester] cheese]; +} + +@end From 10ec8b528c0d3c73c6a00291f342fa9406c125c3 Mon Sep 17 00:00:00 2001 From: Alexander Ljungberg Date: Wed, 27 Apr 2011 13:14:44 -0400 Subject: [PATCH 5/5] Correct return type for [CPURL staticResourceData]. --- Foundation/CPURL.j | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Foundation/CPURL.j b/Foundation/CPURL.j index 1b60010a0..810677c7e 100644 --- a/Foundation/CPURL.j +++ b/Foundation/CPURL.j @@ -227,7 +227,7 @@ CPURLCustomIconKey = @"CPURLCustomIconKey"; return self.setResourcePropertyForKey(aKey, anObject); } -- (CPString)staticResourceData +- (CPData)staticResourceData { return self.staticResourceData(); }