aboutsummaryrefslogtreecommitdiffstats
path: root/Source/TableDocument.m
diff options
context:
space:
mode:
authorrowanbeentje <rowan@beent.je>2009-11-15 23:58:21 +0000
committerrowanbeentje <rowan@beent.je>2009-11-15 23:58:21 +0000
commit50a283b6d1f3ce48e3a06eceeed3a466c6259fe7 (patch)
tree98596427c436f4735ec9baee45da66248e83291c /Source/TableDocument.m
parent69a4fbc7cf11a35e5bf609cf7a16d2844559997c (diff)
downloadsequelpro-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.m70
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];
}