aboutsummaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorrowanbeentje <rowan@beent.je>2009-11-04 01:15:53 +0000
committerrowanbeentje <rowan@beent.je>2009-11-04 01:15:53 +0000
commit48d02b7080cadc507b1e7897c54ce2a8cf149acf (patch)
treef45eba9b97c71e1579580d790e9c9aa00088b26a /Source
parent0d5acfadf8d43ab3889f50456f5dc7ff42bf1a12 (diff)
downloadsequelpro-48d02b7080cadc507b1e7897c54ce2a8cf149acf.tar.gz
sequelpro-48d02b7080cadc507b1e7897c54ce2a8cf149acf.tar.bz2
sequelpro-48d02b7080cadc507b1e7897c54ce2a8cf149acf.zip
- Add task support to all the main interface views
- Improve task support on previously supported views - Use a threaded task load for all initial table loads - Support threaded task loads for table content loads, reloads, sorts, and filters - Improve upon previous threaded task loads by minimising view updates and supporting updates of the existing data arrays where valid
Diffstat (limited to 'Source')
-rw-r--r--Source/CustomQuery.m16
-rw-r--r--Source/SPArrayAdditions.h9
-rw-r--r--Source/SPConstants.h1
-rw-r--r--Source/SPConstants.m1
-rw-r--r--Source/SPExtendedTableInfo.h5
-rw-r--r--Source/SPExtendedTableInfo.m77
-rw-r--r--Source/SPTableInfo.m5
-rw-r--r--Source/SPTableRelations.h4
-rw-r--r--Source/SPTableRelations.m69
-rw-r--r--Source/TableContent.h2
-rw-r--r--Source/TableContent.m439
-rw-r--r--Source/TableSource.m15
-rw-r--r--Source/TablesList.h3
-rw-r--r--Source/TablesList.m453
14 files changed, 666 insertions, 433 deletions
diff --git a/Source/CustomQuery.m b/Source/CustomQuery.m
index 25c90dba..c05d87f7 100644
--- a/Source/CustomQuery.m
+++ b/Source/CustomQuery.m
@@ -2567,10 +2567,8 @@
- (void) startDocumentTaskForTab:(NSNotification *)aNotification
{
- // Only proceed if the current document is the notifying document, and only if
- // this view is selected.
- if ([aNotification object] != tableDocumentInstance
- || ![[[aNotification object] selectedToolbarItemIdentifier] isEqualToString:MAIN_TOOLBAR_CUSTOM_QUERY])
+ // Only proceed if this view is selected.
+ if (![[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:MAIN_TOOLBAR_CUSTOM_QUERY])
return;
[runSelectionButton setEnabled:NO];
@@ -2585,10 +2583,8 @@
- (void) endDocumentTaskForTab:(NSNotification *)aNotification
{
- // Only proceed if the current document is the notifying document, and only if
- // this view is selected.
- if ([aNotification object] != tableDocumentInstance
- || ![[[aNotification object] selectedToolbarItemIdentifier] isEqualToString:MAIN_TOOLBAR_CUSTOM_QUERY])
+ // Only proceed if this view is selected.
+ if (![[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:MAIN_TOOLBAR_CUSTOM_QUERY])
return;
if (selectionButtonCanBeEnabled) {
@@ -2780,11 +2776,11 @@
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(startDocumentTaskForTab:)
name:SPDocumentTaskStartNotification
- object:nil];
+ object:tableDocumentInstance];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(endDocumentTaskForTab:)
name:SPDocumentTaskEndNotification
- object:nil];
+ object:tableDocumentInstance];
}
- (void)dealloc
diff --git a/Source/SPArrayAdditions.h b/Source/SPArrayAdditions.h
index 31493f22..eb11da02 100644
--- a/Source/SPArrayAdditions.h
+++ b/Source/SPArrayAdditions.h
@@ -27,12 +27,11 @@
static inline id NSArrayObjectAtIndex(NSArray* self, NSUInteger i) {
return (id)CFArrayGetValueAtIndex((CFArrayRef)self, i);
}
-
static inline void NSMutableArrayAddObject(NSArray* self, id anObject) {
- typedef void (*SPMutableArrayAddObjectMethodPtr)(NSArray*, SEL, id);
- static SPMutableArrayAddObjectMethodPtr SPNSMutableArrayAddObject;
- if (!SPNSMutableArrayAddObject) SPNSMutableArrayAddObject = (SPMutableArrayAddObjectMethodPtr)[self methodForSelector:@selector(addObject:)];
- SPNSMutableArrayAddObject(self, @selector(addObject:), anObject);
+ CFArrayAppendValue((CFMutableArrayRef)self, anObject);
+}
+static inline void NSMutableArrayReplaceObject(NSArray* self, CFIndex idx, id anObject) {
+ CFArraySetValueAtIndex((CFMutableArrayRef)self, idx, anObject);
}
@interface NSArray (SPArrayAdditions)
diff --git a/Source/SPConstants.h b/Source/SPConstants.h
index d8d16adf..aafabd73 100644
--- a/Source/SPConstants.h
+++ b/Source/SPConstants.h
@@ -159,3 +159,4 @@ extern NSString *SPQueryFavoriteReplacesContent;
extern NSString *SPQueryHistory;
extern NSString *SPQueryHistoryReplacesContent;
extern NSString *SPQuickLookTypes;
+extern NSString *SPTableChangedNotification;
diff --git a/Source/SPConstants.m b/Source/SPConstants.m
index 5e88ab0d..21b9bfe7 100644
--- a/Source/SPConstants.m
+++ b/Source/SPConstants.m
@@ -117,3 +117,4 @@ NSString *SPQueryFavoriteReplacesContent = @"QueryFavoriteReplacesConten
NSString *SPQueryHistory = @"queryHistory";
NSString *SPQueryHistoryReplacesContent = @"QueryHistoryReplacesContent";
NSString *SPQuickLookTypes = @"QuickLookTypes";
+NSString *SPTableChangedNotification = @"SPTableSelectionChanged";
diff --git a/Source/SPExtendedTableInfo.h b/Source/SPExtendedTableInfo.h
index ac0f6096..e9c17b56 100644
--- a/Source/SPExtendedTableInfo.h
+++ b/Source/SPExtendedTableInfo.h
@@ -30,6 +30,7 @@
@interface SPExtendedTableInfo : NSObject
{
+ IBOutlet id tableDocumentInstance;
IBOutlet SPTableData *tableDataInstance;
IBOutlet SPDatabaseData *databaseDataInstance;
@@ -67,4 +68,8 @@
// Others
- (void)loadTable:(NSString *)table;
+// Task interaction
+- (void) startDocumentTaskForTab:(NSNotification *)aNotification;
+- (void) endDocumentTaskForTab:(NSNotification *)aNotification;
+
@end
diff --git a/Source/SPExtendedTableInfo.m b/Source/SPExtendedTableInfo.m
index 54830e9b..0976aa92 100644
--- a/Source/SPExtendedTableInfo.m
+++ b/Source/SPExtendedTableInfo.m
@@ -28,6 +28,8 @@
#import "RegexKitLite.h"
#import "SPDatabaseData.h"
#import "SPStringAdditions.h"
+#import "SPConstants.h"
+#import "TableDocument.h"
@interface SPExtendedTableInfo (PrivateAPI)
@@ -54,6 +56,16 @@
toObject:[NSUserDefaultsController sharedUserDefaultsController]
withKeyPath:@"values.CustomQueryEditorBackgroundColor"
options:bindingOptions];
+
+ // Add observers for document task activity
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(startDocumentTaskForTab:)
+ name:SPDocumentTaskStartNotification
+ object:tableDocumentInstance];
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(endDocumentTaskForTab:)
+ name:SPDocumentTaskEndNotification
+ object:tableDocumentInstance];
}
#pragma mark -
@@ -163,10 +175,13 @@
/**
* Load all the info for the supplied table by querying the table data instance and updaing the interface
- * elements accordingly.
+ * elements accordingly.
+ * Note that interface elements are also toggled in start/endDocumentTaskForTab:, with similar logic.
*/
- (void)loadTable:(NSString *)table
{
+ BOOL enableInteraction = ![[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:MAIN_TOOLBAR_TABLE_INFO] || ![tableDocumentInstance isWorking];
+
// Store the table name away for future use
selectedTable = table;
@@ -230,7 +245,7 @@
}
[tableTypePopUpButton selectItemWithTitle:[statusFields objectForKey:@"Engine"]];
- [tableTypePopUpButton setEnabled:YES];
+ [tableTypePopUpButton setEnabled:enableInteraction];
}
else {
[tableTypePopUpButton addItemWithTitle:@"Not available"];
@@ -252,7 +267,7 @@
}
[tableEncodingPopUpButton selectItemWithTitle:selectedTitle];
- [tableEncodingPopUpButton setEnabled:YES];
+ [tableEncodingPopUpButton setEnabled:enableInteraction];
}
else {
[tableEncodingPopUpButton addItemWithTitle:@"Not available"];
@@ -266,7 +281,7 @@
}
[tableCollationPopUpButton selectItemWithTitle:[statusFields objectForKey:@"Collation"]];
- [tableCollationPopUpButton setEnabled:YES];
+ [tableCollationPopUpButton setEnabled:enableInteraction];
}
else {
[tableCollationPopUpButton addItemWithTitle:@"Not available"];
@@ -288,7 +303,7 @@
[tableSizeFree setStringValue:[self _formatValueWithKey:@"Data_free" inDictionary:statusFields withLabel:@"Free data size"]];
// Set comments
- [tableCommentsTextView setEditable:YES];
+ [tableCommentsTextView setEditable:enableInteraction];
[tableCommentsTextView setString:[statusFields objectForKey:@"Comment"]];
// Set create syntax
@@ -328,11 +343,63 @@
}
}
+#pragma mark -
+#pragma mark Task interaction
+
+/**
+ * Disable all content interactive elements during an ongoing task.
+ */
+- (void) startDocumentTaskForTab:(NSNotification *)aNotification
+{
+
+ // Only proceed if this view is selected.
+ if (![[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:MAIN_TOOLBAR_TABLE_INFO])
+ return;
+
+ [tableTypePopUpButton setEnabled:NO];
+ [tableEncodingPopUpButton setEnabled:NO];
+ [tableCollationPopUpButton setEnabled:NO];
+ [tableCommentsTextView setEditable:NO];
+}
+
+/**
+ * Enable all content interactive elements after an ongoing task.
+ */
+- (void) endDocumentTaskForTab:(NSNotification *)aNotification
+{
+
+ // Only proceed if this view is selected.
+ if (![[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:MAIN_TOOLBAR_TABLE_INFO])
+ return;
+
+ NSDictionary *statusFields = [tableDataInstance statusValues];
+ if (!selectedTable || ![selectedTable length] || [[statusFields objectForKey:@"Engine"] isEqualToString:@"View"])
+ return;
+
+ if ([[databaseDataInstance getDatabaseStorageEngines] count] && [statusFields objectForKey:@"Engine"])
+ [tableTypePopUpButton setEnabled:YES];
+
+ if ([[databaseDataInstance getDatabaseCharacterSetEncodings] count] && [tableDataInstance tableEncoding])
+ [tableEncodingPopUpButton setEnabled:YES];
+
+ if ([[databaseDataInstance getDatabaseCollationsForEncoding:[tableDataInstance tableEncoding]] count]
+ && [statusFields objectForKey:@"Collation"])
+ {
+ [tableCollationPopUpButton setEnabled:YES];
+ }
+
+ [tableCommentsTextView setEditable:YES];
+}
+
+#pragma mark -
+
/**
* Release connection.
*/
- (void)dealloc
{
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+
[connection release], connection = nil;
[super dealloc];
diff --git a/Source/SPTableInfo.m b/Source/SPTableInfo.m
index b3ff4946..166a7634 100644
--- a/Source/SPTableInfo.m
+++ b/Source/SPTableInfo.m
@@ -29,6 +29,7 @@
#import "TableDocument.h"
#import "TablesList.h"
#import "SPTableData.h"
+#import "SPConstants.h"
#import "SPStringAdditions.h"
@interface SPTableInfo (PrivateAPI)
@@ -52,8 +53,8 @@
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(tableChanged:)
- name:NSTableViewSelectionDidChangeNotification
- object:tableList];
+ name:SPTableChangedNotification
+ object:tableDocumentInstance];
[info addObject:NSLocalizedString(@"TABLE INFORMATION", @"header for table info pane")];
[infoTable reloadData];
diff --git a/Source/SPTableRelations.h b/Source/SPTableRelations.h
index 61328e59..6d4315e2 100644
--- a/Source/SPTableRelations.h
+++ b/Source/SPTableRelations.h
@@ -68,4 +68,8 @@
- (IBAction)selectReferenceTable:(id)sender;
- (IBAction)refreshRelations:(id)sender;
+// Task interaction
+- (void) startDocumentTaskForTab:(NSNotification *)aNotification;
+- (void) endDocumentTaskForTab:(NSNotification *)aNotification;
+
@end
diff --git a/Source/SPTableRelations.m b/Source/SPTableRelations.m
index 92eebfaf..bdc1c418 100644
--- a/Source/SPTableRelations.m
+++ b/Source/SPTableRelations.m
@@ -63,8 +63,18 @@
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(tableSelectionChanged:)
- name:NSTableViewSelectionDidChangeNotification
- object:tableList];
+ name:SPTableChangedNotification
+ object:tableDocumentInstance];
+
+ // Add observers for document task activity
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(startDocumentTaskForTab:)
+ name:SPDocumentTaskStartNotification
+ object:tableDocumentInstance];
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(endDocumentTaskForTab:)
+ name:SPDocumentTaskEndNotification
+ object:tableDocumentInstance];
}
#pragma mark -
@@ -210,9 +220,11 @@
*/
- (void)tableSelectionChanged:(NSNotification *)notification
{
+ BOOL enableInteraction = ![[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:MAIN_TOOLBAR_TABLE_RELATIONS] || ![tableDocumentInstance isWorking];
+
// To begin enable all interface elements
- [addRelationButton setEnabled:YES];
- [refreshRelationsButton setEnabled:YES];
+ [addRelationButton setEnabled:enableInteraction];
+ [refreshRelationsButton setEnabled:enableInteraction];
[relationsTableView setEnabled:YES];
// Get the current table's storage engine
@@ -223,8 +235,8 @@
// Update the text label
[labelTextField setStringValue:[NSString stringWithFormat:@"Relations for table: %@", [tablesListInstance tableName]]];
- [addRelationButton setEnabled:YES];
- [refreshRelationsButton setEnabled:YES];
+ [addRelationButton setEnabled:enableInteraction];
+ [refreshRelationsButton setEnabled:enableInteraction];
[relationsTableView setEnabled:YES];
}
else {
@@ -268,9 +280,54 @@
*/
- (BOOL)tableView:(NSTableView *)aTableView shouldEditTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
{
+ if ([tableDocumentInstance isWorking]) return NO;
+
return NO;
}
+/**
+ * Disable row selection while the document is working.
+ */
+- (BOOL)tableView:(NSTableView *)aTableView shouldSelectRow:(NSInteger)rowIndex
+{
+ return ![tableDocumentInstance isWorking];
+}
+
+#pragma mark -
+#pragma mark Task interaction
+
+/**
+ * Disable all content interactive elements during an ongoing task.
+ */
+- (void) startDocumentTaskForTab:(NSNotification *)aNotification
+{
+
+ // Only proceed if this view is selected.
+ if (![[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:MAIN_TOOLBAR_TABLE_RELATIONS])
+ return;
+
+ [addRelationButton setEnabled:NO];
+ [refreshRelationsButton setEnabled:NO];
+ [removeRelationButton setEnabled:NO];
+}
+
+/**
+ * Enable all content interactive elements after an ongoing task.
+ */
+- (void) endDocumentTaskForTab:(NSNotification *)aNotification
+{
+
+ // Only proceed if this view is selected.
+ if (![[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:MAIN_TOOLBAR_TABLE_RELATIONS])
+ return;
+
+ if ([relationsTableView isEnabled]) {
+ [addRelationButton setEnabled:YES];
+ [refreshRelationsButton setEnabled:YES];
+ }
+ [removeRelationButton setEnabled:([relationsTableView numberOfSelectedRows] > 0)];
+}
+
#pragma mark -
#pragma mark Other
diff --git a/Source/TableContent.h b/Source/TableContent.h
index e37cb6f5..b15fb957 100644
--- a/Source/TableContent.h
+++ b/Source/TableContent.h
@@ -61,7 +61,7 @@
NSString *selectedTable, *usedQuery;
NSMutableArray *tableValues, *dataColumns, *keys, *oldRow;
- NSUInteger tableValuesCount;
+ NSUInteger tableRowsCount, previousTableRowsCount, tableColumnsCount;
NSString *compareType;
NSNumber *sortCol;
BOOL isEditingRow, isEditingNewRow, isSavingRow, isDesc, setLimit;
diff --git a/Source/TableContent.m b/Source/TableContent.m
index 610cfa86..ccc82e5e 100644
--- a/Source/TableContent.m
+++ b/Source/TableContent.m
@@ -59,8 +59,10 @@
if ((self == [super init])) {
tableValues = [[NSMutableArray alloc] init];
- tableValuesCount = 0;
+ tableRowsCount = 0;
+ previousTableRowsCount = 0;
dataColumns = [[NSMutableArray alloc] init];
+ tableColumnsCount = 0;
oldRow = [[NSMutableArray alloc] init];
selectedTable = nil;
@@ -125,11 +127,11 @@
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(startDocumentTaskForTab:)
name:SPDocumentTaskStartNotification
- object:nil];
+ object:tableDocumentInstance];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(endDocumentTaskForTab:)
name:SPDocumentTaskEndNotification
- object:nil];
+ object:tableDocumentInstance];
}
#pragma mark -
@@ -146,36 +148,50 @@
NSArray *columnNames;
NSDictionary *columnDefinition;
NSTableColumn *theCol;
+ BOOL enableInteraction = ![[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:MAIN_TOOLBAR_TABLE_CONTENT] || ![tableDocumentInstance isWorking];
- // Clear the selection, and abort the reload if the user is still editing a row
- [tableContentView deselectAll:self];
+ // Abort the reload if the user is still editing a row
if ( isEditingRow )
return;
- // Store the newly selected table name
- selectedTable = aTable;
-
- // Reset table key store for use in argumentForRow:
- if (keys) [keys release], keys = nil;
+ // Check the supplied table name. If it matches the old one, a reload is being performed;
+ // reload the data in-place to maintain table state if possible.
+ if ([selectedTable isEqualToString:aTable]) {
+ previousTableRowsCount = tableRowsCount;
+
+ // Otherwise store the newly selected table name and reset the data
+ } else {
+ selectedTable = aTable;
+ previousTableRowsCount = 0;
- // Restore the table content view to the top left
- [tableContentView scrollRowToVisible:0];
- [tableContentView scrollColumnToVisible:0];
+ // Clear the selection
+ [tableContentView deselectAll:self];
- // Remove existing columns from the table
- while ([[tableContentView tableColumns] count]) {
- [tableContentView removeTableColumn:NSArrayObjectAtIndex([tableContentView tableColumns], 0)];
+ // Restore the table content view to the top left
+ [tableContentView scrollRowToVisible:0];
+ [tableContentView scrollColumnToVisible:0];
}
+ // Reset table key store for use in argumentForRow:
+ if (keys) [keys release], keys = nil;
+
// Reset data column store
+ tableColumnsCount = 0;
[dataColumns removeAllObjects];
// If no table has been supplied, reset the view to a blank table and disabled elements.
// [tableDataInstance tableEncoding] == nil indicates that an error occured while retrieving table data
if ( [[[tableDataInstance statusValues] objectForKey:@"Rows"] isNSNull] || [aTable isEqualToString:@""] || !aTable || [tableDataInstance tableEncoding] == nil)
{
+
+ // Remove existing columns from the table
+ while ([[tableContentView tableColumns] count]) {
+ [tableContentView removeTableColumn:NSArrayObjectAtIndex([tableContentView tableColumns], 0)];
+ }
+
// Empty the stored data arrays
- tableValuesCount = 0;
+ tableRowsCount = 0;
+ previousTableRowsCount = 0;
[tableValues removeAllObjects];
[tableContentView reloadData];
isFiltered = NO;
@@ -250,7 +266,15 @@
}
NSString *nullValue = [prefs objectForKey:SPNullValue];
-
+
+ // Lock drawing in the window
+ [tableWindow disableFlushWindow];
+
+ // Remove existing columns from the table
+ while ([[tableContentView tableColumns] count]) {
+ [tableContentView removeTableColumn:NSArrayObjectAtIndex([tableContentView tableColumns], 0)];
+ }
+
// Add the new columns to the table
for ( i = 0 ; i < [dataColumns count] ; i++ ) {
columnDefinition = NSArrayObjectAtIndex(dataColumns, i);
@@ -316,6 +340,7 @@
// Add the column to the table
[tableContentView addTableColumn:theCol];
+ tableColumnsCount++;
[theCol release];
}
@@ -341,6 +366,9 @@
isDesc = NO;
}
+ // Restore window drawing
+ [tableWindow enableFlushWindow];
+
// Store the current first responder so filter field doesn't steal focus
id currentFirstResponder = [tableWindow firstResponder];
@@ -355,7 +383,7 @@
[self setCompareTypes:self];
[argumentField setEnabled:YES];
[argumentField setStringValue:@""];
- [filterButton setEnabled:YES];
+ [filterButton setEnabled:enableInteraction];
// Restore preserved filter settings if appropriate and valid
if (filterFieldToRestore) {
@@ -401,19 +429,22 @@
}
// Set the state of the table buttons
- [addButton setEnabled:YES];
+ [addButton setEnabled:enableInteraction];
[copyButton setEnabled:NO];
[removeButton setEnabled:NO];
+ // Reset the table store if required - basically if the table is being changed
+ if (!previousTableRowsCount) {
+ tableRowsCount = 0;
+ [tableValues removeAllObjects];
+ }
+
// Trigger a data refresh
[self loadTableValues];
// Restore the view origin if appropriate
if (!NSEqualRects(selectionViewportToRestore, NSZeroRect)) {
- // Let the table know the size of the newly available data
- [tableContentView reloadData];
-
// Scroll the viewport to the saved location
selectionViewportToRestore.size = [tableContentView visibleRect].size;
[tableContentView scrollRectToVisible:selectionViewportToRestore];
@@ -424,8 +455,8 @@
[tableContentView selectRowIndexes:selectionIndexToRestore byExtendingSelection:NO];
}
- // Reload the table data display
- [tableContentView reloadData];
+ // Update display if necessary
+ [tableContentView displayIfNeeded];
// Init copyTable with necessary information for copying selected rows as SQL INSERT
[tableContentView setTableInstance:self withTableData:tableValues withColumns:dataColumns withTableName:selectedTable withConnection:mySQLConnection];
@@ -441,6 +472,7 @@
* Reload the table data without reconfiguring the tableView,
* using filters and limits as appropriate.
* Will not refresh the table view itself.
+ * Note that this does not empty the table array - see use of previousTableRowsCount.
*/
- (void) loadTableValues
{
@@ -456,11 +488,6 @@
[countText setStringValue:NSLocalizedString(@"Loading table data...", @"Loading table data string")];
- // Remove all items from the table
- tableValuesCount = 0;
- [tableContentView noteNumberOfRowsChanged];
- [tableValues removeAllObjects];
-
// Notify any listeners that a query has started
[[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryWillBePerformed" object:self];
@@ -506,13 +533,14 @@
}
// Perform and process the query
+ [tableContentView performSelectorOnMainThread:@selector(noteNumberOfRowsChanged) withObject:nil waitUntilDone:YES];
[self setUsedQuery:queryString];
streamingResult = [mySQLConnection streamingQueryString:queryString];
[self processResultIntoDataStorage:streamingResult approximateRowCount:rowsToLoad];
[streamingResult release];
// If the result is empty, and a limit is active, reset the limit
- if ([prefs boolForKey:SPLimitResults] && queryStringBeforeLimit && !tableValuesCount) {
+ if ([prefs boolForKey:SPLimitResults] && queryStringBeforeLimit && !tableRowsCount) {
[limitRowsField setStringValue:@"1"];
queryString = [NSMutableString stringWithFormat:@"%@ LIMIT 0,%d", queryStringBeforeLimit, [prefs integerForKey:SPLimitResultsValue]];
[self setUsedQuery:queryString];
@@ -523,7 +551,7 @@
if ([prefs boolForKey:SPLimitResults]
&& ([limitRowsField intValue] > 1
- || tableValuesCount == [prefs integerForKey:SPLimitResultsValue]))
+ || tableRowsCount == [prefs integerForKey:SPLimitResultsValue]))
{
isLimited = YES;
} else {
@@ -540,6 +568,96 @@
[[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryHasBeenPerformed" object:self];
}
+/*
+ * Processes a supplied streaming result set, loading it into the data array.
+ */
+- (void)processResultIntoDataStorage:(MCPStreamingResult *)theResult approximateRowCount:(long)targetRowCount
+{
+ NSArray *tempRow;
+ NSMutableArray *newRow;
+ NSMutableArray *columnBlobStatuses = [[NSMutableArray alloc] init];
+ NSUInteger i;
+
+ float relativeTargetRowCount = 100.0/targetRowCount;
+ NSUInteger nextTableDisplayBoundary = 50;
+ BOOL tableViewRedrawn = NO;
+
+ long rowsProcessed = 0;
+
+ NSAutoreleasePool *dataLoadingPool;
+ NSProgressIndicator *dataLoadingIndicator = [tableDocumentInstance valueForKey:@"queryProgressBar"];
+ BOOL prefsLoadBlobsAsNeeded = [prefs boolForKey:SPLoadBlobsAsNeeded];
+
+ // Build up an array of which columns are blobs for faster iteration
+ for ( i = 0; i < tableColumnsCount ; i++ ) {
+ [columnBlobStatuses addObject:[NSNumber numberWithBool:[tableDataInstance columnIsBlobOrText:[NSArrayObjectAtIndex(dataColumns, i) objectForKey:@"name"] ]]];
+ }
+
+ // Set up an autorelease pool for row processing
+ dataLoadingPool = [[NSAutoreleasePool alloc] init];
+
+ // Loop through the result rows as they become available
+ while (tempRow = [theResult fetchNextRowAsArray]) {
+
+ if (rowsProcessed < previousTableRowsCount) {
+ NSMutableArrayReplaceObject(tableValues, rowsProcessed, [NSMutableArray arrayWithArray:tempRow]);
+ } else {
+ NSMutableArrayAddObject(tableValues, [NSMutableArray arrayWithArray:tempRow]);
+ }
+
+ // Alter the values for hidden blob and text fields if appropriate
+ if ( prefsLoadBlobsAsNeeded ) {
+ newRow = NSArrayObjectAtIndex(tableValues, rowsProcessed);
+ for ( i = 0 ; i < tableColumnsCount ; i++ ) {
+ if ( [NSArrayObjectAtIndex(columnBlobStatuses, i) boolValue] ) {
+ NSMutableArrayReplaceObject(newRow, i, [SPNotLoaded notLoaded]);
+ }
+ }
+ }
+ rowsProcessed++;
+
+ // Update the task interface as necessary
+ if (!isFiltered) {
+ if (rowsProcessed < targetRowCount) {
+ [tableDocumentInstance setTaskPercentage:(rowsProcessed*relativeTargetRowCount)];
+ } else if (rowsProcessed == targetRowCount) {
+ [tableDocumentInstance performSelectorOnMainThread:@selector(setTaskProgressToIndeterminate) withObject:nil waitUntilDone:NO];
+ }
+ }
+
+ // Update the table view with new results every now and then
+ if (rowsProcessed > nextTableDisplayBoundary) {
+ if (rowsProcessed > tableRowsCount) tableRowsCount = rowsProcessed;
+ [tableContentView performSelectorOnMainThread:@selector(noteNumberOfRowsChanged) withObject:nil waitUntilDone:NO];
+ if (!tableViewRedrawn) {
+ [tableContentView performSelectorOnMainThread:@selector(displayIfNeeded) withObject:nil waitUntilDone:NO];
+ tableViewRedrawn = YES;
+ }
+ nextTableDisplayBoundary *= 2;
+ }
+
+ // Drain and reset the autorelease pool every ~1024 rows
+ if (!(rowsProcessed % 1024)) {
+ [dataLoadingPool drain];
+ dataLoadingPool = [[NSAutoreleasePool alloc] init];
+ }
+ }
+ tableRowsCount = rowsProcessed;
+
+ // If the reloaded table is shorter than the previous table, remove the extra values from the storage
+ if (tableRowsCount < [tableValues count]) {
+ [tableValues removeObjectsInRange:NSMakeRange(tableRowsCount, [tableValues count] - tableRowsCount)];
+ }
+
+ [tableContentView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
+
+ // Clean up the autorelease pool and reset the progress indicator
+ [dataLoadingPool drain];
+ [dataLoadingIndicator setIndeterminate:YES];
+
+ [columnBlobStatuses release];
+}
+
/**
* Returns the query string for the current filter settings,
* ready to be dropped into a WHERE clause, or nil if no filtering
@@ -703,25 +821,25 @@
// If no filter or limit is active, show just the count of rows in the table
if (!isFiltered && !isLimited) {
- if (tableValuesCount == 1)
- [countString appendFormat:NSLocalizedString(@"%d row in table", @"text showing a single row in the result"), tableValuesCount];
+ if (tableRowsCount == 1)
+ [countString appendFormat:NSLocalizedString(@"%d row in table", @"text showing a single row in the result"), tableRowsCount];
else
- [countString appendFormat:NSLocalizedString(@"%d rows in table", @"text showing how many rows are in the result"), tableValuesCount];
+ [countString appendFormat:NSLocalizedString(@"%d rows in table", @"text showing how many rows are in the result"), tableRowsCount];
// If a limit is active, display a string suggesting a limit is active
} else if (!isFiltered && isLimited) {
- [countString appendFormat:NSLocalizedString(@"Rows %d-%d of %@%d from table", @"text showing how many rows are in the limited result"), [limitRowsField intValue], [limitRowsField intValue]+tableValuesCount-1, maxNumRowsIsEstimate?@"~":@"", maxNumRows];
+ [countString appendFormat:NSLocalizedString(@"Rows %d-%d of %@%d from table", @"text showing how many rows are in the limited result"), [limitRowsField intValue], [limitRowsField intValue]+tableRowsCount-1, maxNumRowsIsEstimate?@"~":@"", maxNumRows];
// If just a filter is active, show a count and an indication a filter is active
} else if (isFiltered && !isLimited) {
- if (tableValuesCount == 1)
- [countString appendFormat:NSLocalizedString(@"%d row of %@%d matches filter", @"text showing how a single rows matched filter"), tableValuesCount, maxNumRowsIsEstimate?@"~":@"", maxNumRows];
+ if (tableRowsCount == 1)
+ [countString appendFormat:NSLocalizedString(@"%d row of %@%d matches filter", @"text showing how a single rows matched filter"), tableRowsCount, maxNumRowsIsEstimate?@"~":@"", maxNumRows];
else
- [countString appendFormat:NSLocalizedString(@"%d rows of %@%d match filter", @"text showing how many rows matched filter"), tableValuesCount, maxNumRowsIsEstimate?@"~":@"", maxNumRows];
+ [countString appendFormat:NSLocalizedString(@"%d rows of %@%d match filter", @"text showing how many rows matched filter"), tableRowsCount, maxNumRowsIsEstimate?@"~":@"", maxNumRows];
// If both a filter and limit is active, display full string
} else {
- [countString appendFormat:NSLocalizedString(@"Rows %d-%d from filtered matches", @"text showing how many rows are in the limited filter match"), [limitRowsField intValue], [limitRowsField intValue]+tableValuesCount-1];
+ [countString appendFormat:NSLocalizedString(@"Rows %d-%d from filtered matches", @"text showing how many rows are in the limited filter match"), [limitRowsField intValue], [limitRowsField intValue]+tableRowsCount-1];
}
// If rows are selected, append selection count
@@ -741,10 +859,18 @@
#pragma mark Table interface actions
/*
- * Reloads the current table data, performing a new SQL query. Now attempts to preserve sort order, filters, and viewport.
+ * Reloads the current table data, performing a new SQL query. Now attempts to preserve sort
+ * order, filters, and viewport. Performs the action in a new thread.
*/
- (IBAction)reloadTable:(id)sender
{
+ [tableDocumentInstance startTaskWithDescription:NSLocalizedString(@"Reloading data...", @"Reloading data task description")];
+ [NSThread detachNewThreadSelector:@selector(reloadTableTask) toTarget:self withObject:nil];
+}
+- (void)reloadTableTask
+{
+ NSAutoreleasePool *reloadPool = [[NSAutoreleasePool alloc] init];
+
// Check whether a save of the current row is required.
if (![self saveRowOnDeselect]) return;
@@ -756,14 +882,24 @@
// Load the table's data
[self loadTable:selectedTable];
+
+ [tableDocumentInstance endTask];
+ [reloadPool drain];
}
/*
- * Filter the table with arguments given by the user
+ * Filter the table with arguments given by the user.
+ * Performs the action in a new thread.
*/
- (IBAction)filterTable:(id)sender
{
if ([tableDocumentInstance isWorking]) return;
+ [tableDocumentInstance startTaskWithDescription:NSLocalizedString(@"Filtering table...", @"Filtering table task description")];
+ [NSThread detachNewThreadSelector:@selector(filterTableTask) toTarget:self withObject:nil];
+}
+- (void)filterTableTask
+{
+ NSAutoreleasePool *filterPool = [[NSAutoreleasePool alloc] init];
// Check whether a save of the current row is required.
if (![self saveRowOnDeselect]) return;
@@ -782,9 +918,15 @@
[limitRowsField setStringValue:[[NSNumber numberWithInt:(newLimit<1)?1:newLimit] stringValue]];
}
- // Reload data using the new filter settings
+ // Reset and reload data using the new filter settings
+ previousTableRowsCount = 0;
+ tableRowsCount = 0;
+ [tableValues removeAllObjects];
[self loadTableValues];
[tableContentView scrollPoint:NSMakePoint(0.0, 0.0)];
+
+ [tableDocumentInstance endTask];
+ [filterPool drain];
}
/**
@@ -876,7 +1018,7 @@
}
}
[tableValues addObject:newRow];
- tableValuesCount++;
+ tableRowsCount++;
[tableContentView reloadData];
[tableContentView selectRowIndexes:[NSIndexSet indexSetWithIndex:[tableContentView numberOfRows]-1] byExtendingSelection:NO];
@@ -911,7 +1053,7 @@
//copy row
tempRow = [NSMutableArray arrayWithArray:[tableValues objectAtIndex:[tableContentView selectedRow]]];
[tableValues insertObject:tempRow atIndex:[tableContentView selectedRow]+1];
- tableValuesCount++;
+ tableRowsCount++;
//if we don't show blobs, read data for this duplicate column from db
if ([prefs boolForKey:SPLoadBlobsAsNeeded]) {
@@ -1331,95 +1473,6 @@
}
/*
- * Processes a supplied streaming result set, loading it into the data array.
- */
-- (void)processResultIntoDataStorage:(MCPStreamingResult *)theResult approximateRowCount:(long)targetRowCount
-{
- NSArray *tempRow;
- NSMutableArray *newRow;
- NSMutableArray *columnBlobStatuses = [[NSMutableArray alloc] init];
- NSUInteger i;
-
- float relativeTargetRowCount = 100.0/targetRowCount;
- NSUInteger nextTableDisplayBoundary = 50;
- BOOL tableViewRedrawn = NO;
-
- long rowsProcessed = 0;
- long columnsCount = [dataColumns count];
-
- NSAutoreleasePool *dataLoadingPool;
- NSProgressIndicator *dataLoadingIndicator = [tableDocumentInstance valueForKey:@"queryProgressBar"];
- BOOL prefsLoadBlobsAsNeeded = [prefs boolForKey:SPLoadBlobsAsNeeded];
-
- // Build up an array of which columns are blobs for faster iteration
- for ( i = 0; i < columnsCount ; i++ ) {
- [columnBlobStatuses addObject:[NSNumber numberWithBool:[tableDataInstance columnIsBlobOrText:[NSArrayObjectAtIndex(dataColumns, i) objectForKey:@"name"] ]]];
- }
-
- // Set up an autorelease pool for row processing
- dataLoadingPool = [[NSAutoreleasePool alloc] init];
-
- // Loop through the result rows as they become available
- while (tempRow = [theResult fetchNextRowAsArray]) {
-
- // Add values for hidden blob and text fields if appropriate
- if ( prefsLoadBlobsAsNeeded ) {
- NSMutableArrayAddObject(tableValues, [NSMutableArray arrayWithCapacity:columnsCount]);
- tableValuesCount++;
- newRow = NSArrayObjectAtIndex(tableValues, rowsProcessed);
- for ( i = 0 ; i < columnsCount ; i++ ) {
- if ( [NSArrayObjectAtIndex(columnBlobStatuses, i) boolValue] ) {
- [newRow addObject:[SPNotLoaded notLoaded]];
- } else {
- NSMutableArrayAddObject(newRow, NSArrayObjectAtIndex(tempRow, i));
- }
- }
-
- // Otherwise just add the new row
- } else {
- NSMutableArrayAddObject(tableValues, [NSMutableArray arrayWithArray:tempRow]);
- tableValuesCount++;
- }
-
- // Update the task interface as necessary
- rowsProcessed++;
- /*if (!isFiltered) {
- if (rowsProcessed < targetRowCount) {
- [tableDocumentInstance setTaskPercentage:(rowsProcessed*relativeTargetRowCount)];
- } else if (rowsProcessed == targetRowCount) {
- [tableDocumentInstance performSelectorOnMainThread:@selector(setTaskProgressToIndeterminate) withObject:nil waitUntilDone:NO];
- }
- }*/
-
- // Update the table view with new results every now and then
- if (rowsProcessed > nextTableDisplayBoundary) {
- [tableContentView performSelectorOnMainThread:@selector(noteNumberOfRowsChanged) withObject:nil waitUntilDone:NO];
- if (!tableViewRedrawn) {
- [tableContentView performSelectorOnMainThread:@selector(displayIfNeeded) withObject:nil waitUntilDone:NO];
- tableViewRedrawn = YES;
- }
- nextTableDisplayBoundary *= 2;
- }
-
- // Drain and reset the autorelease pool every ~1024 rows
- if (!(rowsProcessed % 1024)) {
- [dataLoadingPool drain];
- dataLoadingPool = [[NSAutoreleasePool alloc] init];
- }
- }
-
- [tableContentView performSelectorOnMainThread:@selector(noteNumberOfRowsChanged) withObject:nil waitUntilDone:NO];
- [tableContentView setNeedsDisplay:YES];
-
- // Clean up the autorelease pool and reset the progress indicator
- [dataLoadingPool drain];
- [dataLoadingIndicator setIndeterminate:YES];
-
- [columnBlobStatuses release];
-}
-
-
-/*
* Tries to write a new row to the database.
* Returns YES if row is written to database, otherwise NO; also returns YES if no row
* is being edited and nothing has to be written to the database.
@@ -1548,6 +1601,7 @@
if ( isEditingNewRow ) {
if ( [prefs boolForKey:SPReloadAfterAddingRow] ) {
[tableWindow endEditingFor:nil];
+ previousTableRowsCount = tableRowsCount;
[self loadTableValues];
} else {
@@ -1566,6 +1620,7 @@
// Reload table if set to - otherwise no action required.
if ( [prefs boolForKey:SPReloadAfterEditingRow] ) {
[tableWindow endEditingFor:nil];
+ previousTableRowsCount = tableRowsCount;
[self loadTableValues];
}
}
@@ -1774,7 +1829,7 @@
withObject:[NSMutableArray arrayWithArray:oldRow]];
isEditingRow = NO;
} else {
- tableValuesCount--;
+ tableRowsCount--;
[tableValues removeObjectAtIndex:[tableContentView selectedRow]];
isEditingRow = NO;
isEditingNewRow = NO;
@@ -1989,13 +2044,14 @@
// Refresh table content
if ( errors || reloadAfterRemovingRow ) {
+ previousTableRowsCount = tableRowsCount;
[self loadTableValues];
} else {
- for ( i = 0 ; i < tableValuesCount ; i++ ) {
+ for ( i = 0 ; i < tableRowsCount ; i++ ) {
if ( ![selectedRows containsIndex:i] )
[tempResult addObject:NSArrayObjectAtIndex(tableValues, i)];
}
- tableValuesCount = [tempResult count];
+ tableRowsCount = [tempResult count];
[tableValues setArray:tempResult];
[tableContentView reloadData];
}
@@ -2202,7 +2258,7 @@
// For unfiltered and non-limited tables, use the result count - and update the status count
if (!isLimited && !isFiltered) {
- maxNumRows = tableValuesCount;
+ maxNumRows = tableRowsCount;
maxNumRowsIsEstimate = NO;
[tableDataInstance setStatusValue:[NSString stringWithFormat:@"%d", maxNumRows] forKey:@"Rows"];
[tableDataInstance setStatusValue:@"y" forKey:@"RowsCountAccurate"];
@@ -2235,7 +2291,7 @@
if (checkStatusCount) {
NSInteger foundMaxRows;
if ([prefs boolForKey:SPLimitResults]) {
- foundMaxRows = [limitRowsField intValue] - 1 + tableValuesCount;
+ foundMaxRows = [limitRowsField intValue] - 1 + tableRowsCount;
if (foundMaxRows > maxNumRows) {
if (foundMaxRows == [limitRowsField intValue] - 1 + [prefs integerForKey:SPLimitResultsValue]) {
maxNumRows = foundMaxRows + 1;
@@ -2245,8 +2301,8 @@
maxNumRowsIsEstimate = NO;
}
}
- } else if (tableValuesCount > maxNumRows) {
- maxNumRows = tableValuesCount;
+ } else if (tableRowsCount > maxNumRows) {
+ maxNumRows = tableRowsCount;
maxNumRowsIsEstimate = YES;
}
[tableDataInstance setStatusValue:[NSString stringWithFormat:@"%d", maxNumRows] forKey:@"Rows"];
@@ -2310,21 +2366,26 @@
- (int)numberOfRowsInTableView:(NSTableView *)aTableView
{
- return tableValuesCount;
+ return tableRowsCount;
}
- (id)tableView:(CMCopyTable *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
{
- if (rowIndex >= tableValuesCount) return nil;
- id theValue = NSArrayObjectAtIndex(NSArrayObjectAtIndex(tableValues, rowIndex), [[aTableColumn identifier] intValue]);
+ // In some loading situations, where the table is being redrawn while a load operation is in process on a background
+ // thread, an index higher than the available rows/columns may be requested. Return "..." to indicate loading in these
+ // cases - when the load completes all table data will be redrawn.
+ int columnIndex = [[aTableColumn identifier] intValue];
+ if (rowIndex >= tableRowsCount || columnIndex >= tableColumnsCount) return @"...";
- if ([theValue isKindOfClass:[NSData class]])
- return [theValue shortStringRepresentationUsingEncoding:[mySQLConnection encoding]];
+ id theValue = NSArrayObjectAtIndex(NSArrayObjectAtIndex(tableValues, rowIndex), columnIndex);
if ([theValue isNSNull])
return [prefs objectForKey:SPNullValue];
+ if ([theValue isKindOfClass:[NSData class]])
+ return [theValue shortStringRepresentationUsingEncoding:[mySQLConnection encoding]];
+
if ([theValue isSPNotLoaded])
return NSLocalizedString(@"(not loaded)", @"value shown for hidden blob and text fields");
@@ -2334,21 +2395,32 @@
/**
* This function changes the text color of text/blob fields which are null or not yet loaded to gray
*/
-- (void)tableView:(CMCopyTable *)aTableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn*)aTableColumn row:(int)row
+- (void)tableView:(CMCopyTable *)aTableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn*)aTableColumn row:(int)rowIndex
{
-
- if (row >= tableValuesCount) return;
if (![cell respondsToSelector:@selector(setTextColor:)]) return;
+ // In some loading situations, where the table is being redrawn while a load operation is in process on a background
+ // thread, an index higher than the available rows/columns may be requested. Return gray to indicate loading in these
+ // cases - when the load completes all table data will be redrawn.
+ int columnIndex = [[aTableColumn identifier] intValue];
+ if (rowIndex >= tableRowsCount || columnIndex >= tableColumnsCount) {
+ [cell setTextColor:[NSColor lightGrayColor]];
+ return;
+ }
+
+ id theValue = NSArrayObjectAtIndex(NSArrayObjectAtIndex(tableValues, rowIndex), columnIndex);
+ if (!theValue) {
+ [cell setTextColor:[NSColor lightGrayColor]];
+ return;
+ }
+
// If user wants to edit 'cell' set text color to black and return to avoid
// writing in gray if value was NULL
- if ( [aTableView editedColumn] == [[aTableColumn identifier] intValue] && [aTableView editedRow] == row) {
+ if ( [aTableView editedColumn] == [[aTableColumn identifier] intValue] && [aTableView editedRow] == rowIndex) {
[cell setTextColor:[NSColor blackColor]];
return;
}
- id theValue = NSArrayObjectAtIndex(NSArrayObjectAtIndex(tableValues, row), [[aTableColumn identifier] intValue]);
-
// For null cells and not loaded cells, display the contents in gray.
if ([theValue isNSNull] || [theValue isSPNotLoaded]) {
[cell setTextColor:[NSColor lightGrayColor]];
@@ -2386,29 +2458,37 @@
#pragma mark -
#pragma mark TableView delegate methods
-- (void)tableView:(NSTableView*)tableView didClickTableColumn:(NSTableColumn *)tableColumn
-/*
- sorts the tableView by the clicked column
- if clicked twice, order is descending
+/**
+ * Sorts the tableView by the clicked column.
+ * If clicked twice, order is altered to descending.
+ * Performs the task in a new thread.
*/
+- (void)tableView:(NSTableView*)tableView didClickTableColumn:(NSTableColumn *)tableColumn
{
if ( [selectedTable isEqualToString:@""] || !selectedTable )
return;
- // Check whether a save of the current row is required.
- if ( ![self saveRowOnDeselect] ) return;
-
// Prevent sorting while the table is still loading
if ([tableDocumentInstance isWorking]) return;
-
- //sets order descending if a header is clicked twice
- if ( [[tableColumn identifier] isEqualTo:sortCol] ) {
- if ( isDesc ) {
- isDesc = NO;
- } else {
- isDesc = YES;
- }
+
+ // Start the task
+ [tableDocumentInstance startTaskWithDescription:NSLocalizedString(@"Sorting table...", @"Sorting table task description")];
+ [NSThread detachNewThreadSelector:@selector(sortTableTaskWithColumn:) toTarget:self withObject:tableColumn];
+}
+- (void)sortTableTaskWithColumn:(NSTableColumn *)tableColumn
+{
+ NSAutoreleasePool *sortPool = [[NSAutoreleasePool alloc] init];
+
+ // Check whether a save of the current row is required.
+ if (![self saveRowOnDeselect]) {
+ [sortPool drain];
+ return;
+ }
+
+ // Sets order descending if a header is clicked twice
+ if ([[tableColumn identifier] isEqualTo:sortCol]) {
+ isDesc = !isDesc;
} else {
isDesc = NO;
[tableContentView setIndicatorImage:nil inTableColumn:[tableContentView tableColumnWithIdentifier:sortCol]];
@@ -2417,21 +2497,26 @@
sortCol = [[NSNumber alloc] initWithInt:[[tableColumn identifier] intValue]];
// Update data using the new sort order
+ previousTableRowsCount = tableRowsCount;
[self loadTableValues];
if ( ![[mySQLConnection getLastErrorMessage] isEqualToString:@""] ) {
NSBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil, nil, nil,
[NSString stringWithFormat:NSLocalizedString(@"Couldn't sort table. MySQL said: %@", @"message of panel when sorting of table failed"), [mySQLConnection getLastErrorMessage]]);
+ [sortPool drain];
return;
}
-
- //sets highlight and indicatorImage
+
+ // Set the highlight and indicatorImage
[tableContentView setHighlightedTableColumn:tableColumn];
- if ( isDesc ) {
+ if (isDesc) {
[tableContentView setIndicatorImage:[NSImage imageNamed:@"NSDescendingSortIndicator"] inTableColumn:tableColumn];
} else {
[tableContentView setIndicatorImage:[NSImage imageNamed:@"NSAscendingSortIndicator"] inTableColumn:tableColumn];
}
+
+ [tableDocumentInstance endTask];
+ [sortPool drain];
}
- (void)tableViewSelectionDidChange:(NSNotification *)aNotification
@@ -2635,10 +2720,8 @@
- (void) startDocumentTaskForTab:(NSNotification *)aNotification
{
- // Only proceed if the current document is the notifying document, and only if
- // this view is selected.
- if ([aNotification object] != tableDocumentInstance
- || ![[[aNotification object] selectedToolbarItemIdentifier] isEqualToString:MAIN_TOOLBAR_TABLE_CONTENT])
+ // Only proceed if this view is selected.
+ if (![[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:MAIN_TOOLBAR_TABLE_CONTENT])
return;
[addButton setEnabled:NO];
@@ -2654,10 +2737,8 @@
- (void) endDocumentTaskForTab:(NSNotification *)aNotification
{
- // Only proceed if the current document is the notifying document, and only if
- // this view is selected.
- if ([aNotification object] != tableDocumentInstance
- || ![[[aNotification object] selectedToolbarItemIdentifier] isEqualToString:MAIN_TOOLBAR_TABLE_CONTENT])
+ // Only proceed if this view is selected.
+ if (![[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:MAIN_TOOLBAR_TABLE_CONTENT])
return;
if ( ![[[tableDataInstance statusValues] objectForKey:@"Rows"] isNSNull] && selectedTable && [selectedTable length] && [tableDataInstance tableEncoding]) [addButton setEnabled:YES];
@@ -2729,7 +2810,7 @@
} else if ( isEditingNewRow ) {
isEditingRow = NO;
isEditingNewRow = NO;
- tableValuesCount--;
+ tableRowsCount--;
[tableValues removeObjectAtIndex:row];
[tableContentView reloadData];
}
diff --git a/Source/TableSource.m b/Source/TableSource.m
index f5900bc5..2111a498 100644
--- a/Source/TableSource.m
+++ b/Source/TableSource.m
@@ -47,7 +47,7 @@ loads aTable, put it in an array, update the tableViewColumns and reload the tab
id extra;
int i;
SPSQLParser *fieldParser;
- BOOL enableInteraction = ![tableDocumentInstance isWorking];
+ BOOL enableInteraction = ![[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:MAIN_TOOLBAR_TABLE_STRUCTURE] || ![tableDocumentInstance isWorking];
// Check whether a save of the current row is required.
if ( ![self saveRowOnDeselect] ) return;
@@ -1057,10 +1057,8 @@ returns a dictionary containing enum/set field names as key and possible values
- (void) startDocumentTaskForTab:(NSNotification *)aNotification
{
- // Only proceed if the current document is the notifying document, and only if
- // this view is selected.
- if ([aNotification object] != tableDocumentInstance
- || ![[[aNotification object] selectedToolbarItemIdentifier] isEqualToString:MAIN_TOOLBAR_TABLE_STRUCTURE])
+ // Only proceed if this view is selected.
+ if (![[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:MAIN_TOOLBAR_TABLE_STRUCTURE])
return;
[tableSourceView setEnabled:NO];
@@ -1083,8 +1081,7 @@ returns a dictionary containing enum/set field names as key and possible values
{
// Only re-enable elements if the current tab is the structure view
- if ([aNotification object] != tableDocumentInstance
- || ![[[aNotification object] selectedToolbarItemIdentifier] isEqualToString:MAIN_TOOLBAR_TABLE_STRUCTURE])
+ if (![[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:MAIN_TOOLBAR_TABLE_STRUCTURE])
return;
BOOL editingEnabled = ([tablesListInstance tableType] == SP_TABLETYPE_TABLE);
@@ -1471,11 +1468,11 @@ would result in a position change.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(startDocumentTaskForTab:)
name:SPDocumentTaskStartNotification
- object:nil];
+ object:tableDocumentInstance];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(endDocumentTaskForTab:)
name:SPDocumentTaskEndNotification
- object:nil];
+ object:tableDocumentInstance];
}
- (void)dealloc
diff --git a/Source/TablesList.h b/Source/TablesList.h
index d0349531..e32ec789 100644
--- a/Source/TablesList.h
+++ b/Source/TablesList.h
@@ -122,7 +122,8 @@ enum sp_table_types
// Additional methods
- (void)setConnection:(MCPConnection *)theConnection;
- (void)doPerformQueryService:(NSString *)query;
-- (void)updateSelection;
+- (void)updateSelectionWithTaskString:(NSString *)taskString;
+- (void)updateSelectionTask;
- (void)selectTableAtIndex:(NSNumber *)row;
// Getters
diff --git a/Source/TablesList.m b/Source/TablesList.m
index bb5f80ec..9264b9f1 100644
--- a/Source/TablesList.m
+++ b/Source/TablesList.m
@@ -600,209 +600,11 @@
* Updates the current table selection. Triggered most times tableViewSelectionDidChange:
* fires, and also as a result of certain table actions.
*/
-- (void)updateSelection
+- (void)updateSelectionWithTaskString:(NSString *)taskString
{
- if ( [tablesListView numberOfSelectedRows] == 1 && [[filteredTables objectAtIndex:[tablesListView selectedRow]] length] ) {
- // 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];
-
- // Remove the "current selection" item for filtered lists if appropriate
- if (isTableListFiltered && [tablesListView selectedRow] < [filteredTables count] - 2 && [filteredTables count] > 2
- && [[filteredTableTypes objectAtIndex:[filteredTableTypes count]-2] intValue] == SP_TABLETYPE_NONE
- && [[filteredTables objectAtIndex:[filteredTables count]-2] isEqualToString:NSLocalizedString(@"CURRENT SELECTION",@"header for current selection in filtered list")])
- {
- [filteredTables removeObjectsInRange:NSMakeRange([filteredTables count]-2, 2)];
- [filteredTableTypes removeObjectsInRange:NSMakeRange([filteredTableTypes count]-2, 2)];
- [tablesListView reloadData];
- }
-
- // Reset the table information caches
- [tableDataInstance resetAllData];
-
- [separatorTableMenuItem setHidden:NO];
- [separatorTableContextMenuItem setHidden:NO];
-
- if( selectedTableType == SP_TABLETYPE_VIEW || selectedTableType == SP_TABLETYPE_TABLE) {
-
- // tableEncoding == nil indicates that there was an error while retrieving table data
- NSString *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];
- }
- }
-
- 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 loadTable:selectedTableName];
- 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 loadTable:nil];
- 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];
-
- if(selectedTableType == SP_TABLETYPE_VIEW)
- {
- // Change mainMenu > Table > ... according to table type
- [[tableSubMenu itemAtIndex:0] setTitle:NSLocalizedString(@"Copy Create View Syntax", @"copy create view syntax menu item")];
- [[tableSubMenu itemAtIndex:1] setTitle:NSLocalizedString(@"Show Create View Syntax", @"show create view syntax menu item")];
- [[tableSubMenu itemAtIndex:2] setHidden:NO]; // divider
- [[tableSubMenu itemAtIndex:3] setHidden:NO];
- [[tableSubMenu itemAtIndex:3] setTitle:NSLocalizedString(@"Check View", @"check view menu item")];
- [[tableSubMenu itemAtIndex:4] setHidden:YES]; // repair
- [[tableSubMenu itemAtIndex:5] setHidden:YES]; // divider
- [[tableSubMenu itemAtIndex:6] setHidden:YES]; // analyse
- [[tableSubMenu itemAtIndex:7] setHidden:YES]; // optimize
- [[tableSubMenu itemAtIndex:8] setHidden:NO];
- [[tableSubMenu itemAtIndex:8] setTitle:NSLocalizedString(@"Flush View", @"flush view menu item")];
- [[tableSubMenu itemAtIndex:9] setHidden:YES]; // checksum
-
- [renameTableMenuItem setHidden:NO]; // we don't have to check the mysql version
- [renameTableMenuItem setTitle:NSLocalizedString(@"Rename View...", @"rename view menu title")];
- [duplicateTableMenuItem setHidden:NO];
- [duplicateTableMenuItem setTitle:NSLocalizedString(@"Duplicate View...", @"duplicate view menu title")];
- [truncateTableButton setHidden:YES];
- [removeTableMenuItem setTitle:NSLocalizedString(@"Remove View", @"remove view menu title")];
-
- [renameTableContextMenuItem setHidden:NO]; // we don't have to check the mysql version
- [renameTableContextMenuItem setTitle:NSLocalizedString(@"Rename View...", @"rename view menu title")];
- [duplicateTableContextMenuItem setHidden:NO];
- [duplicateTableContextMenuItem setTitle:NSLocalizedString(@"Duplicate View...", @"duplicate view menu title")];
- [truncateTableContextButton setHidden:YES];
- [removeTableContextMenuItem setTitle:NSLocalizedString(@"Remove View", @"remove view menu title")];
- }
- else if(selectedTableType == SP_TABLETYPE_TABLE) {
- [[tableSubMenu itemAtIndex:0] setTitle:NSLocalizedString(@"Copy Create Table Syntax", @"copy create table syntax menu item")];
- [[tableSubMenu itemAtIndex:1] setTitle:NSLocalizedString(@"Show Create Table Syntax", @"show create table syntax menu item")];
- [[tableSubMenu itemAtIndex:2] setHidden:NO]; // divider
- [[tableSubMenu itemAtIndex:3] setHidden:NO];
- [[tableSubMenu itemAtIndex:3] setTitle:NSLocalizedString(@"Check Table", @"check table menu item")];
- [[tableSubMenu itemAtIndex:4] setHidden:NO];
- [[tableSubMenu itemAtIndex:5] setHidden:NO]; // divider
- [[tableSubMenu itemAtIndex:6] setHidden:NO];
- [[tableSubMenu itemAtIndex:7] setHidden:NO];
- [[tableSubMenu itemAtIndex:8] setHidden:NO];
- [[tableSubMenu itemAtIndex:8] setTitle:NSLocalizedString(@"Flush Table", @"flush table menu item")];
- [[tableSubMenu itemAtIndex:9] setHidden:NO];
-
- [renameTableMenuItem setHidden:NO];
- [renameTableMenuItem setTitle:NSLocalizedString(@"Rename Table...", @"rename table menu title")];
- [duplicateTableMenuItem setHidden:NO];
- [duplicateTableMenuItem setTitle:NSLocalizedString(@"Duplicate Table...", @"duplicate table menu title")];
- [truncateTableButton setHidden:NO];
- [truncateTableButton setTitle:NSLocalizedString(@"Truncate Table", @"truncate table menu title")];
- [removeTableMenuItem setTitle:NSLocalizedString(@"Remove Table", @"remove table menu title")];
-
- [renameTableContextMenuItem setHidden:NO];
- [renameTableContextMenuItem setTitle:NSLocalizedString(@"Rename Table...", @"rename table menu title")];
- [duplicateTableContextMenuItem setHidden:NO];
- [duplicateTableContextMenuItem setTitle:NSLocalizedString(@"Duplicate Table...", @"duplicate table menu title")];
- [truncateTableContextButton setHidden:NO];
- [truncateTableContextButton setTitle:NSLocalizedString(@"Truncate Table", @"truncate table menu title")];
- [removeTableContextMenuItem setTitle:NSLocalizedString(@"Remove Table", @"remove table menu title")];
-
- }
- else if(selectedTableType == SP_TABLETYPE_PROC) {
- [[tableSubMenu itemAtIndex:0] setTitle:NSLocalizedString(@"Copy Create Procedure Syntax", @"copy create proc syntax menu item")];
- [[tableSubMenu itemAtIndex:1] setTitle:NSLocalizedString(@"Show Create Procedure Syntax", @"show create proc syntax menu item")];
- [[tableSubMenu itemAtIndex:2] setHidden:YES]; // divider
- [[tableSubMenu itemAtIndex:3] setHidden:YES]; // copy columns
- [[tableSubMenu itemAtIndex:4] setHidden:YES]; // divider
- [[tableSubMenu itemAtIndex:5] setHidden:YES];
- [[tableSubMenu itemAtIndex:6] setHidden:YES];
- [[tableSubMenu itemAtIndex:7] setHidden:YES]; // divider
- [[tableSubMenu itemAtIndex:8] setHidden:YES];
- [[tableSubMenu itemAtIndex:9] setHidden:YES];
-
- [renameTableMenuItem setHidden:NO];
- [renameTableMenuItem setTitle:NSLocalizedString(@"Rename Procedure...", @"rename proc menu title")];
- [duplicateTableMenuItem setHidden:NO];
- [duplicateTableMenuItem setTitle:NSLocalizedString(@"Duplicate Procedure...", @"duplicate proc menu title")];
- [truncateTableButton setHidden:YES];
- [removeTableMenuItem setTitle:NSLocalizedString(@"Remove Procedure", @"remove proc menu title")];
-
- [renameTableContextMenuItem setHidden:NO];
- [renameTableContextMenuItem setTitle:NSLocalizedString(@"Rename Procedure...", @"rename proc menu title")];
- [duplicateTableContextMenuItem setHidden:NO];
- [duplicateTableContextMenuItem setTitle:NSLocalizedString(@"Duplicate Procedure...", @"duplicate proc menu title")];
- [truncateTableContextButton setHidden:YES];
- [removeTableContextMenuItem setTitle:NSLocalizedString(@"Remove Procedure", @"remove proc menu title")];
-
- }
- else if(selectedTableType == SP_TABLETYPE_FUNC) {
- [[tableSubMenu itemAtIndex:0] setTitle:NSLocalizedString(@"Copy Create Function Syntax", @"copy create func syntax menu item")];
- [[tableSubMenu itemAtIndex:1] setTitle:NSLocalizedString(@"Show Create Function Syntax", @"show create func syntax menu item")];
- [[tableSubMenu itemAtIndex:2] setHidden:YES]; // divider
- [[tableSubMenu itemAtIndex:3] setHidden:YES]; // copy columns
- [[tableSubMenu itemAtIndex:4] setHidden:YES]; // divider
- [[tableSubMenu itemAtIndex:5] setHidden:YES];
- [[tableSubMenu itemAtIndex:6] setHidden:YES];
- [[tableSubMenu itemAtIndex:7] setHidden:YES]; // divider
- [[tableSubMenu itemAtIndex:8] setHidden:YES];
- [[tableSubMenu itemAtIndex:9] setHidden:YES];
-
- [renameTableMenuItem setHidden:NO];
- [renameTableMenuItem setTitle:NSLocalizedString(@"Rename Function...", @"rename func menu title")];
- [duplicateTableMenuItem setHidden:NO];
- [duplicateTableMenuItem setTitle:NSLocalizedString(@"Duplicate Function...", @"duplicate func menu title")];
- [truncateTableButton setHidden:YES];
- [removeTableMenuItem setTitle:NSLocalizedString(@"Remove Function", @"remove func menu title")];
-
- [renameTableContextMenuItem setHidden:NO];
- [renameTableContextMenuItem setTitle:NSLocalizedString(@"Rename Function...", @"rename func menu title")];
- [duplicateTableContextMenuItem setHidden:NO];
- [duplicateTableContextMenuItem setTitle:NSLocalizedString(@"Duplicate Function...", @"duplicate func menu title")];
- [truncateTableContextButton setHidden:YES];
- [removeTableContextMenuItem setTitle:NSLocalizedString(@"Remove Function", @"remove func menu title")];
-
- }
-
- // 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];
-
- } else {
+ // If there is a multiple or blank selection, clear all views directly.
+ if ( [tablesListView numberOfSelectedRows] != 1 || ![[filteredTables objectAtIndex:[tablesListView selectedRow]] length] ) {
NSIndexSet *indexes = [tablesListView selectedRowIndexes];
// Update the selected table name and type
@@ -885,10 +687,232 @@
// 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 and fire up a thread to deal with view changes and data loading
+ [tableDocumentInstance startTaskWithDescription:taskString];
+ [NSThread detachNewThreadSelector:@selector(updateSelectionTask) toTarget:self withObject:nil];
+}
+
+- (void) updateSelectionTask
+{
+ NSAutoreleasePool *selectionChangePool = [[NSAutoreleasePool alloc] init];
+
+ // 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];
+
+ // Remove the "current selection" item for filtered lists if appropriate
+ if (isTableListFiltered && [tablesListView selectedRow] < [filteredTables count] - 2 && [filteredTables count] > 2
+ && [[filteredTableTypes objectAtIndex:[filteredTableTypes count]-2] intValue] == SP_TABLETYPE_NONE
+ && [[filteredTables objectAtIndex:[filteredTables count]-2] isEqualToString:NSLocalizedString(@"CURRENT SELECTION",@"header for current selection in filtered list")])
+ {
+ [filteredTables removeObjectsInRange:NSMakeRange([filteredTables count]-2, 2)];
+ [filteredTableTypes removeObjectsInRange:NSMakeRange([filteredTableTypes count]-2, 2)];
+ [tablesListView reloadData];
+ }
+
+ // Reset the table information caches
+ [tableDataInstance resetAllData];
+
+ [separatorTableMenuItem setHidden:NO];
+ [separatorTableContextMenuItem setHidden:NO];
+
+ if( selectedTableType == SP_TABLETYPE_VIEW || selectedTableType == SP_TABLETYPE_TABLE) {
+
+ // tableEncoding == nil indicates that there was an error while retrieving table data
+ NSString *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];
+ }
+ }
+
+ 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 loadTable:selectedTableName];
+ 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 loadTable:nil];
+ 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];
+
+ if(selectedTableType == SP_TABLETYPE_VIEW)
+ {
+ // Change mainMenu > Table > ... according to table type
+ [[tableSubMenu itemAtIndex:0] setTitle:NSLocalizedString(@"Copy Create View Syntax", @"copy create view syntax menu item")];
+ [[tableSubMenu itemAtIndex:1] setTitle:NSLocalizedString(@"Show Create View Syntax", @"show create view syntax menu item")];
+ [[tableSubMenu itemAtIndex:2] setHidden:NO]; // divider
+ [[tableSubMenu itemAtIndex:3] setHidden:NO];
+ [[tableSubMenu itemAtIndex:3] setTitle:NSLocalizedString(@"Check View", @"check view menu item")];
+ [[tableSubMenu itemAtIndex:4] setHidden:YES]; // repair
+ [[tableSubMenu itemAtIndex:5] setHidden:YES]; // divider
+ [[tableSubMenu itemAtIndex:6] setHidden:YES]; // analyse
+ [[tableSubMenu itemAtIndex:7] setHidden:YES]; // optimize
+ [[tableSubMenu itemAtIndex:8] setHidden:NO];
+ [[tableSubMenu itemAtIndex:8] setTitle:NSLocalizedString(@"Flush View", @"flush view menu item")];
+ [[tableSubMenu itemAtIndex:9] setHidden:YES]; // checksum
+
+ [renameTableMenuItem setHidden:NO]; // we don't have to check the mysql version
+ [renameTableMenuItem setTitle:NSLocalizedString(@"Rename View...", @"rename view menu title")];
+ [duplicateTableMenuItem setHidden:NO];
+ [duplicateTableMenuItem setTitle:NSLocalizedString(@"Duplicate View...", @"duplicate view menu title")];
+ [truncateTableButton setHidden:YES];
+ [removeTableMenuItem setTitle:NSLocalizedString(@"Remove View", @"remove view menu title")];
+
+ [renameTableContextMenuItem setHidden:NO]; // we don't have to check the mysql version
+ [renameTableContextMenuItem setTitle:NSLocalizedString(@"Rename View...", @"rename view menu title")];
+ [duplicateTableContextMenuItem setHidden:NO];
+ [duplicateTableContextMenuItem setTitle:NSLocalizedString(@"Duplicate View...", @"duplicate view menu title")];
+ [truncateTableContextButton setHidden:YES];
+ [removeTableContextMenuItem setTitle:NSLocalizedString(@"Remove View", @"remove view menu title")];
+ }
+ else if(selectedTableType == SP_TABLETYPE_TABLE) {
+ [[tableSubMenu itemAtIndex:0] setTitle:NSLocalizedString(@"Copy Create Table Syntax", @"copy create table syntax menu item")];
+ [[tableSubMenu itemAtIndex:1] setTitle:NSLocalizedString(@"Show Create Table Syntax", @"show create table syntax menu item")];
+ [[tableSubMenu itemAtIndex:2] setHidden:NO]; // divider
+ [[tableSubMenu itemAtIndex:3] setHidden:NO];
+ [[tableSubMenu itemAtIndex:3] setTitle:NSLocalizedString(@"Check Table", @"check table menu item")];
+ [[tableSubMenu itemAtIndex:4] setHidden:NO];
+ [[tableSubMenu itemAtIndex:5] setHidden:NO]; // divider
+ [[tableSubMenu itemAtIndex:6] setHidden:NO];
+ [[tableSubMenu itemAtIndex:7] setHidden:NO];
+ [[tableSubMenu itemAtIndex:8] setHidden:NO];
+ [[tableSubMenu itemAtIndex:8] setTitle:NSLocalizedString(@"Flush Table", @"flush table menu item")];
+ [[tableSubMenu itemAtIndex:9] setHidden:NO];
+
+ [renameTableMenuItem setHidden:NO];
+ [renameTableMenuItem setTitle:NSLocalizedString(@"Rename Table...", @"rename table menu title")];
+ [duplicateTableMenuItem setHidden:NO];
+ [duplicateTableMenuItem setTitle:NSLocalizedString(@"Duplicate Table...", @"duplicate table menu title")];
+ [truncateTableButton setHidden:NO];
+ [truncateTableButton setTitle:NSLocalizedString(@"Truncate Table", @"truncate table menu title")];
+ [removeTableMenuItem setTitle:NSLocalizedString(@"Remove Table", @"remove table menu title")];
+
+ [renameTableContextMenuItem setHidden:NO];
+ [renameTableContextMenuItem setTitle:NSLocalizedString(@"Rename Table...", @"rename table menu title")];
+ [duplicateTableContextMenuItem setHidden:NO];
+ [duplicateTableContextMenuItem setTitle:NSLocalizedString(@"Duplicate Table...", @"duplicate table menu title")];
+ [truncateTableContextButton setHidden:NO];
+ [truncateTableContextButton setTitle:NSLocalizedString(@"Truncate Table", @"truncate table menu title")];
+ [removeTableContextMenuItem setTitle:NSLocalizedString(@"Remove Table", @"remove table menu title")];
+
+ }
+ else if(selectedTableType == SP_TABLETYPE_PROC) {
+ [[tableSubMenu itemAtIndex:0] setTitle:NSLocalizedString(@"Copy Create Procedure Syntax", @"copy create proc syntax menu item")];
+ [[tableSubMenu itemAtIndex:1] setTitle:NSLocalizedString(@"Show Create Procedure Syntax", @"show create proc syntax menu item")];
+ [[tableSubMenu itemAtIndex:2] setHidden:YES]; // divider
+ [[tableSubMenu itemAtIndex:3] setHidden:YES]; // copy columns
+ [[tableSubMenu itemAtIndex:4] setHidden:YES]; // divider
+ [[tableSubMenu itemAtIndex:5] setHidden:YES];
+ [[tableSubMenu itemAtIndex:6] setHidden:YES];
+ [[tableSubMenu itemAtIndex:7] setHidden:YES]; // divider
+ [[tableSubMenu itemAtIndex:8] setHidden:YES];
+ [[tableSubMenu itemAtIndex:9] setHidden:YES];
+
+ [renameTableMenuItem setHidden:NO];
+ [renameTableMenuItem setTitle:NSLocalizedString(@"Rename Procedure...", @"rename proc menu title")];
+ [duplicateTableMenuItem setHidden:NO];
+ [duplicateTableMenuItem setTitle:NSLocalizedString(@"Duplicate Procedure...", @"duplicate proc menu title")];
+ [truncateTableButton setHidden:YES];
+ [removeTableMenuItem setTitle:NSLocalizedString(@"Remove Procedure", @"remove proc menu title")];
+
+ [renameTableContextMenuItem setHidden:NO];
+ [renameTableContextMenuItem setTitle:NSLocalizedString(@"Rename Procedure...", @"rename proc menu title")];
+ [duplicateTableContextMenuItem setHidden:NO];
+ [duplicateTableContextMenuItem setTitle:NSLocalizedString(@"Duplicate Procedure...", @"duplicate proc menu title")];
+ [truncateTableContextButton setHidden:YES];
+ [removeTableContextMenuItem setTitle:NSLocalizedString(@"Remove Procedure", @"remove proc menu title")];
+
+ }
+ else if(selectedTableType == SP_TABLETYPE_FUNC) {
+ [[tableSubMenu itemAtIndex:0] setTitle:NSLocalizedString(@"Copy Create Function Syntax", @"copy create func syntax menu item")];
+ [[tableSubMenu itemAtIndex:1] setTitle:NSLocalizedString(@"Show Create Function Syntax", @"show create func syntax menu item")];
+ [[tableSubMenu itemAtIndex:2] setHidden:YES]; // divider
+ [[tableSubMenu itemAtIndex:3] setHidden:YES]; // copy columns
+ [[tableSubMenu itemAtIndex:4] setHidden:YES]; // divider
+ [[tableSubMenu itemAtIndex:5] setHidden:YES];
+ [[tableSubMenu itemAtIndex:6] setHidden:YES];
+ [[tableSubMenu itemAtIndex:7] setHidden:YES]; // divider
+ [[tableSubMenu itemAtIndex:8] setHidden:YES];
+ [[tableSubMenu itemAtIndex:9] setHidden:YES];
+
+ [renameTableMenuItem setHidden:NO];
+ [renameTableMenuItem setTitle:NSLocalizedString(@"Rename Function...", @"rename func menu title")];
+ [duplicateTableMenuItem setHidden:NO];
+ [duplicateTableMenuItem setTitle:NSLocalizedString(@"Duplicate Function...", @"duplicate func menu title")];
+ [truncateTableButton setHidden:YES];
+ [removeTableMenuItem setTitle:NSLocalizedString(@"Remove Function", @"remove func menu title")];
+
+ [renameTableContextMenuItem setHidden:NO];
+ [renameTableContextMenuItem setTitle:NSLocalizedString(@"Rename Function...", @"rename func menu title")];
+ [duplicateTableContextMenuItem setHidden:NO];
+ [duplicateTableContextMenuItem setTitle:NSLocalizedString(@"Duplicate Function...", @"duplicate func menu title")];
+ [truncateTableContextButton setHidden:YES];
+ [removeTableContextMenuItem setTitle:NSLocalizedString(@"Remove Function", @"remove func menu title")];
+
+ }
+
+ // 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];
+
+ // 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];
+ [selectionChangePool drain];
}
#pragma mark -
@@ -1082,7 +1106,7 @@
selectedTableName = [[NSString alloc] initWithString:[tables objectAtIndex:itemIndex]];
selectedTableType = [[tableTypes objectAtIndex:itemIndex] intValue];
[self updateFilter:self];
- [self updateSelection];
+ [self updateSelectionWithTaskString:[NSString stringWithFormat:NSLocalizedString(@"Loading %@...", @"Loading table task string"), theName]];
}
}
return YES;
@@ -1306,7 +1330,10 @@
// Save existing scroll position and details
[spHistoryControllerInstance updateHistoryEntries];
- [self updateSelection];
+ NSString *tableName = @"data";
+ if ([tablesListView numberOfSelectedRows] == 1 && [[filteredTables objectAtIndex:[tablesListView selectedRow]] length])
+ tableName = [filteredTables objectAtIndex:[tablesListView selectedRow]];
+ [self updateSelectionWithTaskString:[NSString stringWithFormat:NSLocalizedString(@"Loading %@...", @"Loading table task string"), tableName]];
}
/**
@@ -1557,10 +1584,6 @@
*/
- (void) startDocumentTaskForTab:(NSNotification *)aNotification
{
-
- // Only proceed if the notification was received from the current document.
- if ([aNotification object] != tableDocumentInstance) return;
-
[toolbarAddButton setEnabled:NO];
[toolbarActionsButton setEnabled:NO];
[toolbarReloadButton setEnabled:NO];
@@ -1571,8 +1594,6 @@
*/
- (void) endDocumentTaskForTab:(NSNotification *)aNotification
{
- if ([aNotification object] != tableDocumentInstance) return;
-
[toolbarAddButton setEnabled:YES];
[toolbarActionsButton setEnabled:YES];
[toolbarReloadButton setEnabled:YES];
@@ -1642,11 +1663,11 @@
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(startDocumentTaskForTab:)
name:SPDocumentTaskStartNotification
- object:nil];
+ object:tableDocumentInstance];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(endDocumentTaskForTab:)
name:SPDocumentTaskEndNotification
- object:nil];
+ object:tableDocumentInstance];
}
/**
@@ -1836,8 +1857,8 @@
selectedTableName = [[NSString alloc] initWithString:tableName];
selectedTableType = SP_TABLETYPE_TABLE;
[self updateFilter:self];
- [self updateSelection];
[tablesListView scrollRowToVisible:[tablesListView selectedRow]];
+ [self updateSelectionWithTaskString:[NSString stringWithFormat:NSLocalizedString(@"Loading %@...", @"Loading table task string"), selectedTableName]];
}
else {
// Error while creating new table
@@ -2028,8 +2049,8 @@
selectedTableName = [[NSString alloc] initWithString:[copyTableNameField stringValue]];
selectedTableType = tblType;
[self updateFilter:self];
- [self updateSelection];
[tablesListView scrollRowToVisible:[tablesListView selectedRow]];
+ [self updateSelectionWithTaskString:[NSString stringWithFormat:NSLocalizedString(@"Loading %@...", @"Loading table task string"), selectedTableName]];
}
}
}
@@ -2056,7 +2077,8 @@
if (selectedTableName) [selectedTableName release];
selectedTableName = [[NSString alloc] initWithString:[tableRenameField stringValue]];
[tablesListView reloadData];
- [self updateSelection];
+ [self updateSelectionWithTaskString:[NSString stringWithFormat:NSLocalizedString(@"Loading %@...", @"Loading table task string"), selectedTableName]];
+ return;
}
} else {
// procedures and functions can only be renamed if one creates the new one and delete the old one
@@ -2120,7 +2142,8 @@
if (selectedTableName) [selectedTableName release];
selectedTableName = [[NSString alloc] initWithString:[tableRenameField stringValue]];
[tablesListView reloadData];
- [self updateSelection];
+ [self updateSelectionWithTaskString:[NSString stringWithFormat:NSLocalizedString(@"Loading %@...", @"Loading table task string"), selectedTableName]];
+ return;
}
}