From 7ead84b0868975752f445d1917bc693a5bf502b7 Mon Sep 17 00:00:00 2001 From: rowanbeentje Date: Sat, 21 Nov 2009 22:18:27 +0000 Subject: - 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. --- .../English.lproj/ProgressIndicatorLayer.xib | 241 +++++++++++++-------- Source/NSNotificationAdditions.h | 34 +++ Source/NSNotificationAdditions.m | 75 +++++++ Source/TableContent.m | 3 +- Source/TableDocument.h | 2 +- Source/TableDocument.m | 18 +- Source/TablesList.m | 12 +- Source/YRKSpinningProgressIndicator.m | 1 + sequel-pro.xcodeproj/project.pbxproj | 6 + 9 files changed, 290 insertions(+), 102 deletions(-) create mode 100644 Source/NSNotificationAdditions.h create mode 100644 Source/NSNotificationAdditions.m diff --git a/Interfaces/English.lproj/ProgressIndicatorLayer.xib b/Interfaces/English.lproj/ProgressIndicatorLayer.xib index de3df433..54d32869 100644 --- a/Interfaces/English.lproj/ProgressIndicatorLayer.xib +++ b/Interfaces/English.lproj/ProgressIndicatorLayer.xib @@ -2,10 +2,10 @@ 1050 - 10B504 + 10C540 740 - 1038.2 - 437.00 + 1038.25 + 458.00 YES @@ -21,7 +21,7 @@ YES - + YES @@ -63,76 +63,125 @@ 256 YES - + - 274 - {{50, 84}, {160, 160}} + 12 + + YES + + + 256 + + YES + + + 290 + {{97, 30}, {326, 49}} + + YES + + 1 + -1 + 2 + + 3 + MAA + + + 2 + YES + + 67239424 + 4460544 + Multiline Label + + LucidaGrande-Bold + 13 + 16 + + + + 1 + MCAwIDAAA + + + 3 + MQA + + + + + {436, 90} + + 2 + + + {{0, 70}, {436, 90}} - YES - - 1 - -1 - 1 - + 2 + {0, 0} + + 67239424 + 0 + Box + + LucidaGrande + 11 + 3100 + + + 6 + System + textBackgroundColor + + + 3 - MAA + MCAwLjgwMDAwMDAxMTkAA - 2 - YRKSpinningProgressIndicator + + 0 + 4 + 0 + NO + 9 + + 3 + MC4yNTQwMzIyNTgxIDAuOAA + - + - 290 - {{13, 34}, {234, 42}} + 274 + {{13, 79}, {73, 73}} YES 1 -1 - 2 + 1 2 - YES - - 67239424 - 138678272 - Multiline Label - - LucidaGrande-Bold - 13 - 16 - - - - 1 - MCAwIDAAA - - - 3 - MQA - - + YRKSpinningProgressIndicator 290 - {{64, 4}, {132, 28}} + {{295, 72}, {132, 28}} + 2 YES 67239424 134348800 Cancel - - LucidaGrande - 11 - 3100 - + - -2038284033 + -2034876161 268435585 + . 200 @@ -140,24 +189,21 @@ - {260, 260} + {437, 160} + 2 - {260, 260} + {{0, -70}, {437, 160}} + 2 {0, 0} 67239424 0 Box - - 6 - System - textBackgroundColor - - + 3 MCAwLjgwMDAwMDAxMTkAA @@ -168,15 +214,16 @@ 4 0 NO + YES 15 3 - MCAwLjUAA + MCAwLjcAA - {260, 260} + {437, 90} 2 NSView @@ -267,31 +314,17 @@ YES - - + + - - 15 - - - YES - - - - 11 - - 16 - - - 17 @@ -306,6 +339,29 @@ + + 38 + + + YES + + + + + + 15 + + + YES + + + + + + 16 + + + @@ -333,6 +389,10 @@ 16.IBPluginDependency 17.IBPluginDependency 18.IBPluginDependency + 38.IBPluginDependency + 38.IBViewIntegration.shadowBlurRadius + 38.IBViewIntegration.shadowOffsetHeight + 38.IBViewIntegration.shadowOffsetWidth YES @@ -346,7 +406,7 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - {{393, 332}, {260, 260}} + {{393, 502}, {437, 90}} com.apple.InterfaceBuilder.CocoaPlugin {628, 654} {{357, 416}, {480, 272}} @@ -363,6 +423,10 @@ com.apple.InterfaceBuilder.CocoaPlugin com.brandonwalkin.BWToolkit com.brandonwalkin.BWToolkit + com.apple.InterfaceBuilder.CocoaPlugin + + + @@ -381,7 +445,7 @@ - 37 + 38 @@ -552,6 +616,13 @@ Source/SPUserManager.h + + TableDocument + + IBProjectSource + Source/SPConnectionDelegate.h + + TableDocument NSDocument @@ -572,11 +643,8 @@ closePanelSheet: closePasswordSheet: closeSheet: - copy: copyCreateTableSyntax: copyCreateTableSyntaxFromSheet: - copyServerVariableName: - copyServerVariableValue: export: exportMultipleTables: exportTable: @@ -589,12 +657,12 @@ repairTable: saveConnectionSheet: saveCreateSyntax: - saveServerVariables: setDatabases: showCreateTableSyntax: showMySQLHelp: + showServerProcesses: + showServerVariables: showUserManager: - showVariables: validateSaveConnectionAccessory: viewContent: viewQuery: @@ -643,9 +711,6 @@ id id id - id - id - id @@ -685,7 +750,6 @@ saveConnectionIncludeQuery saveConnectionSavePassword saveConnectionSavePasswordAlert - saveVariablesButton sidebarGrabber spHistoryControllerInstance tableContentInstance @@ -708,10 +772,6 @@ titleImageView titleStringView userManagerInstance - variablesCountTextField - variablesSearchField - variablesSheet - variablesTableView YES @@ -748,7 +808,6 @@ id id id - NSButton id id id @@ -771,10 +830,6 @@ id id SPUserManager - NSTextField - NSSearchField - id - id 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 + +@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 + +#import "NSNotificationAdditions.h" +#import + +@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; diff --git a/sequel-pro.xcodeproj/project.pbxproj b/sequel-pro.xcodeproj/project.pbxproj index c8a884d3..73980982 100644 --- a/sequel-pro.xcodeproj/project.pbxproj +++ b/sequel-pro.xcodeproj/project.pbxproj @@ -166,6 +166,7 @@ 589235321020C1230011DE00 /* SPHistoryController.m in Sources */ = {isa = PBXBuildFile; fileRef = 589235301020C1230011DE00 /* SPHistoryController.m */; }; 58BC5E56103898140058C2E6 /* MCPStreamingResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 583B779710386B0200B21F7E /* MCPStreamingResult.h */; settings = {ATTRIBUTES = (Public, ); }; }; 58BC5E571038983E0058C2E6 /* MCPResultPlus.h in Headers */ = {isa = PBXBuildFile; fileRef = 17B7B5D1101603B200F057DE /* MCPResultPlus.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 58C34F5310B86CAE00D37E14 /* NSNotificationAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 58C34F5210B86CAE00D37E14 /* NSNotificationAdditions.m */; }; 58C56EF50F438E120035701E /* SPDataCellFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 58C56EF40F438E120035701E /* SPDataCellFormatter.m */; }; 58CB20ED0F79A75D005EA204 /* button_edit_mode_selected.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 58CB20EC0F79A75D005EA204 /* button_edit_mode_selected.tiff */; }; 58CDB3300FCE138D00F8ACA3 /* SPSSHTunnel.m in Sources */ = {isa = PBXBuildFile; fileRef = 58CDB32F0FCE138D00F8ACA3 /* SPSSHTunnel.m */; }; @@ -569,6 +570,8 @@ 588B2CC70FE5641E00EC5FC0 /* ssh-disconnected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "ssh-disconnected.png"; sourceTree = ""; }; 589235301020C1230011DE00 /* SPHistoryController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPHistoryController.m; sourceTree = ""; }; 589235311020C1230011DE00 /* SPHistoryController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPHistoryController.h; sourceTree = ""; }; + 58C34F5110B86CAE00D37E14 /* NSNotificationAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSNotificationAdditions.h; sourceTree = ""; }; + 58C34F5210B86CAE00D37E14 /* NSNotificationAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSNotificationAdditions.m; sourceTree = ""; }; 58C56EF30F438E120035701E /* SPDataCellFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPDataCellFormatter.h; sourceTree = ""; }; 58C56EF40F438E120035701E /* SPDataCellFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPDataCellFormatter.m; sourceTree = ""; }; 58CB20EC0F79A75D005EA204 /* button_edit_mode_selected.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = button_edit_mode_selected.tiff; sourceTree = ""; }; @@ -1414,6 +1417,8 @@ B52460D40F8EF92300171639 /* SPArrayAdditions.m */, 5841929F101E57BB0089807F /* NSMutableArray-MultipleSort.h */, 584192A0101E57BB0089807F /* NSMutableArray-MultipleSort.m */, + 58C34F5110B86CAE00D37E14 /* NSNotificationAdditions.h */, + 58C34F5210B86CAE00D37E14 /* NSNotificationAdditions.m */, 1789343A0F30C1DD0097539A /* SPStringAdditions.h */, 1789343B0F30C1DD0097539A /* SPStringAdditions.m */, B52460D50F8EF92300171639 /* SPTextViewAdditions.h */, @@ -1860,6 +1865,7 @@ 1792C13710AD75C800ABE758 /* SPServerVariablesController.m in Sources */, 1792C26110AE1A2D00ABE758 /* SPConnectionDelegate.m in Sources */, 17CC97F310B4ABE90034CD7A /* SPAboutController.m in Sources */, + 58C34F5310B86CAE00D37E14 /* NSNotificationAdditions.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; -- cgit v1.2.3