diff options
author | rowanbeentje <rowan@beent.je> | 2009-11-15 23:58:21 +0000 |
---|---|---|
committer | rowanbeentje <rowan@beent.je> | 2009-11-15 23:58:21 +0000 |
commit | 50a283b6d1f3ce48e3a06eceeed3a466c6259fe7 (patch) | |
tree | 98596427c436f4735ec9baee45da66248e83291c /Source/TableDocument.m | |
parent | 69a4fbc7cf11a35e5bf609cf7a16d2844559997c (diff) | |
download | sequelpro-50a283b6d1f3ce48e3a06eceeed3a466c6259fe7.tar.gz sequelpro-50a283b6d1f3ce48e3a06eceeed3a466c6259fe7.tar.bz2 sequelpro-50a283b6d1f3ce48e3a06eceeed3a466c6259fe7.zip |
Implement query cancellation support within MCPKit, and add it to the task functionality:
- MCPKit now supports cancelling the active query; for MySQL servers >= 5.0.0 a query kill is attempted from a new connection, and if that fails or for MySQL < 5 a reconnect is triggered.
- TableDocument now supports enabling a cancel task button on the task interface, including an optional callback
- Implement query cancellation for custom queries. This addresses Issue #86.
- Implement query cancellation for table content loads, filters, and sorts.
Diffstat (limited to 'Source/TableDocument.m')
-rw-r--r-- | Source/TableDocument.m | 70 |
1 files changed, 64 insertions, 6 deletions
diff --git a/Source/TableDocument.m b/Source/TableDocument.m index fa07e143..78df5e16 100644 --- a/Source/TableDocument.m +++ b/Source/TableDocument.m @@ -103,6 +103,9 @@ taskProgressValueDisplayInterval = 1; taskDrawTimer = nil; taskFadeAnimator = nil; + taskCanBeCancelled = NO; + taskCancellationCallbackObject = nil; + taskCancellationCallbackSelector = NULL; keyChainID = nil; } @@ -223,15 +226,17 @@ NSLog(@"Progress indicator layer could not be loaded; progress display will not function correctly."); } - // Set up the progress indicator child window and later - add to main window, change indicator color and size + // Set up the progress indicator child window and layer - add to main window, change indicator color and size + [taskProgressIndicator setForeColor:[NSColor whiteColor]]; taskProgressWindow = [[NSWindow alloc] initWithContentRect:[taskProgressLayer bounds] styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]; [taskProgressWindow setOpaque:NO]; - [taskProgressWindow setIgnoresMouseEvents:YES]; [taskProgressWindow setBackgroundColor:[NSColor clearColor]]; [taskProgressWindow setAlphaValue:0.0]; - [[taskProgressWindow contentView] addSubview:taskProgressLayer]; + [taskProgressWindow orderWindow:NSWindowAbove relativeTo:[tableWindow windowNumber]]; [tableWindow addChildWindow:taskProgressWindow ordered:NSWindowAbove]; - [taskProgressIndicator setForeColor:[NSColor whiteColor]]; + [taskProgressWindow release]; + [taskProgressWindow setContentView:taskProgressLayer]; + [self centerTaskWindow]; } /** @@ -1258,7 +1263,7 @@ [historyControl setEnabled:NO]; databaseListIsSelectable = NO; [[NSNotificationCenter defaultCenter] postNotificationName:SPDocumentTaskStartNotification object:self]; - + // Schedule appearance of the task window in the near future taskDrawTimer = [[NSTimer scheduledTimerWithTimeInterval:0.25 target:self selector:@selector(showTaskProgressWindow:) userInfo:nil repeats:NO] retain]; } @@ -1333,6 +1338,9 @@ // Decrement the working level _isWorkingLevel--; + // Ensure cancellation interface is reset + [self disableTaskCancellation]; + // If all tasks have ended, re-enable the interface if (!_isWorkingLevel) { @@ -1358,6 +1366,57 @@ } /** + * Allow a task to be cancelled, enabling the button with a supplied title + * and optionally supplying a callback object and function. + */ +- (void) enableTaskCancellationWithTitle:(NSString *)buttonTitle callbackObject:(id)callbackObject callbackFunction:(SEL)callbackFunction +{ + + // If no task is active, return + if (!_isWorkingLevel) return; + + if (callbackObject && callbackFunction) { + taskCancellationCallbackObject = callbackObject; + taskCancellationCallbackSelector = callbackFunction; + } + taskCanBeCancelled = YES; + + [taskCancelButton setTitle:buttonTitle]; + [taskCancelButton setEnabled:YES]; + [taskCancelButton setHidden:NO]; +} + +/** + * Disable task cancellation. Called automatically at the end of a task. + */ +- (void) disableTaskCancellation +{ + + // If no task is active, return + if (!_isWorkingLevel) return; + + taskCanBeCancelled = NO; + taskCancellationCallbackObject = nil; + taskCancellationCallbackSelector = NULL; + [taskCancelButton setHidden:YES]; +} + +/** + * Action sent by the cancel button when it's active. + */ +- (IBAction) cancelTask:(id)sender +{ + if (!taskCanBeCancelled) return; + + [taskCancelButton setEnabled:NO]; + [mySQLConnection cancelCurrentQuery]; + + if (taskCancellationCallbackObject && taskCancellationCallbackSelector) { + [taskCancellationCallbackObject performSelector:taskCancellationCallbackSelector]; + } +} + +/** * Returns whether the document is busy performing a task - allows UI or actions * to be restricted as appropriate. */ @@ -3553,7 +3612,6 @@ if (spfSession) [spfSession release]; if (spfDocData) [spfDocData release]; if (keyChainID) [keyChainID release]; - if (taskProgressWindow) [taskProgressWindow release]; [super dealloc]; } |