diff options
author | rowanbeentje <rowan@beent.je> | 2010-11-03 01:42:32 +0000 |
---|---|---|
committer | rowanbeentje <rowan@beent.je> | 2010-11-03 01:42:32 +0000 |
commit | 6d5927b835706d28ee8ec24254d7b5c19bf6e5fe (patch) | |
tree | ab9d3c93221afd14c0d1634a72437fb152ed129f /Source | |
parent | e3b2ea1aa4b868db760d465e2a4319f86c475131 (diff) | |
download | sequelpro-6d5927b835706d28ee8ec24254d7b5c19bf6e5fe.tar.gz sequelpro-6d5927b835706d28ee8ec24254d7b5c19bf6e5fe.tar.bz2 sequelpro-6d5927b835706d28ee8ec24254d7b5c19bf6e5fe.zip |
Add a new category to SPDatabaseDocument, allowing code cleanup and moving central functionality out of SPTablesList:
- Centralise control over table loading, moving it away from SPTablesList and into SPDatabaseDocument and the new SPDatabaseViewController category
- Centralise control over the main tab view, moving control away from SPTablesList and into SPDatabaseDocument and the new SPDatabaseViewController category
- Simplify and clean up view loading logic
- Improve thread safety
- Update localisable strings
Diffstat (limited to 'Source')
-rw-r--r-- | Source/SPConnectionController.m | 2 | ||||
-rw-r--r-- | Source/SPDataImport.m | 6 | ||||
-rw-r--r-- | Source/SPDatabaseDocument.h | 18 | ||||
-rw-r--r-- | Source/SPDatabaseDocument.m | 157 | ||||
-rw-r--r-- | Source/SPDatabaseViewController.h | 53 | ||||
-rw-r--r-- | Source/SPDatabaseViewController.m | 485 | ||||
-rw-r--r-- | Source/SPExtendedTableInfo.m | 2 | ||||
-rw-r--r-- | Source/SPHistoryController.m | 2 | ||||
-rw-r--r-- | Source/SPIndexesController.m | 4 | ||||
-rw-r--r-- | Source/SPTableContent.m | 8 | ||||
-rw-r--r-- | Source/SPTableStructure.m | 14 | ||||
-rw-r--r-- | Source/SPTableStructureDelegate.m | 4 | ||||
-rw-r--r-- | Source/SPTablesList.h | 11 | ||||
-rw-r--r-- | Source/SPTablesList.m | 343 | ||||
-rw-r--r-- | Source/SPWindowController.m | 2 |
15 files changed, 616 insertions, 495 deletions
diff --git a/Source/SPConnectionController.m b/Source/SPConnectionController.m index 241a6e1d..1128b822 100644 --- a/Source/SPConnectionController.m +++ b/Source/SPConnectionController.m @@ -84,7 +84,7 @@ { if (self = [super init]) { tableDocument = theTableDocument; - databaseConnectionSuperview = [tableDocument parentView]; + databaseConnectionSuperview = [tableDocument databaseView]; databaseConnectionView = [tableDocument valueForKey:@"contentViewSplitter"]; connectionKeychainItemName = nil; connectionKeychainItemAccount = nil; diff --git a/Source/SPDataImport.m b/Source/SPDataImport.m index f7f3eb4c..dff20466 100644 --- a/Source/SPDataImport.m +++ b/Source/SPDataImport.m @@ -1120,11 +1120,7 @@ // If import was done into a new table or the table selected for import is also selected in the content view, // update the content view - on the main thread to avoid crashes. if ([tablesListInstance tableName] && [selectedTableTarget isEqualToString:[tablesListInstance tableName]]) { - if ([[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:SPMainToolbarTableContent]) { - [tableContentInstance performSelectorOnMainThread:@selector(reloadTable:) withObject:nil waitUntilDone:YES]; - } else { - [tablesListInstance setContentRequiresReload:YES]; - } + [tableDocumentInstance setContentRequiresReload:YES]; } } diff --git a/Source/SPDatabaseDocument.h b/Source/SPDatabaseDocument.h index f01abe63..35681506 100644 --- a/Source/SPDatabaseDocument.h +++ b/Source/SPDatabaseDocument.h @@ -139,6 +139,16 @@ MCPConnection *mySQLConnection; + NSInteger currentTabIndex; + + NSString *selectedTableName; + NSInteger selectedTableType; + + BOOL structureLoaded; + BOOL contentLoaded; + BOOL statusLoaded; + BOOL triggersLoaded; + NSString *selectedDatabase; NSString *mySQLVersion; NSUserDefaults *prefs; @@ -292,11 +302,9 @@ - (IBAction)toggleNavigator:(id)sender; // Accessor methods -- (NSView *)parentView; - (NSString *)host; - (NSString *)name; - (NSString *)database; -- (NSString *)table; - (NSString *)port; - (NSString *)mySQLVersion; - (NSString *)user; @@ -315,12 +323,6 @@ - (IBAction)saveConnectionSheet:(id)sender; - (IBAction)import:(id)sender; - (IBAction)importFromClipboard:(id)sender; -- (IBAction)viewStructure:(id)sender; -- (IBAction)viewContent:(id)sender; -- (IBAction)viewQuery:(id)sender; -- (IBAction)viewStatus:(id)sender; -- (IBAction)viewRelations:(id)sender; -- (IBAction)viewTriggers:(id)sender; - (IBAction)addConnectionToFavorites:(id)sender; - (BOOL)isCustomQuerySelected; diff --git a/Source/SPDatabaseDocument.m b/Source/SPDatabaseDocument.m index beb8ab5a..75a16e73 100644 --- a/Source/SPDatabaseDocument.m +++ b/Source/SPDatabaseDocument.m @@ -87,6 +87,15 @@ chooseDatabaseButton = nil; chooseDatabaseToolbarItem = nil; connectionController = nil; + + selectedTableName = nil; + selectedTableType = SPTableTypeNone; + + structureLoaded = NO; + contentLoaded = NO; + statusLoaded = NO; + triggersLoaded = NO; + selectedDatabase = nil; mySQLConnection = nil; mySQLVersion = nil; @@ -1218,12 +1227,12 @@ if (selectedDatabase) [selectedDatabase release], selectedDatabase = nil; selectedDatabase = [[NSString alloc] initWithString:dbName]; [chooseDatabaseButton selectItemWithTitle:selectedDatabase]; - [self updateWindowTitle:self]; + [[self onMainThread] updateWindowTitle:self]; } } else { if (selectedDatabase) [selectedDatabase release], selectedDatabase = nil; [chooseDatabaseButton selectItemAtIndex:0]; - [self updateWindowTitle:self]; + [[self onMainThread] updateWindowTitle:self]; } } @@ -1634,19 +1643,19 @@ // Update the selected menu item if (useLatin1Transport) { - [self updateEncodingMenuWithSelectedEncoding:[self encodingTagFromMySQLEncoding:[NSString stringWithFormat:@"%@-", mysqlEncoding]]]; + [[self onMainThread] updateEncodingMenuWithSelectedEncoding:[self encodingTagFromMySQLEncoding:[NSString stringWithFormat:@"%@-", mysqlEncoding]]]; } else { - [self updateEncodingMenuWithSelectedEncoding:[self encodingTagFromMySQLEncoding:mysqlEncoding]]; + [[self onMainThread] updateEncodingMenuWithSelectedEncoding:[self encodingTagFromMySQLEncoding:mysqlEncoding]]; } // Update the stored connection encoding to prevent switches [mySQLConnection storeEncodingForRestoration]; - // Reload stuff as appropriate + // Reload views as appropriate if (reloadViews) { - if ([tablesListInstance structureLoaded]) [tableSourceInstance reloadTable:self]; - if ([tablesListInstance contentLoaded]) [tableContentInstance reloadTable:self]; - if ([tablesListInstance statusLoaded]) [extendedTableInfoInstance reloadTable:self]; + [self setStructureRequiresReload:YES]; + [self setContentRequiresReload:YES]; + [self setStatusRequiresReload:YES]; } } @@ -2617,16 +2626,6 @@ #pragma mark - #pragma mark Accessor methods - -/** - * Returns the parent view, which in its turn contains the database view for this - * connection. - */ -- (NSView *)parentView -{ - return parentView; -} - /** * Returns the host */ @@ -2734,14 +2733,6 @@ } /** - * Returns the currently selected table (passing the request to SPTablesList) - */ -- (NSString *)table -{ - return [tablesListInstance tableName]; -} - -/** * Returns the MySQL version */ - (NSString *)mySQLVersion @@ -3711,113 +3702,6 @@ return YES; } -- (IBAction)viewStructure:(id)sender -{ - // Cancel the selection if currently editing a view and unable to save - if (![self couldCommitCurrentViewActions]) { - [mainToolbar setSelectedItemIdentifier:*SPViewModeToMainToolbarMap[[prefs integerForKey:SPLastViewMode]]]; - return; - } - - [tableTabView selectTabViewItemAtIndex:0]; - [mainToolbar setSelectedItemIdentifier:SPMainToolbarTableStructure]; - [spHistoryControllerInstance updateHistoryEntries]; - - [prefs setInteger:SPStructureViewMode forKey:SPLastViewMode]; -} - -- (IBAction)viewContent:(id)sender -{ - - // Cancel the selection if currently editing a view and unable to save - if (![self couldCommitCurrentViewActions]) { - [mainToolbar setSelectedItemIdentifier:*SPViewModeToMainToolbarMap[[prefs integerForKey:SPLastViewMode]]]; - return; - } - - [tableTabView selectTabViewItemAtIndex:1]; - [mainToolbar setSelectedItemIdentifier:SPMainToolbarTableContent]; - [spHistoryControllerInstance updateHistoryEntries]; - - [prefs setInteger:SPContentViewMode forKey:SPLastViewMode]; -} - -- (IBAction)viewQuery:(id)sender -{ - - // Cancel the selection if currently editing a view and unable to save - if (![self couldCommitCurrentViewActions]) { - [mainToolbar setSelectedItemIdentifier:*SPViewModeToMainToolbarMap[[prefs integerForKey:SPLastViewMode]]]; - return; - } - - [tableTabView selectTabViewItemAtIndex:2]; - [mainToolbar setSelectedItemIdentifier:SPMainToolbarCustomQuery]; - [spHistoryControllerInstance updateHistoryEntries]; - - // Set the focus on the text field - [parentWindow makeFirstResponder:customQueryTextView]; - - [prefs setInteger:SPQueryEditorViewMode forKey:SPLastViewMode]; -} - -- (IBAction)viewStatus:(id)sender -{ - - // Cancel the selection if currently editing a view and unable to save - if (![self couldCommitCurrentViewActions]) { - [mainToolbar setSelectedItemIdentifier:*SPViewModeToMainToolbarMap[[prefs integerForKey:SPLastViewMode]]]; - return; - } - - [tableTabView selectTabViewItemAtIndex:3]; - [mainToolbar setSelectedItemIdentifier:SPMainToolbarTableInfo]; - [spHistoryControllerInstance updateHistoryEntries]; - - // Refresh data - if([self table] && [[self table] length]) { - [tableDataInstance resetAllData]; - [extendedTableInfoInstance loadTable:[self table]]; - } - - [parentWindow makeFirstResponder:[extendedTableInfoInstance valueForKeyPath:@"tableCreateSyntaxTextView"]]; - - [prefs setInteger:SPTableInfoViewMode forKey:SPLastViewMode]; -} - -- (IBAction)viewRelations:(id)sender -{ - - // Cancel the selection if currently editing a view and unable to save - if (![self couldCommitCurrentViewActions]) { - [mainToolbar setSelectedItemIdentifier:*SPViewModeToMainToolbarMap[[prefs integerForKey:SPLastViewMode]]]; - return; - } - - [tableTabView selectTabViewItemAtIndex:4]; - [mainToolbar setSelectedItemIdentifier:SPMainToolbarTableRelations]; - [spHistoryControllerInstance updateHistoryEntries]; - - [prefs setInteger:SPRelationsViewMode forKey:SPLastViewMode]; -} - -- (IBAction)viewTriggers:(id)sender -{ - - // Cancel the selection if currently editing a view and unable to save - if (![self couldCommitCurrentViewActions]) { - [mainToolbar setSelectedItemIdentifier:*SPViewModeToMainToolbarMap[[prefs integerForKey:SPLastViewMode]]]; - return; - } - - [tableTabView selectTabViewItemAtIndex:5]; - [mainToolbar setSelectedItemIdentifier:SPMainToolbarTableTriggers]; - [spHistoryControllerInstance updateHistoryEntries]; - - [prefs setInteger:SPTriggersViewMode forKey:SPLastViewMode]; -} - - /** * Adds the current database connection details to the user's favorites if it doesn't already exist. */ @@ -4491,7 +4375,7 @@ - (void)connectionControllerConnectAttemptFailed:(id)controller { // Reset the window title - [self updateWindowTitle:self]; + [[self onMainThread] updateWindowTitle:self]; } #pragma mark - @@ -4721,6 +4605,7 @@ [printWebView release]; [taskProgressWindow close]; + if (selectedTableName) [selectedTableName release]; if (connectionController) [connectionController release]; if (processListController) [processListController release]; if (serverVariablesController) [serverVariablesController release]; @@ -4854,7 +4739,7 @@ [tablesListInstance setConnection:mySQLConnection]; [tableDumpInstance setConnection:mySQLConnection]; - [self updateWindowTitle:self]; + [[self onMainThread] updateWindowTitle:self]; } /** @@ -4893,7 +4778,7 @@ [tablesListInstance setConnection:mySQLConnection]; [tableDumpInstance setConnection:mySQLConnection]; - [self updateWindowTitle:self]; + [[self onMainThread] updateWindowTitle:self]; } /** diff --git a/Source/SPDatabaseViewController.h b/Source/SPDatabaseViewController.h new file mode 100644 index 00000000..14dd5e88 --- /dev/null +++ b/Source/SPDatabaseViewController.h @@ -0,0 +1,53 @@ +// +// $Id$ +// +// SPDatabaseViewController.h +// sequel-pro +// +// Created by Rowan Beentje on 31/10/2010. +// Copyright 2010 Arboreal. All rights reserved. +// +// 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 "SPDatabaseDocument.h" + + +@interface SPDatabaseDocument (SPDatabaseViewController) + +// Getters +- (NSView *)parentView; +- (NSString *)table; +- (NSInteger)tableType; +- (BOOL)structureLoaded; +- (BOOL)contentLoaded; +- (BOOL)statusLoaded; + +// Tab view control +- (IBAction)viewStructure:(id)sender; +- (IBAction)viewContent:(id)sender; +- (IBAction)viewQuery:(id)sender; +- (IBAction)viewStatus:(id)sender; +- (IBAction)viewRelations:(id)sender; +- (IBAction)viewTriggers:(id)sender; +- (void)setStructureRequiresReload:(BOOL)reload; +- (void)setContentRequiresReload:(BOOL)reload; +- (void)setStatusRequiresReload:(BOOL)reload; + +// Table control +- (void)loadTable:(NSString *)aTable ofType:(NSInteger)aTableType; + +@end diff --git a/Source/SPDatabaseViewController.m b/Source/SPDatabaseViewController.m new file mode 100644 index 00000000..cb5b5bb2 --- /dev/null +++ b/Source/SPDatabaseViewController.m @@ -0,0 +1,485 @@ +// +// $Id$ +// +// SPDatabaseViewController.m +// sequel-pro +// +// Created by Rowan Beentje on 31/10/2010. +// Copyright 2010 Arboreal. All rights reserved. +// +// 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 "SPDatabaseViewController.h" +#import "SPTableData.h" + +@interface SPDatabaseDocument (SPDatabaseViewControllerPrivateAPI) + +- (void)_loadTabTask:(NSTabViewItem *)tabViewItem; +- (void)_loadTableTask; + +@end + + +@implementation SPDatabaseDocument (SPDatabaseViewController) + +#pragma mark - +#pragma mark Getters + +/** + * Returns the master database view, containing the tables list and views for + * table setup and contents. + */ +- (NSView *)databaseView +{ + return parentView; +} + +/** + * Returns the name of the currently selected table/view/procedure/function. + */ +- (NSString *)table +{ + return selectedTableName; +} + +/** + * Returns the currently selected table type, or -1 if no table or multiple tables are selected + */ +- (NSInteger)tableType +{ + return selectedTableType; +} + +/** + * Returns YES if table source has already been loaded + */ +- (BOOL)structureLoaded +{ + return structureLoaded; +} + +/** + * Returns YES if table content has already been loaded + */ +- (BOOL)contentLoaded +{ + return contentLoaded; +} + +/** + * Returns YES if table status has already been loaded + */ +- (BOOL)statusLoaded +{ + return statusLoaded; +} + + +#pragma mark - +#pragma mark Tab view control and delegate methods + +- (IBAction)viewStructure:(id)sender +{ + // Cancel the selection if currently editing a view and unable to save + if (![self couldCommitCurrentViewActions]) { + [mainToolbar setSelectedItemIdentifier:*SPViewModeToMainToolbarMap[[prefs integerForKey:SPLastViewMode]]]; + return; + } + + [tableTabView selectTabViewItemAtIndex:0]; + [mainToolbar setSelectedItemIdentifier:SPMainToolbarTableStructure]; + [spHistoryControllerInstance updateHistoryEntries]; + + [prefs setInteger:SPStructureViewMode forKey:SPLastViewMode]; +} + +- (IBAction)viewContent:(id)sender +{ + + // Cancel the selection if currently editing a view and unable to save + if (![self couldCommitCurrentViewActions]) { + [mainToolbar setSelectedItemIdentifier:*SPViewModeToMainToolbarMap[[prefs integerForKey:SPLastViewMode]]]; + return; + } + + [tableTabView selectTabViewItemAtIndex:1]; + [mainToolbar setSelectedItemIdentifier:SPMainToolbarTableContent]; + [spHistoryControllerInstance updateHistoryEntries]; + + [prefs setInteger:SPContentViewMode forKey:SPLastViewMode]; +} + +- (IBAction)viewQuery:(id)sender +{ + + // Cancel the selection if currently editing a view and unable to save + if (![self couldCommitCurrentViewActions]) { + [mainToolbar setSelectedItemIdentifier:*SPViewModeToMainToolbarMap[[prefs integerForKey:SPLastViewMode]]]; + return; + } + + [tableTabView selectTabViewItemAtIndex:2]; + [mainToolbar setSelectedItemIdentifier:SPMainToolbarCustomQuery]; + [spHistoryControllerInstance updateHistoryEntries]; + + // Set the focus on the text field + [parentWindow makeFirstResponder:customQueryTextView]; + + [prefs setInteger:SPQueryEditorViewMode forKey:SPLastViewMode]; +} + +- (IBAction)viewStatus:(id)sender +{ + + // Cancel the selection if currently editing a view and unable to save + if (![self couldCommitCurrentViewActions]) { + [mainToolbar setSelectedItemIdentifier:*SPViewModeToMainToolbarMap[[prefs integerForKey:SPLastViewMode]]]; + return; + } + + [tableTabView selectTabViewItemAtIndex:3]; + [mainToolbar setSelectedItemIdentifier:SPMainToolbarTableInfo]; + [spHistoryControllerInstance updateHistoryEntries]; + + // Refresh data + if([self table] && [[self table] length]) { + [tableDataInstance resetAllData]; + [extendedTableInfoInstance loadTable:[self table]]; + } + + [parentWindow makeFirstResponder:[extendedTableInfoInstance valueForKeyPath:@"tableCreateSyntaxTextView"]]; + + [prefs setInteger:SPTableInfoViewMode forKey:SPLastViewMode]; +} + +- (IBAction)viewRelations:(id)sender +{ + + // Cancel the selection if currently editing a view and unable to save + if (![self couldCommitCurrentViewActions]) { + [mainToolbar setSelectedItemIdentifier:*SPViewModeToMainToolbarMap[[prefs integerForKey:SPLastViewMode]]]; + return; + } + + [tableTabView selectTabViewItemAtIndex:4]; + [mainToolbar setSelectedItemIdentifier:SPMainToolbarTableRelations]; + [spHistoryControllerInstance updateHistoryEntries]; + + [prefs setInteger:SPRelationsViewMode forKey:SPLastViewMode]; +} + +- (IBAction)viewTriggers:(id)sender +{ + + // Cancel the selection if currently editing a view and unable to save + if (![self couldCommitCurrentViewActions]) { + [mainToolbar setSelectedItemIdentifier:*SPViewModeToMainToolbarMap[[prefs integerForKey:SPLastViewMode]]]; + return; + } + + [tableTabView selectTabViewItemAtIndex:5]; + [mainToolbar setSelectedItemIdentifier:SPMainToolbarTableTriggers]; + [spHistoryControllerInstance updateHistoryEntries]; + + [prefs setInteger:SPTriggersViewMode forKey:SPLastViewMode]; +} + +/** + * Mark the structure tab for refresh when it's next switched to, + * or reload the view if it's currently active + */ +- (void)setStructureRequiresReload:(BOOL)reload +{ + if (reload && selectedTableName && [tableTabView indexOfTabViewItem:[tableTabView selectedTabViewItem]] == SPTableViewStructure) { + [tableSourceInstance loadTable:selectedTableName]; + } else { + structureLoaded = !reload; + } +} + +/** + * Mark the content tab for refresh when it's next switched to, + * or reload the view if it's currently active + */ +- (void)setContentRequiresReload:(BOOL)reload +{ + if (reload && selectedTableName && [tableTabView indexOfTabViewItem:[tableTabView selectedTabViewItem]] == SPTableViewContent) { + [tableContentInstance loadTable:selectedTableName]; + } else { + contentLoaded = !reload; + } +} + +/** + * Mark the extended tab info for refresh when it's next switched to, + * or reload the view if it's currently active + */ +- (void)setStatusRequiresReload:(BOOL)reload +{ + if (reload && selectedTableName && [tableTabView indexOfTabViewItem:[tableTabView selectedTabViewItem]] == SPTableViewStatus) { + [[extendedTableInfoInstance onMainThread] loadTable:selectedTableName]; + } else { + statusLoaded = !reload; + } +} + + +/** + * Triggers a task to update the newly selected tab view, ensuring + * the data is fully loaded and up-to-date. + */ +- (void)tabView:(NSTabView *)aTabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem +{ + [self startTaskWithDescription:[NSString stringWithFormat:NSLocalizedString(@"Loading %@...", @"Loading table task string"), [self table]]]; + if ([NSThread isMainThread]) { + [NSThread detachNewThreadSelector:@selector(_loadTabTask:) toTarget:self withObject:tabViewItem]; + } else { + [self _loadTabTask:tabViewItem]; + } +} + +#pragma mark - +#pragma mark Table control + +/** + * Loads a specified table into the database view, and ensures it's selected in + * the tables list. Passing a table name of nil will deselect any currently selected + * table, but will leave multiple selections intact. + * If this method is supplied with the currently selected name, a reload rather than + * a load will be triggered. + */ +- (void)loadTable:(NSString *)aTable ofType:(NSInteger)aTableType +{ + + // Ensure a connection is still present + if (![mySQLConnection isConnected]) return; + + // If the supplied table name was nil, clear the views. + if (!aTable) { + + // Update the selected table name and type + if (selectedTableName) [selectedTableName release], selectedTableName = nil; + selectedTableType = SPTableTypeNone; + + // Clear the views + if ([[tablesListInstance selectedTableNames] count] == 1) { + [[tablesListInstance onMainThread] setSelection:nil]; + } + [tableSourceInstance loadTable:nil]; + [tableContentInstance loadTable:nil]; + [[extendedTableInfoInstance onMainThread] loadTable:nil]; + [[tableTriggersInstance onMainThread] loadTriggers]; + structureLoaded = NO; + contentLoaded = NO; + statusLoaded = NO; + triggersLoaded = NO; + + // Update the window title + [[self onMainThread] updateWindowTitle:self]; + + // Add a history entry + [spHistoryControllerInstance updateHistoryEntries]; + + // Notify listeners of the table change + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:SPTableChangedNotification object:self]; + + return; + } + + BOOL isReloading = (selectedTableName && [selectedTableName isEqualToString:aTable]); + + // Store the new name + if (selectedTableName) [selectedTableName release]; + selectedTableName = [[NSString alloc] initWithString:aTable]; + selectedTableType = aTableType; + + // Start a task + if (isReloading) { + [self startTaskWithDescription:NSLocalizedString(@"Reloading...", @"Reloading table task string")]; + } else { + [self startTaskWithDescription:[NSString stringWithFormat:NSLocalizedString(@"Loading %@...", @"Loading table task string"), aTable]]; + } + + // Update the tables list interface - also updates menus to reflect the selected table type + [[tablesListInstance onMainThread] setSelection:[NSDictionary dictionaryWithObjectsAndKeys:aTable, @"name", [NSNumber numberWithInteger:aTableType], @"type", nil]]; + + // If on the main thread, fire up a thread to deal with view changes and data loading; + // if already on a background thread, make the changes on the existing thread. + if ([NSThread isMainThread]) { + [NSThread detachNewThreadSelector:@selector(_loadTableTask) toTarget:self withObject:nil]; + } else { + [self _loadTableTask]; + } +} + +@end + +#pragma mark - + +@implementation SPDatabaseDocument (SPDatabaseViewControllerPrivateAPI) + +/** + * In a threaded task, ensure that the supplied tab is loaded - + * usually as a result of switching to it. + */ +- (void)_loadTabTask:(NSTabViewItem *)tabViewItem +{ + NSAutoreleasePool *tabLoadPool = [[NSAutoreleasePool alloc] init]; + + // If anything other than a single table or view is selected, don't proceed. + if (![self table] + || ([tablesListInstance tableType] != SPTableTypeTable && [tablesListInstance tableType] != SPTableTypeView)) + { + [self endTask]; + [tabLoadPool drain]; + return; + } + + // Get the tab view index and ensure the associated view is loaded + NSInteger selectedTabViewIndex = [[tabViewItem tabView] indexOfTabViewItem:tabViewItem]; + + switch (selectedTabViewIndex) { + case SPTableViewStructure: + if (!structureLoaded) { + [tableSourceInstance loadTable:selectedTableName]; + structureLoaded = YES; + } + break; + case SPTableViewContent: + if (!contentLoaded) { + [tableContentInstance loadTable:selectedTableName]; + contentLoaded = YES; + } + break; + case SPTableViewStatus: + if (!statusLoaded) { + [[extendedTableInfoInstance onMainThread] loadTable:selectedTableName]; + statusLoaded = YES; + } + break; + case SPTableViewTriggers: + if (!triggersLoaded) { + [[tableTriggersInstance onMainThread] loadTriggers]; + triggersLoaded = YES; + } + break; + } + + [self endTask]; + [tabLoadPool drain]; +} + + +/** + * In a threaded task, load the currently selected table/view/proc/function. + */ +- (void)_loadTableTask +{ + NSAutoreleasePool *loadPool = [[NSAutoreleasePool alloc] init]; + NSString *tableEncoding = nil; + + // Update the window title + [[self onMainThread] updateWindowTitle:self]; + + // Reset table information caches + [tableDataInstance resetAllData]; + + // Ensure status and details are fetched using UTF8 + NSString *previousEncoding = [mySQLConnection encoding]; + BOOL changeEncoding = ![previousEncoding isEqualToString:@"utf8"]; + if (changeEncoding) { + [mySQLConnection storeEncodingForRestoration]; + [mySQLConnection setEncoding:@"utf8"]; + } + + // Cache status information on the working thread + [tableDataInstance updateStatusInformationForCurrentTable]; + + // Check the current encoding against the table encoding to see whether + // an encoding change and reset is required + if( selectedTableType == SPTableTypeView || selectedTableType == SPTableTypeTable) { + + // 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] intValue] == SPEncodingAutodetect) { + if (tableEncoding != nil && ![tableEncoding isEqualToString:previousEncoding]) { + [self setConnectionEncoding:tableEncoding reloadingViews:NO]; + changeEncoding = NO; + } + } + } + + if (changeEncoding) [mySQLConnection restoreStoredEncoding]; + + // Notify listeners of the table change now that the state is fully set up. + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:SPTableChangedNotification object:self]; + + // Restore view states as appropriate + [spHistoryControllerInstance restoreViewStates]; + + // Reset all loaded views + structureLoaded = NO; + contentLoaded = NO; + statusLoaded = NO; + triggersLoaded = NO; + [tableSourceInstance loadTable:nil]; + [tableContentInstance loadTable:nil]; + [[extendedTableInfoInstance onMainThread] loadTable:nil]; + [[tableTriggersInstance onMainThread] loadTriggers]; + + // Load the currently selected view if looking at a table or view + if (tableEncoding && (selectedTableType == SPTableTypeView || selectedTableType == SPTableTypeTable)) + { + NSInteger selectedTabViewIndex = [tableTabView indexOfTabViewItem:[tableTabView selectedTabViewItem]]; + + switch (selectedTabViewIndex) { + case SPTableViewStructure: + [tableSourceInstance loadTable:selectedTableName]; + structureLoaded = YES; + break; + case SPTableViewContent: + [tableContentInstance loadTable:selectedTableName]; + contentLoaded = YES; + break; + case SPTableViewStatus: + [[extendedTableInfoInstance onMainThread] loadTable:selectedTableName]; + statusLoaded = YES; + break; + case SPTableViewTriggers: + [[tableTriggersInstance onMainThread] loadTriggers]; + triggersLoaded = YES; + break; + } + } + + // Update the "Show Create Syntax" window if it's already opened + // according to the selected table/view/proc/func + if([[[self onMainThread] getCreateTableSyntaxWindow] isVisible]) + [[self onMainThread] showCreateTableSyntax:self]; + + // Add a history entry + [spHistoryControllerInstance updateHistoryEntries]; + + // Empty the loading pool and exit the thread + [self endTask]; + [loadPool drain]; +} + +@end
\ No newline at end of file diff --git a/Source/SPExtendedTableInfo.m b/Source/SPExtendedTableInfo.m index bcf726c7..1f67b95d 100644 --- a/Source/SPExtendedTableInfo.m +++ b/Source/SPExtendedTableInfo.m @@ -102,7 +102,7 @@ if ([connection getLastErrorID] == 0) { // Reload the table's data - [tablesListInstance updateSelectionWithTaskString:NSLocalizedString(@"Reloading data...", @"Reloading data task description")]; + [tableDocumentInstance loadTable:selectedTable ofType:[tableDocumentInstance tableType]]; } else { [sender selectItemWithTitle:currentType]; diff --git a/Source/SPHistoryController.m b/Source/SPHistoryController.m index 3d7f00d0..3fb0e100 100644 --- a/Source/SPHistoryController.m +++ b/Source/SPHistoryController.m @@ -413,7 +413,7 @@ // If the same table was selected, mark the content as requiring a reload if ([historyEntry objectForKey:@"table"] && [[theDocument table] isEqualToString:[historyEntry objectForKey:@"table"]]) { - [tablesListInstance setContentRequiresReload:YES]; + [theDocument setContentRequiresReload:YES]; } // Update the database and table name if necessary diff --git a/Source/SPIndexesController.m b/Source/SPIndexesController.m index 09f1a3d8..a19480e6 100644 --- a/Source/SPIndexesController.m +++ b/Source/SPIndexesController.m @@ -716,7 +716,7 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; } else { [tableData resetAllData]; - [tablesList setStatusRequiresReload:YES]; + [dbDocument setStatusRequiresReload:YES]; [tableStructure loadTable:table]; } @@ -795,7 +795,7 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; } else { [tableData resetAllData]; - [tablesList setStatusRequiresReload:YES]; + [dbDocument setStatusRequiresReload:YES]; [tableStructure loadTable:table]; } diff --git a/Source/SPTableContent.m b/Source/SPTableContent.m index fe9e37ec..3c44b980 100644 --- a/Source/SPTableContent.m +++ b/Source/SPTableContent.m @@ -2005,8 +2005,8 @@ NSUInteger i; // Load table if not already done - if ( ![tablesListInstance contentLoaded] ) { - [self loadTable:[tablesListInstance tableName]]; + if ( ![tableDocumentInstance contentLoaded] ) { + [self loadTable:[tableDocumentInstance table]]; } tableColumns = [tableContentView tableColumns]; @@ -2060,8 +2060,8 @@ NSUInteger i; // Load the table if not already loaded - if ( ![tablesListInstance contentLoaded] ) { - [self loadTable:[tablesListInstance tableName]]; + if ( ![tableDocumentInstance contentLoaded] ) { + [self loadTable:[tableDocumentInstance table]]; } tableColumns = [tableContentView tableColumns]; diff --git a/Source/SPTableStructure.m b/Source/SPTableStructure.m index 86b4a84a..79a0a0a2 100644 --- a/Source/SPTableStructure.m +++ b/Source/SPTableStructure.m @@ -352,7 +352,7 @@ - (IBAction)reloadTable:(id)sender { [tableDataInstance resetAllData]; - [tablesListInstance setStatusRequiresReload:YES]; + [tableDocumentInstance setStatusRequiresReload:YES]; // Query the structure of all databases in the background (mainly for completion) [NSThread detachNewThreadSelector:@selector(queryDbStructureWithUserInfo:) toTarget:mySQLConnection withObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"forceUpdate", nil]]; @@ -1100,11 +1100,11 @@ currentlyEditingRow = -1; [tableDataInstance resetAllData]; - [tablesListInstance setStatusRequiresReload:YES]; + [tableDocumentInstance setStatusRequiresReload:YES]; [self loadTable:selectedTable]; // Mark the content table for refresh - [tablesListInstance setContentRequiresReload:YES]; + [tableDocumentInstance setContentRequiresReload:YES]; // Query the structure of all databases in the background [NSThread detachNewThreadSelector:@selector(queryDbStructureWithUserInfo:) toTarget:mySQLConnection withObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"forceUpdate", selectedTable, @"affectedItem", [NSNumber numberWithInt:[tablesListInstance tableType]], @"affectedItemType", nil]]; @@ -1322,8 +1322,8 @@ id field; //load table if not already done - if ( ![tablesListInstance structureLoaded] ) { - [self loadTable:[tablesListInstance tableName]]; + if ( ![tableDocumentInstance structureLoaded] ) { + [self loadTable:[tableDocumentInstance table]]; } //get field names @@ -1525,11 +1525,11 @@ } else { [tableDataInstance resetAllData]; - [tablesListInstance setStatusRequiresReload:YES]; + [tableDocumentInstance setStatusRequiresReload:YES]; [self loadTable:selectedTable]; // Mark the content table cache for refresh - [tablesListInstance setContentRequiresReload:YES]; + [tableDocumentInstance setContentRequiresReload:YES]; } [tableDocumentInstance endTask]; diff --git a/Source/SPTableStructureDelegate.m b/Source/SPTableStructureDelegate.m index 84c0a80c..049e2507 100644 --- a/Source/SPTableStructureDelegate.m +++ b/Source/SPTableStructureDelegate.m @@ -338,11 +338,11 @@ } else { [tableDataInstance resetAllData]; - [tablesListInstance setStatusRequiresReload:YES]; + [tableDocumentInstance setStatusRequiresReload:YES]; [self loadTable:selectedTable]; // Mark the content table cache for refresh - [tablesListInstance setContentRequiresReload:YES]; + [tableDocumentInstance setContentRequiresReload:YES]; if ( originalRowIndex < destinationRowIndex ) { [tableSourceView selectRowIndexes:[NSIndexSet indexSetWithIndex:destinationRowIndex-1] byExtendingSelection:NO]; diff --git a/Source/SPTablesList.h b/Source/SPTablesList.h index f0b0bed4..1ae4eecd 100644 --- a/Source/SPTablesList.h +++ b/Source/SPTablesList.h @@ -56,7 +56,6 @@ IBOutlet id copyTableNameField; IBOutlet id copyTableMessageField; IBOutlet id copyTableContentSwitch; - IBOutlet id tabView; IBOutlet id tableSheet; IBOutlet id tableNameField; IBOutlet id tableEncodingButton; @@ -101,7 +100,7 @@ BOOL tableListIsSelectable; BOOL tableListContainsViews; - BOOL structureLoaded, contentLoaded, statusLoaded, triggersLoaded, alertSheetOpened; + BOOL alertSheetOpened; } // IBAction methods @@ -117,8 +116,6 @@ // Additional methods - (void)setConnection:(MCPConnection *)theConnection; - (void)doPerformQueryService:(NSString *)query; -- (void)updateSelectionWithTaskString:(NSString *)taskString; -- (void)updateSelectionTask; - (void)setSelection:(NSDictionary *)selectionDetails; - (void)selectTableAtIndex:(NSNumber *)row; - (void)makeTableListFilterHaveFocus; @@ -139,18 +136,12 @@ - (NSArray *)allDatabaseNames; - (NSArray *)allSystemDatabaseNames; - (NSString *)selectedDatabase; -- (BOOL)structureLoaded; -- (BOOL)contentLoaded; -- (BOOL)statusLoaded; // Setters - (void)setContentRequiresReload:(BOOL)reload; - (void)setStatusRequiresReload:(BOOL)reload; - (BOOL)selectItemWithName:(NSString *)theName; -// Tabview delegate methods -- (void)loadTabTask:(NSTabViewItem *)tabViewItem; - // Table list filter interaction - (void) showFilter; - (void) hideFilter; diff --git a/Source/SPTablesList.m b/Source/SPTablesList.m index 722c3242..fc7be0f8 100644 --- a/Source/SPTablesList.m +++ b/Source/SPTablesList.m @@ -620,15 +620,6 @@ } /** - * Selects customQuery tab and passes query to customQueryInstance - */ -- (void)doPerformQueryService:(NSString *)query -{ - [tabView selectTabViewItemAtIndex:2]; - [customQueryInstance doPerformQueryService:query]; -} - -/** * Performs interface validation for various controls. */ - (void)controlTextDidChange:(NSNotification *)notification @@ -665,135 +656,6 @@ } /** - * Updates the current table selection. Triggered most times tableViewSelectionDidChange: - * fires, and also as a result of certain table actions. - */ -- (void)updateSelectionWithTaskString:(NSString *)taskString -{ - if (![mySQLConnection isConnected] || [tablesListView selectedRow] < 0) { - return; - } - id selectedItem = [filteredTables objectAtIndex:[tablesListView selectedRow]]; - if(![selectedItem isKindOfClass:[NSString class]]) { - return; - } - - // If there is a multiple or blank selection, clear all views directly. - if ( [tablesListView numberOfSelectedRows] != 1 || ![(NSString *)selectedItem 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] postNotificationOnMainThreadWithName: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; - NSString *previousEncoding = [mySQLConnection encoding]; - BOOL changeEncoding = ![previousEncoding isEqualToString:@"utf8"]; - if (changeEncoding) { - [mySQLConnection storeEncodingForRestoration]; - [mySQLConnection setEncoding:@"utf8"]; - } - - // 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]; - - // Ensure status information is cached on the working thread - [tableDataInstance updateStatusInformationForCurrentTable]; - - // Check the encoding if appropriate to determine if an encoding change is required - if( selectedTableType == SPTableTypeView || selectedTableType == SPTableTypeTable) { - - // 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] intValue] == SPEncodingAutodetect) { - if (tableEncoding != nil && ![tableEncoding isEqualToString:previousEncoding]) { - [tableDocumentInstance setConnectionEncoding:tableEncoding reloadingViews:NO]; - changeEncoding = NO; - } - } - } - - if (changeEncoding) [mySQLConnection restoreStoredEncoding]; - - // Notify listeners of the table change now that the state is fully set up. - [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:SPTableChangedNotification object:tableDocumentInstance]; - - // Restore view states as appropriate - [spHistoryControllerInstance restoreViewStates]; - - structureLoaded = NO; - contentLoaded = NO; - statusLoaded = NO; - triggersLoaded = NO; - if( selectedTableType == SPTableTypeView || selectedTableType == SPTableTypeTable) { - if ( [tabView indexOfTabViewItem:[tabView selectedTabViewItem]] == SPTableViewStructure ) { - [tableSourceInstance loadTable:selectedTableName]; - structureLoaded = YES; - } else if ( [tabView indexOfTabViewItem:[tabView selectedTabViewItem]] == SPTableViewContent ) { - if(tableEncoding == nil) { - [tableContentInstance loadTable:nil]; - } else { - [tableContentInstance loadTable:selectedTableName]; - } - contentLoaded = YES; - } else if ( [tabView indexOfTabViewItem:[tabView selectedTabViewItem]] == SPTableViewStatus ) { - [[extendedTableInfoInstance onMainThread] loadTable:selectedTableName]; - statusLoaded = YES; - } else if ( [tabView indexOfTabViewItem:[tabView selectedTabViewItem]] == SPTableViewTriggers ) { - [[tableTriggersInstance onMainThread] loadTriggers]; - triggersLoaded = YES; - } - } else { - - // if we are not looking at a table or view, clear these - [tableSourceInstance loadTable:nil]; - [tableContentInstance loadTable:nil]; - [[extendedTableInfoInstance onMainThread] loadTable:nil]; - [[tableTriggersInstance onMainThread] loadTriggers]; - } - - // 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. @@ -815,18 +677,6 @@ selectedTableName = nil; } - selectedTableType = SPTableTypeNone; - - [tableSourceInstance loadTable:nil]; - [tableContentInstance loadTable:nil]; - [extendedTableInfoInstance loadTable:nil]; - [tableTriggersInstance loadTriggers]; - - structureLoaded = NO; - contentLoaded = NO; - statusLoaded = NO; - triggersLoaded = NO; - // Set gear menu items Remove/Duplicate table/view according to the table types // if at least one item is selected if ([indexes count]) { @@ -922,9 +772,6 @@ [[tableSubMenu itemAtIndex:9] setHidden:NO]; [[tableSubMenu itemAtIndex:10] setHidden:NO]; - // set window title - [tableDocumentInstance updateWindowTitle:self]; - return; } @@ -947,10 +794,7 @@ [tablesListView reloadData]; } - // Reset the table information caches - [tableDataInstance resetAllData]; - - // Show menu separatoes + // Show menu separators [separatorTableMenuItem setHidden:NO]; [separatorTableContextMenuItem setHidden:NO]; [separatorTableMenuItem2 setHidden:NO]; @@ -1094,9 +938,6 @@ [showCreateSyntaxContextMenuItem setHidden:NO]; [showCreateSyntaxContextMenuItem setTitle:NSLocalizedString(@"Show Create Function Syntax...", @"show create func syntax menu item")]; } - - // set window title - [tableDocumentInstance updateWindowTitle:self]; } #pragma mark - @@ -1259,48 +1100,10 @@ return tableTypes; } -/** - * Returns YES if table source has already been loaded - */ -- (BOOL)structureLoaded -{ - return structureLoaded; -} - -/** - * Returns YES if table content has already been loaded - */ -- (BOOL)contentLoaded -{ - return contentLoaded; -} - -/** - * Returns YES if table status has already been loaded - */ -- (BOOL)statusLoaded -{ - return statusLoaded; -} #pragma mark - #pragma mark Setter methods -/** - * Mark the content table for refresh when it's next switched to - */ -- (void)setContentRequiresReload:(BOOL)reload -{ - contentLoaded = !reload; -} - -/** - * Mark the exteded table info for refresh when it's next switched to - */ -- (void)setStatusRequiresReload:(BOOL)reload -{ - statusLoaded = !reload; -} /** * Select an item using the provided name; returns YES if the @@ -1343,7 +1146,7 @@ selectedTableName = [[NSString alloc] initWithString:[tables objectAtIndex:itemIndex]]; selectedTableType = [[tableTypes objectAtIndex:itemIndex] integerValue]; [self updateFilter:self]; - [self updateSelectionWithTaskString:[NSString stringWithFormat:NSLocalizedString(@"Loading %@...", @"Loading table task string"), theName]]; + [tableDocumentInstance loadTable:selectedTableName ofType:selectedTableType]; } } @@ -1428,31 +1231,10 @@ if (selectedTableName) [selectedTableName release]; selectedTableName = [[NSString alloc] initWithString:newTableName]; - // if the 'table' is a view or a table, reload the currently selected view + // if the 'table' is a view or a table, ensure data is reloaded if (selectedTableType == SPTableTypeTable || selectedTableType == SPTableTypeView) { - statusLoaded = NO; - structureLoaded = NO; - contentLoaded = NO; - triggersLoaded = NO; - switch ([tabView indexOfTabViewItem:[tabView selectedTabViewItem]]) { - case SPTableViewStructure: - [tableSourceInstance loadTable:newTableName]; - structureLoaded = YES; - break; - case SPTableViewContent: - [tableContentInstance loadTable:newTableName]; - contentLoaded = YES; - break; - case SPTableViewStatus: - [extendedTableInfoInstance loadTable:newTableName]; - statusLoaded = YES; - break; - case SPTableViewTriggers: - [tableTriggersInstance loadTriggers]; - triggersLoaded = YES; - break; - } + [tableDocumentInstance loadTable:selectedTableName ofType:selectedTableType]; } } @catch (NSException * myException) { @@ -1516,28 +1298,18 @@ */ - (void)tableViewSelectionDidChange:(NSNotification *)aNotification { + if ([tablesListView numberOfSelectedRows] != 1) { - if([tablesListView selectedRow] < 0) { - // Reset all - if (selectedTableName) [selectedTableName release]; - selectedTableName = nil; + // Ensure the state is cleared + if ([tableDocumentInstance table]) [tableDocumentInstance loadTable:nil ofType:SPTableTypeNone]; + if (selectedTableName) [selectedTableName release], selectedTableName = nil; selectedTableType = SPTableTypeNone; - [tableSourceInstance loadTable:nil]; - [tableContentInstance loadTable:nil]; - [extendedTableInfoInstance loadTable:nil]; - [tableTriggersInstance loadTriggers]; - structureLoaded = NO; - contentLoaded = NO; - statusLoaded = NO; - triggersLoaded = NO; - [self updateSelectionWithTaskString:NSLocalizedString(@"Reloading...", @"Reloading table task string")]; return; } - id selectedItem = [filteredTables objectAtIndex:[tablesListView selectedRow]]; + NSInteger selectedRowIndex = [tablesListView selectedRow]; - if(![selectedItem isKindOfClass:[NSString class]]) { - [self updateSelectionWithTaskString:NSLocalizedString(@"Reloading...", @"Reloading table task string")]; + if (![[filteredTables objectAtIndex:selectedRowIndex] isKindOfClass:[NSString class]]) { return; } @@ -1545,32 +1317,28 @@ if ([tableDocumentInstance isWorking]) tableListIsSelectable = NO; // Perform no action if the selected table hasn't actually changed - reselection etc - if ([tablesListView numberOfSelectedRows] == 1 - && [(NSString *)selectedItem length] - && [selectedTableName isEqualToString:(NSString *)selectedItem] - && selectedTableType == [[filteredTableTypes objectAtIndex:[tablesListView selectedRow]] integerValue]) - { + NSString *newName = [filteredTables objectAtIndex:selectedRowIndex]; + NSInteger newType = [[filteredTableTypes objectAtIndex:selectedRowIndex] integerValue]; + if ([selectedTableName isEqualToString:newName] && selectedTableType == newType) { return; } // Save existing scroll position and details [spHistoryControllerInstance updateHistoryEntries]; - NSString *tableName = @"data"; - if ([tablesListView numberOfSelectedRows] == 1 && [selectedItem isKindOfClass:[NSString class]] && [(NSString *)selectedItem length]) - tableName = [filteredTables objectAtIndex:[tablesListView selectedRow]]; - [self updateSelectionWithTaskString:[NSString stringWithFormat:NSLocalizedString(@"Loading %@...", @"Loading table task string"), tableName]]; + if (selectedTableName) [selectedTableName release], selectedTableName = nil; + selectedTableName = [[NSString alloc] initWithString:newName]; + selectedTableType = newType; + [tableDocumentInstance loadTable:selectedTableName ofType:selectedTableType]; - if([[SPNavigatorController sharedNavigatorController] syncMode] && [tablesListView numberOfSelectedRows] == 1) { + if([[SPNavigatorController sharedNavigatorController] syncMode]) { NSMutableString *schemaPath = [NSMutableString string]; [schemaPath setString:[tableDocumentInstance connectionID]]; if([tableDocumentInstance database] && [[tableDocumentInstance database] length]) { [schemaPath appendString:SPUniqueSchemaDelimiter]; [schemaPath appendString:[tableDocumentInstance database]]; - if(tableName && [tableName length]) { - [schemaPath appendString:SPUniqueSchemaDelimiter]; - [schemaPath appendString:tableName]; - } + [schemaPath appendString:SPUniqueSchemaDelimiter]; + [schemaPath appendString:selectedTableName]; } [[SPNavigatorController sharedNavigatorController] selectPath:schemaPath]; } @@ -1682,57 +1450,7 @@ } #pragma mark - -#pragma mark TabView delegate methods - -/** - * Loads structure or source if tab selected the first time, - * using a threaded load if currently on the main thread. - */ -- (void)tabView:(NSTabView *)aTabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem -{ - [tableDocumentInstance startTaskWithDescription:[NSString stringWithFormat:NSLocalizedString(@"Loading %@...", @"Loading table task string"), selectedTableName]]; - if ([NSThread isMainThread]) { - [NSThread detachNewThreadSelector:@selector(loadTabTask:) toTarget:self withObject:tabViewItem]; - } else { - [self loadTabTask:tabViewItem]; - } -} -- (void)loadTabTask:(NSTabViewItem *)tabViewItem -{ - NSAutoreleasePool *tabLoadPool = [[NSAutoreleasePool alloc] init]; - - if ([tablesListView numberOfSelectedRows] == 1 - && ([self tableType] == SPTableTypeTable || [self tableType] == SPTableTypeView) ) - { - - if ( ([tabView indexOfTabViewItem:[tabView selectedTabViewItem]] == SPTableViewStructure) && !structureLoaded ) { - [tableSourceInstance loadTable:selectedTableName]; - structureLoaded = YES; - } - - if ( ([tabView indexOfTabViewItem:[tabView selectedTabViewItem]] == SPTableViewContent) && !contentLoaded ) { - [tableContentInstance loadTable:selectedTableName]; - contentLoaded = YES; - } - - if ( ([tabView indexOfTabViewItem:[tabView selectedTabViewItem]] == SPTableViewStatus) && !statusLoaded ) { - [[extendedTableInfoInstance onMainThread] loadTable:selectedTableName]; - statusLoaded = YES; - } - - if ( ([tabView indexOfTabViewItem:[tabView selectedTabViewItem]] == SPTableViewTriggers) && !triggersLoaded ) { - [[tableTriggersInstance onMainThread] loadTriggers]; - triggersLoaded = YES; - } - } - else { - [tableSourceInstance loadTable:nil]; - [tableContentInstance loadTable:nil]; - } - - [tableDocumentInstance endTask]; - [tabLoadPool drain]; -} +#pragma mark Interface validation /** * Menu item interface validation @@ -1949,10 +1667,6 @@ filteredTables = tables; tableTypes = [[NSMutableArray alloc] init]; filteredTableTypes = tableTypes; - structureLoaded = NO; - contentLoaded = NO; - statusLoaded = NO; - triggersLoaded = NO; isTableListFiltered = NO; tableListIsSelectable = YES; tableListContainsViews = NO; @@ -2159,11 +1873,7 @@ } // Ensure the the table's content view is updated to show that it has been truncated - if ([tabView indexOfTabViewItem:[tabView selectedTabViewItem]] == SPTableViewContent) { - [tableContentInstance reloadTable:self]; - } else { - [self setContentRequiresReload:YES]; - } + [tableDocumentInstance setContentRequiresReload:YES]; [tableDataInstance resetStatusData]; } @@ -2233,17 +1943,16 @@ [tableTypes insertObject:[NSNumber numberWithInteger:SPTableTypeTable] atIndex:addItemAtIndex]; } - // Set the selected table name and type, and then use updateFilter and updateSelection to update the filter list and selection. + // Set the selected table name and type, and then update the filter list and the + // selection. if (selectedTableName) [selectedTableName release]; - selectedTableName = [[NSString alloc] initWithString:tableName]; selectedTableType = SPTableTypeTable; [self updateFilter:self]; - [tablesListView scrollRowToVisible:[tablesListView selectedRow]]; - [self updateSelectionWithTaskString:[NSString stringWithFormat:NSLocalizedString(@"Loading %@...", @"Loading table task string"), selectedTableName]]; + [tableDocumentInstance loadTable:selectedTableName ofType:selectedTableType]; // Query the structure of all databases in the background (mainly for completion) [NSThread detachNewThreadSelector:@selector(queryDbStructureWithUserInfo:) toTarget:mySQLConnection withObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"forceUpdate", nil]]; @@ -2439,7 +2148,7 @@ selectedTableType = tblType; [self updateFilter:self]; [tablesListView scrollRowToVisible:[tablesListView selectedRow]]; - [self updateSelectionWithTaskString:[NSString stringWithFormat:NSLocalizedString(@"Loading %@...", @"Loading table task string"), selectedTableName]]; + [tableDocumentInstance loadTable:selectedTableName ofType:selectedTableType]; // Query the structure of all databases in the background (mainly for completion) [NSThread detachNewThreadSelector:@selector(queryDbStructureWithUserInfo:) toTarget:mySQLConnection withObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"forceUpdate", nil]]; diff --git a/Source/SPWindowController.m b/Source/SPWindowController.m index 22b7c13d..b22248fe 100644 --- a/Source/SPWindowController.m +++ b/Source/SPWindowController.m @@ -106,7 +106,7 @@ // Set up a new tab with the connection view as the identifier, add the view, and add it to the tab view NSTabViewItem *newItem = [[[NSTabViewItem alloc] initWithIdentifier:newTableDocument] autorelease]; - [newItem setView:[newTableDocument parentView]]; + [newItem setView:[newTableDocument databaseView]]; [tabView addTabViewItem:newItem]; [tabView selectTabViewItem:newItem]; [newTableDocument setParentTabViewItem:newItem]; |