From 03a3560910ec5d18d662706f8dc6c94c15f326b9 Mon Sep 17 00:00:00 2001 From: rowanbeentje Date: Thu, 15 Apr 2010 01:33:32 +0000 Subject: - Tweak the history controller to track the toolbar item visibility, and only update it when visible - this fixes crashes after the toolbar item is removed from the toolbar and then updated (eg http://spbug.com/l/114 ) --- Source/SPHistoryController.h | 2 ++ Source/SPHistoryController.m | 68 +++++++++++++++++++++++++++++++++++++++++++- Source/TableDocument.m | 5 ++-- 3 files changed, 72 insertions(+), 3 deletions(-) (limited to 'Source') diff --git a/Source/SPHistoryController.h b/Source/SPHistoryController.h index 1ae1456c..b0f3e082 100644 --- a/Source/SPHistoryController.h +++ b/Source/SPHistoryController.h @@ -37,6 +37,7 @@ NSMutableDictionary *tableContentStates; NSUInteger historyPosition; BOOL modifyingState; + BOOL toolbarItemVisible; } @property (readonly) NSUInteger historyPosition; @@ -49,6 +50,7 @@ - (void)goForwardInHistory; - (IBAction) historyControlClicked:(NSSegmentedControl *)theControl; - (NSUInteger) currentlySelectedView; +- (void) setupInterface; // Adding or updating history entries - (void) updateHistoryEntries; diff --git a/Source/SPHistoryController.m b/Source/SPHistoryController.m index 2fbf18b5..dcef796c 100644 --- a/Source/SPHistoryController.m +++ b/Source/SPHistoryController.m @@ -56,10 +56,16 @@ { tableContentInstance = [theDocument valueForKey:@"tableContentInstance"]; tablesListInstance = [theDocument valueForKey:@"tablesListInstance"]; + toolbarItemVisible = NO; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(toolbarWillAddItem:) name:NSToolbarWillAddItemNotification object:[theDocument valueForKey:@"mainToolbar"]]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(toolbarDidRemoveItem:) name:NSToolbarDidRemoveItemNotification object:[theDocument valueForKey:@"mainToolbar"]]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(startDocumentTask:) name:SPDocumentTaskStartNotification object:theDocument]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(endDocumentTask:) name:SPDocumentTaskEndNotification object:theDocument]; } - (void) dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; [tableContentStates release]; [history release]; [super dealloc]; @@ -73,6 +79,11 @@ */ - (void) updateToolbarItem { + + // If the toolbar item isn't visible, don't perform any actions - as manipulating + // items not on the toolbar can cause crashes. + if (!toolbarItemVisible) return; + BOOL backEnabled = NO; BOOL forwardEnabled = NO; NSInteger i; @@ -81,7 +92,7 @@ // Set the active state of the segments if appropriate if ([history count] && historyPosition > 0) backEnabled = YES; if ([history count] && historyPosition + 1 < [history count]) forwardEnabled = YES; - + [historyControl setEnabled:backEnabled forSegment:0]; [historyControl setEnabled:forwardEnabled forSegment:1]; @@ -175,6 +186,61 @@ return theView; } +/** + * Set up the toolbar items as appropriate. + * State tracking is necessary as manipulating items not on the toolbar + * can cause crashes. + */ +- (void) setupInterface +{ + NSArray *toolbarItems = [[theDocument valueForKey:@"mainToolbar"] items]; + for (NSToolbarItem *toolbarItem in toolbarItems) { + if ([[toolbarItem itemIdentifier] isEqualToString:SPMainToolbarHistoryNavigation]) { + toolbarItemVisible = YES; + break; + } + } +} + +/** + * Disable the controls during a task. + */ +- (void) startDocumentTask:(NSNotification *)aNotification +{ + if (toolbarItemVisible) [historyControl setEnabled:NO]; +} + +/** + * Enable the controls once a task has completed. + */ +- (void) endDocumentTask:(NSNotification *)aNotification +{ + if (toolbarItemVisible) [historyControl setEnabled:YES]; +} + +/** + * Update the state when the item is added from the toolbar. + * State tracking is necessary as manipulating items not on the toolbar + * can cause crashes. + */ +- (void) toolbarWillAddItem:(NSNotification *)aNotification { + if ([[[[aNotification userInfo] objectForKey:@"item"] itemIdentifier] isEqualToString:SPMainToolbarHistoryNavigation]) { + toolbarItemVisible = YES; + [self performSelector:@selector(updateToolbarItem) withObject:nil afterDelay:0.1]; + } +} + +/** + * Update the state when the item is removed from the toolbar + * State tracking is necessary as manipulating items not on the toolbar + * can cause crashes. + */ +- (void) toolbarDidRemoveItem:(NSNotification *)aNotification { + if ([[[[aNotification userInfo] objectForKey:@"item"] itemIdentifier] isEqualToString:SPMainToolbarHistoryNavigation]) { + toolbarItemVisible = NO; + } +} + #pragma mark - #pragma mark Adding or updating history entries diff --git a/Source/TableDocument.m b/Source/TableDocument.m index b0465c0b..2e2d045d 100644 --- a/Source/TableDocument.m +++ b/Source/TableDocument.m @@ -1220,7 +1220,6 @@ [taskCancelButton setHidden:YES]; // Set flags and prevent further UI interaction in this window - [historyControl setEnabled:NO]; databaseListIsSelectable = NO; [[NSNotificationCenter defaultCenter] postNotificationName:SPDocumentTaskStartNotification object:self]; [mainToolbar validateVisibleItems]; @@ -1336,7 +1335,6 @@ [taskProgressIndicator setIndeterminate:YES]; // Re-enable window interface - [historyControl setEnabled:YES]; databaseListIsSelectable = YES; [[NSNotificationCenter defaultCenter] postNotificationName:SPDocumentTaskEndNotification object:self]; [mainToolbar validateVisibleItems]; @@ -3437,6 +3435,9 @@ // update the toolbar item size [self updateChooseDatabaseToolbarItemWidth]; + + // The history controller needs to track toolbar item state - trigger setup. + [spHistoryControllerInstance setupInterface]; } /** -- cgit v1.2.3