aboutsummaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorrowanbeentje <rowan@beent.je>2009-11-21 22:18:27 +0000
committerrowanbeentje <rowan@beent.je>2009-11-21 22:18:27 +0000
commit7ead84b0868975752f445d1917bc693a5bf502b7 (patch)
tree8bb28e0a7b5482fc13276bc192e738d6e9761b8b /Source
parentf184235a7f7996e68f4f6548ec8932b289e3d3c1 (diff)
downloadsequelpro-7ead84b0868975752f445d1917bc693a5bf502b7.tar.gz
sequelpro-7ead84b0868975752f445d1917bc693a5bf502b7.tar.bz2
sequelpro-7ead84b0868975752f445d1917bc693a5bf502b7.zip
- Relocate the table changed notification, allowing table info pane to update early in the change process, but ensure the change notification occurs on the main thread for stability. Added NSNotificationAdditions from the Colloquy project for this.
- Change the design of the progress indicator layer, and tweak task progress for improved feedback and less flickering by correctly updating interface as appropriate, and delaying status changes for a short time. This partially addresses Issue #455.
Diffstat (limited to 'Source')
-rw-r--r--Source/NSNotificationAdditions.h34
-rw-r--r--Source/NSNotificationAdditions.m75
-rw-r--r--Source/TableContent.m3
-rw-r--r--Source/TableDocument.h2
-rw-r--r--Source/TableDocument.m18
-rw-r--r--Source/TablesList.m12
-rw-r--r--Source/YRKSpinningProgressIndicator.m1
7 files changed, 136 insertions, 9 deletions
diff --git a/Source/NSNotificationAdditions.h b/Source/NSNotificationAdditions.h
new file mode 100644
index 00000000..37fe4c0e
--- /dev/null
+++ b/Source/NSNotificationAdditions.h
@@ -0,0 +1,34 @@
+//
+// $Id$
+//
+// NSNotificationAdditions.h
+// sequel-pro
+//
+// Copied from the Colloquy project; original code available from Trac at
+// http://colloquy.info/project/browser/trunk/Additions/NSNotificationAdditions.h
+//
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// More info at <http://code.google.com/p/sequel-pro/>
+
+@interface NSNotificationCenter (NSNotificationCenterAdditions)
+- (void) postNotificationOnMainThread:(NSNotification *) notification;
+- (void) postNotificationOnMainThread:(NSNotification *) notification waitUntilDone:(BOOL) wait;
+
+- (void) postNotificationOnMainThreadWithName:(NSString *) name object:(id) object;
+- (void) postNotificationOnMainThreadWithName:(NSString *) name object:(id) object userInfo:(NSDictionary *) userInfo;
+- (void) postNotificationOnMainThreadWithName:(NSString *) name object:(id) object userInfo:(NSDictionary *) userInfo waitUntilDone:(BOOL) wait;
+@end
diff --git a/Source/NSNotificationAdditions.m b/Source/NSNotificationAdditions.m
new file mode 100644
index 00000000..2e075ed3
--- /dev/null
+++ b/Source/NSNotificationAdditions.m
@@ -0,0 +1,75 @@
+//
+// $Id$
+//
+// NSNotificationAdditions.m
+// sequel-pro
+//
+// Copied from the Colloquy project; original code available from Trac at
+// http://colloquy.info/project/browser/trunk/Additions/NSNotificationAdditions.m
+//
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// More info at <http://code.google.com/p/sequel-pro/>
+
+#import "NSNotificationAdditions.h"
+#import <pthread.h>
+
+@implementation NSNotificationCenter (NSNotificationCenterAdditions)
+- (void) postNotificationOnMainThread:(NSNotification *) notification {
+ if( pthread_main_np() ) return [self postNotification:notification];
+ [self postNotificationOnMainThread:notification waitUntilDone:NO];
+}
+
+- (void) postNotificationOnMainThread:(NSNotification *) notification waitUntilDone:(BOOL) wait {
+ if( pthread_main_np() ) return [self postNotification:notification];
+ [[self class] performSelectorOnMainThread:@selector( _postNotification: ) withObject:notification waitUntilDone:wait];
+}
+
++ (void) _postNotification:(NSNotification *) notification {
+ [[self defaultCenter] postNotification:notification];
+}
+
+- (void) postNotificationOnMainThreadWithName:(NSString *) name object:(id) object {
+ if( pthread_main_np() ) return [self postNotificationName:name object:object userInfo:nil];
+ [self postNotificationOnMainThreadWithName:name object:object userInfo:nil waitUntilDone:NO];
+}
+
+- (void) postNotificationOnMainThreadWithName:(NSString *) name object:(id) object userInfo:(NSDictionary *) userInfo {
+ if( pthread_main_np() ) return [self postNotificationName:name object:object userInfo:userInfo];
+ [self postNotificationOnMainThreadWithName:name object:object userInfo:userInfo waitUntilDone:NO];
+}
+
+- (void) postNotificationOnMainThreadWithName:(NSString *) name object:(id) object userInfo:(NSDictionary *) userInfo waitUntilDone:(BOOL) wait {
+ if( pthread_main_np() ) return [self postNotificationName:name object:object userInfo:userInfo];
+
+ NSMutableDictionary *info = [[NSMutableDictionary allocWithZone:nil] initWithCapacity:3];
+ if( name ) [info setObject:name forKey:@"name"];
+ if( object ) [info setObject:object forKey:@"object"];
+ if( userInfo ) [info setObject:userInfo forKey:@"userInfo"];
+
+ [[self class] performSelectorOnMainThread:@selector( _postNotificationName: ) withObject:info waitUntilDone:wait];
+
+ [info release];
+}
+
++ (void) _postNotificationName:(NSDictionary *) info {
+ NSString *name = [info objectForKey:@"name"];
+ id object = [info objectForKey:@"object"];
+ NSDictionary *userInfo = [info objectForKey:@"userInfo"];
+
+ [[self defaultCenter] postNotificationName:name object:object userInfo:userInfo];
+}
+@end
diff --git a/Source/TableContent.m b/Source/TableContent.m
index 60a7ce4a..bcaed509 100644
--- a/Source/TableContent.m
+++ b/Source/TableContent.m
@@ -638,7 +638,8 @@
if (rowsProcessed < targetRowCount) {
[tableDocumentInstance setTaskPercentage:(rowsProcessed*relativeTargetRowCount)];
} else if (rowsProcessed == targetRowCount) {
- [tableDocumentInstance performSelectorOnMainThread:@selector(setTaskProgressToIndeterminate) withObject:nil waitUntilDone:NO];
+ [tableDocumentInstance setTaskPercentage:100.0];
+ [tableDocumentInstance performSelectorOnMainThread:@selector(setTaskProgressToIndeterminateAfterDelay:) withObject:[NSNumber numberWithBool:YES] waitUntilDone:NO];
}
}
diff --git a/Source/TableDocument.h b/Source/TableDocument.h
index db4b48ae..8164746a 100644
--- a/Source/TableDocument.h
+++ b/Source/TableDocument.h
@@ -187,7 +187,7 @@
- (void) showTaskProgressWindow:(NSTimer *)theTimer;
- (void) setTaskDescription:(NSString *)description;
- (void) setTaskPercentage:(float)taskPercentage;
-- (void) setTaskProgressToIndeterminate;
+- (void) setTaskProgressToIndeterminateAfterDelay:(BOOL)afterDelay;
- (void) endTask;
- (void) enableTaskCancellationWithTitle:(NSString *)buttonTitle callbackObject:(id)callbackObject callbackFunction:(SEL)callbackFunction;
- (void) disableTaskCancellation;
diff --git a/Source/TableDocument.m b/Source/TableDocument.m
index 4e0f68fc..98a231ab 100644
--- a/Source/TableDocument.m
+++ b/Source/TableDocument.m
@@ -1266,7 +1266,7 @@
[[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];
+ taskDrawTimer = [[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(showTaskProgressWindow:) userInfo:nil repeats:NO] retain];
}
}
@@ -1306,6 +1306,7 @@
if (taskDisplayIsIndeterminate) {
taskDisplayIsIndeterminate = NO;
[taskProgressIndicator stopAnimation:self];
+ [taskProgressIndicator setDoubleValue:0.5];
}
taskProgressValue = taskPercentage;
@@ -1319,10 +1320,17 @@
/**
* Sets the task progress indicator back to indeterminate (also performed
- * automatically whenever a new task is started)
+ * automatically whenever a new task is started).
+ * This can optionally be called with afterDelay set, in which case the intederminate
+ * switch will be made a fter a short pause to minimise flicker for short actions.
*/
-- (void) setTaskProgressToIndeterminate
+- (void) setTaskProgressToIndeterminateAfterDelay:(BOOL)afterDelay
{
+ if (afterDelay) {
+ [self performSelector:@selector(setTaskProgressToIndeterminateAfterDelay:) withObject:nil afterDelay:0.5];
+ return;
+ }
+
if (taskDisplayIsIndeterminate) return;
taskDisplayIsIndeterminate = YES;
[taskProgressIndicator setIndeterminate:YES];
@@ -1354,9 +1362,11 @@
[taskFadeAnimator release], taskFadeAnimator = nil;
}
- // Hide the task interface
+ // Hide the task interface and reset to indeterminate
if (taskDisplayIsIndeterminate) [taskProgressIndicator stopAnimation:self];
[taskProgressWindow setAlphaValue:0.0];
+ taskDisplayIsIndeterminate = YES;
+ [taskProgressIndicator setIndeterminate:YES];
// Re-enable window interface
[historyControl setEnabled:YES];
diff --git a/Source/TablesList.m b/Source/TablesList.m
index f37be72e..eabf062f 100644
--- a/Source/TablesList.m
+++ b/Source/TablesList.m
@@ -35,6 +35,7 @@
#import "RegexKitLite.h"
#import "SPDatabaseData.h"
#import "NSMutableArray-MultipleSort.h"
+#import "NSNotificationAdditions.h"
#import "SPConstants.h"
@interface TablesList (PrivateAPI)
@@ -738,6 +739,14 @@
// Reset the table information caches
[tableDataInstance resetAllData];
+ if (selectedTableType == SP_TABLETYPE_TABLE) {
+ [tableDataInstance updateInformationForCurrentTable];
+ } else if (selectedTableType == SP_TABLETYPE_VIEW) {
+ [tableDataInstance updateInformationForCurrentView];
+ }
+
+ // Notify listeners of the table change now that the state is fully set up.
+ [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:SPTableChangedNotification object:tableDocumentInstance];
[separatorTableMenuItem setHidden:NO];
[separatorTableContextMenuItem setHidden:NO];
@@ -921,9 +930,6 @@
// Add a history entry
[spHistoryControllerInstance updateHistoryEntries];
-
- // Notify listeners of the table change now that the state is fully set up
- [[NSNotificationCenter defaultCenter] postNotificationName:SPTableChangedNotification object:tableDocumentInstance];
// Empty the loading pool and exit the thread
[tableDocumentInstance endTask];
diff --git a/Source/YRKSpinningProgressIndicator.m b/Source/YRKSpinningProgressIndicator.m
index 4d211be3..cca0a28c 100644
--- a/Source/YRKSpinningProgressIndicator.m
+++ b/Source/YRKSpinningProgressIndicator.m
@@ -192,6 +192,7 @@
- (void)startAnimation:(id)sender
{
+ if (!_isIndeterminate) return;
if (_isAnimating) return;
_isAnimating = YES;