aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrowanbeentje <rowan@beent.je>2009-12-08 00:02:50 +0000
committerrowanbeentje <rowan@beent.je>2009-12-08 00:02:50 +0000
commit0483d38f13410bcf5dd81f38cf7a1c801b5f7271 (patch)
tree0811dc2a2e3801d5ecea5fb2faf56959925974a4
parenta2c7f0a33464fd3558f328bc975b8f1fc3ca2dfe (diff)
downloadsequelpro-0483d38f13410bcf5dd81f38cf7a1c801b5f7271.tar.gz
sequelpro-0483d38f13410bcf5dd81f38cf7a1c801b5f7271.tar.bz2
sequelpro-0483d38f13410bcf5dd81f38cf7a1c801b5f7271.zip
- Improve TablesList item selection by splitting out interface updates to a method to be called in the main thread; should improve stability
-rw-r--r--Source/TablesList.h1
-rw-r--r--Source/TablesList.m221
2 files changed, 126 insertions, 96 deletions
diff --git a/Source/TablesList.h b/Source/TablesList.h
index 3f29011c..d7a22b53 100644
--- a/Source/TablesList.h
+++ b/Source/TablesList.h
@@ -125,6 +125,7 @@ enum sp_table_types
- (void)doPerformQueryService:(NSString *)query;
- (void)updateSelectionWithTaskString:(NSString *)taskString;
- (void)updateSelectionTask;
+- (void)setSelection:(NSDictionary *)selectionDetails;
- (void)selectTableAtIndex:(NSNumber *)row;
// Getters
diff --git a/Source/TablesList.m b/Source/TablesList.m
index de1ce991..8ca98f9a 100644
--- a/Source/TablesList.m
+++ b/Source/TablesList.m
@@ -615,6 +615,124 @@
// If there is a multiple or blank selection, clear all views directly.
if ( [tablesListView numberOfSelectedRows] != 1 || ![[filteredTables objectAtIndex:[tablesListView selectedRow]] length] ) {
+
+ // Update the selection variables and the interface
+ [self performSelectorOnMainThread:@selector(setSelection:) withObject:nil waitUntilDone:YES];
+
+ // 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];
+
+ return;
+ }
+
+ // Otherwise, set up a task
+ [tableDocumentInstance startTaskWithDescription:taskString];
+
+ // If on the main thread, fire up a thread to deal with view changes and data loading, else perform inline
+ if ([NSThread isMainThread]) {
+ [NSThread detachNewThreadSelector:@selector(updateSelectionTask) toTarget:self withObject:nil];
+ } else {
+ [self updateSelectionTask];
+ }
+}
+
+- (void) updateSelectionTask
+{
+ NSAutoreleasePool *selectionChangePool = [[NSAutoreleasePool alloc] init];
+ NSString *tableEncoding = nil;
+
+ // Update selection variables and interface
+ NSDictionary *selectionDetails = [NSDictionary dictionaryWithObjectsAndKeys:
+ [filteredTables objectAtIndex:[tablesListView selectedRow]], @"name",
+ [filteredTableTypes objectAtIndex:[tablesListView selectedRow]], @"type",
+ nil];
+ [self performSelectorOnMainThread:@selector(setSelection:) withObject:selectionDetails waitUntilDone:YES];
+
+ // Check the encoding if appropriate to determine if an encoding change and reset is required
+ if( selectedTableType == SP_TABLETYPE_VIEW || selectedTableType == SP_TABLETYPE_TABLE) {
+
+ // tableEncoding == nil indicates that there was an error while retrieving table data
+ tableEncoding = [tableDataInstance tableEncoding];
+
+ // If encoding is set to Autodetect, update the connection character set encoding
+ // based on the newly selected table's encoding - but only if it differs from the current encoding.
+ if ([[[NSUserDefaults standardUserDefaults] objectForKey:SPDefaultEncoding] isEqualToString:@"Autodetect"]) {
+ if (tableEncoding != nil && ![tableEncoding isEqualToString:[tableDocumentInstance connectionEncoding]]) {
+ [tableDocumentInstance setConnectionEncoding:tableEncoding reloadingViews:NO];
+ [tableDataInstance resetAllData];
+ tableEncoding = [tableDataInstance tableEncoding];
+ }
+ }
+ }
+
+ // Ensure status information is cached on the working thread
+ [tableDataInstance updateStatusInformationForCurrentTable];
+
+ // Notify listeners of the table change now that the state is fully set up.
+ [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:SPTableChangedNotification object:tableDocumentInstance];
+
+ if( selectedTableType == SP_TABLETYPE_VIEW || selectedTableType == SP_TABLETYPE_TABLE) {
+ if ( [tabView indexOfTabViewItem:[tabView selectedTabViewItem]] == 0 ) {
+ [tableSourceInstance loadTable:selectedTableName];
+ structureLoaded = YES;
+ contentLoaded = NO;
+ statusLoaded = NO;
+ } else if ( [tabView indexOfTabViewItem:[tabView selectedTabViewItem]] == 1 ) {
+ if(tableEncoding == nil) {
+ [tableContentInstance loadTable:nil];
+ } else {
+ [tableContentInstance loadTable:selectedTableName];
+ }
+ structureLoaded = NO;
+ contentLoaded = YES;
+ statusLoaded = NO;
+ } else if ( [tabView indexOfTabViewItem:[tabView selectedTabViewItem]] == 3 ) {
+ [extendedTableInfoInstance performSelectorOnMainThread:@selector(loadTable:) withObject:selectedTableName waitUntilDone:YES];
+ structureLoaded = NO;
+ contentLoaded = NO;
+ statusLoaded = YES;
+ } else {
+ structureLoaded = NO;
+ contentLoaded = NO;
+ statusLoaded = NO;
+ }
+ } else {
+
+ // if we are not looking at a table or view, clear these
+ [tableSourceInstance loadTable:nil];
+ [tableContentInstance loadTable:nil];
+ [extendedTableInfoInstance performSelectorOnMainThread:@selector(loadTable:) withObject:nil waitUntilDone:YES];
+ structureLoaded = NO;
+ contentLoaded = NO;
+ statusLoaded = NO;
+ }
+
+ // Update the "Show Create Syntax" window if it's already opened
+ // according to the selected table/view/proc/func
+ if([[tableDocumentInstance getCreateTableSyntaxWindow] isVisible])
+ [tableDocumentInstance performSelectorOnMainThread:@selector(showCreateTableSyntax:) withObject:self waitUntilDone:YES];
+
+ // Add a history entry
+ [spHistoryControllerInstance updateHistoryEntries];
+
+ // Empty the loading pool and exit the thread
+ [tableDocumentInstance endTask];
+ [selectionChangePool drain];
+}
+
+/**
+ * Takes a dictionary of selection details, containing the selection name
+ * and type, and updates stored variables and the table list interface to
+ * match.
+ * Should be called on the main thread.
+ */
+- (void)setSelection:(NSDictionary *)selectionDetails
+{
+ // First handle empty or multiple selections
+ if (!selectionDetails || ![selectionDetails objectForKey:@"name"]) {
NSIndexSet *indexes = [tablesListView selectedRowIndexes];
// Update the selected table name and type
@@ -628,7 +746,7 @@
[tableSourceInstance loadTable:nil];
[tableContentInstance loadTable:nil];
- [extendedTableInfoInstance performSelectorOnMainThread:@selector(loadTable:) withObject:nil waitUntilDone:YES];
+ [extendedTableInfoInstance loadTable:nil];
structureLoaded = NO;
contentLoaded = NO;
statusLoaded = NO;
@@ -697,36 +815,18 @@
// set window title
[tableWindow setTitle:[tableDocumentInstance displaySPName]];
-
- // 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];
return;
}
- // Otherwise, set up a task
- [tableDocumentInstance startTaskWithDescription:taskString];
-
- // If on the main thread, fire up a thread to deal with view changes and data loading, else perform inline
- if ([NSThread isMainThread]) {
- [NSThread detachNewThreadSelector:@selector(updateSelectionTask) toTarget:self withObject:nil];
- } else {
- [self updateSelectionTask];
- }
-}
-
-- (void) updateSelectionTask
-{
- NSAutoreleasePool *selectionChangePool = [[NSAutoreleasePool alloc] init];
- NSString *tableEncoding = nil;
+ // If a new selection has been provided, store variables and update the interface to match
+ NSString *selectedItemName = [selectionDetails objectForKey:@"name"];
+ NSInteger selectedItemType = [[selectionDetails objectForKey:@"type"] integerValue];
// Update the selected table name and type
if (selectedTableName) [selectedTableName release];
- selectedTableName = [[NSString alloc] initWithString:[filteredTables objectAtIndex:[tablesListView selectedRow]]];
- selectedTableType = [[filteredTableTypes objectAtIndex:[tablesListView selectedRow]] intValue];
+ selectedTableName = [[NSString alloc] initWithString:selectedItemName];
+ selectedTableType = selectedItemType;
// Remove the "current selection" item for filtered lists if appropriate
if (isTableListFiltered && [tablesListView selectedRow] < [filteredTables count] - 2 && [filteredTables count] > 2
@@ -737,72 +837,13 @@
[filteredTableTypes removeObjectsInRange:NSMakeRange([filteredTableTypes count]-2, 2)];
[tablesListView reloadData];
}
-
+
// Reset the table information caches
[tableDataInstance resetAllData];
- // Check the encoding if appropriate to determine if an encoding change and reset is required
- if( selectedTableType == SP_TABLETYPE_VIEW || selectedTableType == SP_TABLETYPE_TABLE) {
-
- // tableEncoding == nil indicates that there was an error while retrieving table data
- tableEncoding = [tableDataInstance tableEncoding];
-
- // If encoding is set to Autodetect, update the connection character set encoding
- // based on the newly selected table's encoding - but only if it differs from the current encoding.
- if ([[[NSUserDefaults standardUserDefaults] objectForKey:SPDefaultEncoding] isEqualToString:@"Autodetect"]) {
- if (tableEncoding != nil && ![tableEncoding isEqualToString:[tableDocumentInstance connectionEncoding]]) {
- [tableDocumentInstance setConnectionEncoding:tableEncoding reloadingViews:NO];
- [tableDataInstance resetAllData];
- tableEncoding = [tableDataInstance tableEncoding];
- }
- }
- }
-
- // Ensure status information is cached on the working thread
- [tableDataInstance updateStatusInformationForCurrentTable];
-
- // 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];
- if( selectedTableType == SP_TABLETYPE_VIEW || selectedTableType == SP_TABLETYPE_TABLE) {
- if ( [tabView indexOfTabViewItem:[tabView selectedTabViewItem]] == 0 ) {
- [tableSourceInstance loadTable:selectedTableName];
- structureLoaded = YES;
- contentLoaded = NO;
- statusLoaded = NO;
- } else if ( [tabView indexOfTabViewItem:[tabView selectedTabViewItem]] == 1 ) {
- if(tableEncoding == nil) {
- [tableContentInstance loadTable:nil];
- } else {
- [tableContentInstance loadTable:selectedTableName];
- }
- structureLoaded = NO;
- contentLoaded = YES;
- statusLoaded = NO;
- } else if ( [tabView indexOfTabViewItem:[tabView selectedTabViewItem]] == 3 ) {
- [extendedTableInfoInstance performSelectorOnMainThread:@selector(loadTable:) withObject:selectedTableName waitUntilDone:YES];
- structureLoaded = NO;
- contentLoaded = NO;
- statusLoaded = YES;
- } else {
- structureLoaded = NO;
- contentLoaded = NO;
- statusLoaded = NO;
- }
- } else {
-
- // if we are not looking at a table or view, clear these
- [tableSourceInstance loadTable:nil];
- [tableContentInstance loadTable:nil];
- [extendedTableInfoInstance performSelectorOnMainThread:@selector(loadTable:) withObject:nil waitUntilDone:YES];
- structureLoaded = NO;
- contentLoaded = NO;
- statusLoaded = NO;
- }
-
// Set gear menu items Remove/Duplicate table/view and mainMenu > Table items
// according to the table types
NSMenu *tableSubMenu = [[[NSApp mainMenu] itemWithTitle:@"Table"] submenu];
@@ -925,18 +966,6 @@
// set window title
[tableWindow setTitle:[tableDocumentInstance displaySPName]];
-
- // Update the "Show Create Syntax" window if it's already opened
- // according to the selected table/view/proc/func
- if([[tableDocumentInstance getCreateTableSyntaxWindow] isVisible])
- [tableDocumentInstance showCreateTableSyntax:self];
-
- // Add a history entry
- [spHistoryControllerInstance updateHistoryEntries];
-
- // Empty the loading pool and exit the thread
- [tableDocumentInstance endTask];
- [selectionChangePool drain];
}
#pragma mark -