aboutsummaryrefslogtreecommitdiffstats
path: root/Source/TableDocument.m
diff options
context:
space:
mode:
Diffstat (limited to 'Source/TableDocument.m')
-rw-r--r--Source/TableDocument.m113
1 files changed, 84 insertions, 29 deletions
diff --git a/Source/TableDocument.m b/Source/TableDocument.m
index 211c37c0..d17ee1e2 100644
--- a/Source/TableDocument.m
+++ b/Source/TableDocument.m
@@ -75,7 +75,8 @@
_mainNibLoaded = NO;
_encoding = [[NSString alloc] initWithString:@"utf8"];
_isConnected = NO;
- _isWorking = NO;
+ _isWorkingLevel = 0;
+ databaseListIsSelectable = YES;
_queryMode = SP_QUERYMODE_INTERFACE;
chooseDatabaseButton = nil;
chooseDatabaseToolbarItem = nil;
@@ -902,8 +903,8 @@
}
/**
- * selects the database choosen by the user
- * errorsheet if connection failed
+ * Selects the database choosen by the user, using a child task if necessary,
+ * and displaying errors in an alert sheet on failure.
*/
- (IBAction)chooseDatabase:(id)sender
{
@@ -919,6 +920,21 @@
return;
}
+ // Lock editability again if performing a task
+ if (_isWorkingLevel) databaseListIsSelectable = NO;
+
+ // Start a task
+ [self startTaskWithDescription:[NSString stringWithFormat:NSLocalizedString(@"Loading database '%@'...", @"Loading database task string"), [chooseDatabaseButton titleOfSelectedItem]]];
+ if ([NSThread isMainThread]) {
+ [NSThread detachNewThreadSelector:@selector(chooseDatabaseTask) toTarget:self withObject:nil];
+ } else {
+ [self chooseDatabaseTask];
+ }
+}
+- (void)chooseDatabaseTask
+{
+ NSAutoreleasePool *taskPool = [[NSAutoreleasePool alloc] init];
+
// Save existing scroll position and details, and ensure no duplicate entries are created as table list changes
BOOL historyStateChanging = [spHistoryControllerInstance modifyingHistoryState];
if (!historyStateChanging) {
@@ -932,6 +948,8 @@
NSBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil, nil, nil, [NSString stringWithFormat:NSLocalizedString(@"Unable to connect to database %@.\nBe sure that you have the necessary privileges.", @"message of panel when connection to db failed after selecting from popupbutton"), [chooseDatabaseButton titleOfSelectedItem]]);
[self setDatabases:self];
}
+ [self endTask];
+ [taskPool drain];
return;
}
@@ -956,6 +974,8 @@
else
[tableWindow makeFirstResponder:[tablesListInstance valueForKeyPath:@"tablesListView"]];
+ [self endTask];
+ [taskPool drain];
}
/**
@@ -1148,21 +1168,30 @@
- (void) startTaskWithDescription:(NSString *)description
{
- // Set flags and prevent further UI interaction in this window
- _isWorking = YES;
- [historyControl setEnabled:NO];
- [[NSNotificationCenter defaultCenter] postNotificationName:SPDocumentTaskStartNotification object:self];
+ // Increment the working level and set the task text
+ _isWorkingLevel++;
+ [taskDescriptionText setStringValue:description];
- // Reset the progress indicator
- taskDisplayIsIndeterminate = YES;
- [taskProgressIndicator setIndeterminate:YES];
- [taskProgressIndicator animate:self];
- [taskProgressIndicator startAnimation:self];
- taskDisplayLastValue = 0;
+ // Reset the progress indicator if necessary
+ if (_isWorkingLevel == 1 || !taskDisplayIsIndeterminate) {
+ taskDisplayIsIndeterminate = YES;
+ [taskProgressIndicator setIndeterminate:YES];
+ [taskProgressIndicator animate:self];
+ [taskProgressIndicator startAnimation:self];
+ taskDisplayLastValue = 0;
+ }
- // Set the descriptive label and schedule appearance in the near future
- [taskDescriptionText setStringValue:description];
- taskDrawTimer = [[NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(showTaskProgressLayer:) userInfo:nil repeats:NO] retain];
+ // If the working level just moved to start a task, set up the interface
+ if (_isWorkingLevel == 1) {
+
+ // Set flags and prevent further UI interaction in this window
+ [historyControl setEnabled:NO];
+ databaseListIsSelectable = NO;
+ [[NSNotificationCenter defaultCenter] postNotificationName:SPDocumentTaskStartNotification object:self];
+
+ // Set the descriptive label and schedule appearance in the near future
+ taskDrawTimer = [[NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(showTaskProgressLayer:) userInfo:nil repeats:NO] retain];
+ }
}
/**
@@ -1189,6 +1218,11 @@
*/
- (void) setTaskPercentage:(float)taskPercentage
{
+ if (taskDisplayIsIndeterminate) {
+ taskDisplayIsIndeterminate = NO;
+ [taskProgressIndicator stopAnimation:self];
+ }
+
taskProgressValue = taskPercentage;
if (taskProgressValue > taskDisplayLastValue + taskProgressValueDisplayInterval
|| taskProgressValue < taskDisplayLastValue - taskProgressValueDisplayInterval)
@@ -1217,17 +1251,25 @@
- (void) endTask
{
- // Cancel the draw timer if it exists
- if (taskDrawTimer) [taskDrawTimer invalidate], [taskDrawTimer release], taskDrawTimer = nil;
+ // Decrement the working level
+ _isWorkingLevel--;
- // Hide the task interface
- if (taskDisplayIsIndeterminate) [taskProgressIndicator stopAnimation:self];
- [taskProgressLayer setHidden:YES];
+ // If all tasks have ended, re-enable the interface
+ if (!_isWorkingLevel) {
+
+ // Cancel the draw timer if it exists
+ if (taskDrawTimer) [taskDrawTimer invalidate], [taskDrawTimer release], taskDrawTimer = nil;
- // Re-enable window interface
- _isWorking = NO;
- [historyControl setEnabled:YES];
- [[NSNotificationCenter defaultCenter] postNotificationName:SPDocumentTaskEndNotification object:self];
+ // Hide the task interface
+ if (taskDisplayIsIndeterminate) [taskProgressIndicator stopAnimation:self];
+ [taskProgressLayer setHidden:YES];
+
+ // Re-enable window interface
+ [historyControl setEnabled:YES];
+ databaseListIsSelectable = YES;
+ [[NSNotificationCenter defaultCenter] postNotificationName:SPDocumentTaskEndNotification object:self];
+ [mainToolbar validateVisibleItems];
+ }
}
/**
@@ -1236,7 +1278,15 @@
*/
- (BOOL) isWorking
{
- return _isWorking;
+ return (_isWorkingLevel > 0);
+}
+
+/**
+ * Set whether the database list is selectable or not during the task process.
+ */
+- (void) setDatabaseListIsSelectable:(BOOL)isSelectable
+{
+ databaseListIsSelectable = isSelectable;
}
#pragma mark -
@@ -2700,7 +2750,12 @@
*/
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem
{
- if (!_isConnected || _isWorking) {
+
+ if ([menuItem menu] == chooseDatabaseButton) {
+ return (_isConnected && databaseListIsSelectable);
+ }
+
+ if (!_isConnected || _isWorkingLevel) {
return ([menuItem action] == @selector(newDocument:) || [menuItem action] == @selector(terminate:));
}
@@ -3205,7 +3260,7 @@
*/
- (BOOL)validateToolbarItem:(NSToolbarItem *)toolbarItem;
{
- if (!_isConnected || _isWorking) return NO;
+ if (!_isConnected || _isWorkingLevel) return NO;
NSString *identifier = [toolbarItem itemIdentifier];
@@ -3302,7 +3357,7 @@
*/
- (BOOL)windowShouldClose:(id)sender
{
- if (_isWorking) {
+ if (_isWorkingLevel) {
return NO;
} else if ( ![tablesListInstance selectionShouldChangeInTableView:nil] ) {
return NO;