aboutsummaryrefslogtreecommitdiffstats
path: root/Source/TableDocument.m
diff options
context:
space:
mode:
Diffstat (limited to 'Source/TableDocument.m')
-rw-r--r--Source/TableDocument.m610
1 files changed, 370 insertions, 240 deletions
diff --git a/Source/TableDocument.m b/Source/TableDocument.m
index 385e9781..5d3209e5 100644
--- a/Source/TableDocument.m
+++ b/Source/TableDocument.m
@@ -73,6 +73,9 @@
@implementation TableDocument
+@synthesize parentWindowController;
+@synthesize parentTabViewItem;
+
- (id)init
{
@@ -92,6 +95,9 @@
mySQLVersion = nil;
allDatabases = nil;
allSystemDatabases = nil;
+ mainToolbar = nil;
+ parentWindow = nil;
+ isProcessing = NO;
printWebView = [[WebView alloc] init];
[printWebView setFrameLoadDelegate:self];
@@ -99,10 +105,12 @@
prefs = [NSUserDefaults standardUserDefaults];
queryEditorInitString = nil;
+ spfFileURL = nil;
spfSession = nil;
spfPreferences = [[NSMutableDictionary alloc] init];
spfDocData = [[NSMutableDictionary alloc] init];
+ titleAccessoryView = nil;
taskProgressWindow = nil;
taskDisplayIsIndeterminate = YES;
taskDisplayLastValue = 0;
@@ -117,6 +125,15 @@
keyChainID = nil;
statusValues = nil;
printThread = nil;
+ nibObjectsToRelease = [[NSMutableArray alloc] init];
+
+ // As this object is not an NSWindowController subclass, top-level objects in loaded nibs aren't
+ // automatically released. Keep track of the top-level objects for release on dealloc.
+ NSArray *dbViewTopLevelObjects = nil;
+ NSNib *nibLoader = [[NSNib alloc] initWithNibNamed:@"DBView" bundle:[NSBundle mainBundle]];
+ [nibLoader instantiateNibWithOwner:self topLevelObjects:&dbViewTopLevelObjects];
+ [nibLoader release];
+ [nibObjectsToRelease addObjectsFromArray:dbViewTopLevelObjects];
}
return self;
@@ -127,48 +144,6 @@
if (_mainNibLoaded) return;
_mainNibLoaded = YES;
- // The first window should use autosaving; subsequent windows should cascade
- BOOL usedAutosave = [tableWindow setFrameAutosaveName:[self windowNibName]];
- if (!usedAutosave) {
- [tableWindow setFrameUsingName:[self windowNibName]];
- NSArray *documents = [[NSDocumentController sharedDocumentController] documents];
- NSRect previousFrame = [[[documents objectAtIndex:(([documents count] > 1)?[documents count]-2:[documents count]-1)] valueForKey:@"tableWindow"] frame];
- NSPoint topLeftPoint = previousFrame.origin;
- topLeftPoint.y += previousFrame.size.height;
- [tableWindow setFrameTopLeftPoint:[tableWindow cascadeTopLeftFromPoint:topLeftPoint]];
-
- // Try to check if new frame fits into the screen
- NSRect screenFrame = [[NSScreen mainScreen] frame];
- NSScreen* candidate;
- for(candidate in [NSScreen screens])
- if(NSMinX([candidate frame]) < topLeftPoint.x && NSMinX([candidate frame]) > NSMinX(screenFrame))
- screenFrame = [candidate visibleFrame];
-
- previousFrame = [tableWindow frame];
-
- // Determine if move/resize is required
- if(previousFrame.origin.x - screenFrame.origin.x + previousFrame.size.width >= screenFrame.size.width
- || previousFrame.origin.y - screenFrame.origin.y + previousFrame.size.height >= screenFrame.size.height)
- {
-
- // First try to move the window back onto the screen if it will fit
- if (previousFrame.size.width <= screenFrame.size.width && previousFrame.size.height <= screenFrame.size.height) {
- previousFrame.origin.x -= (previousFrame.origin.x + previousFrame.size.width) - (screenFrame.origin.x + screenFrame.size.width);
- previousFrame.origin.y -= (previousFrame.origin.y + previousFrame.size.height) - (screenFrame.origin.y + screenFrame.size.height);
- [tableWindow setFrame:previousFrame display:YES];
-
- // Otherwise, resize and de-cascade a little
- } else {
- previousFrame.size.width -= 50;
- previousFrame.size.height -= 50;
- previousFrame.origin.y += 50;
- if(previousFrame.size.width >= [tableWindow minSize].width && previousFrame.size.height >= [tableWindow minSize].height)
- [tableWindow setFrame:previousFrame display:YES];
- }
- }
-
- }
-
// Set up the toolbar
[self setupToolbar];
@@ -200,23 +175,21 @@
// Register a second observer for when the logging preference changes so we can tell the current connection about it
[prefs addObserver:self forKeyPath:SPConsoleEnableLogging options:NSKeyValueObservingOptionNew context:NULL];
+ // Register for notifications
+ //register for notifications
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willPerformQuery:)
+ name:@"SMySQLQueryWillBePerformed" object:self];
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(hasPerformedQuery:)
+ name:@"SMySQLQueryHasBeenPerformed" object:self];
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillTerminate:)
+ name:@"NSApplicationWillTerminateNotification" object:nil];
+
// Find the Database -> Database Encoding menu (it's not in our nib, so we can't use interface builder)
- selectEncodingMenu = [[[[[NSApp mainMenu] itemWithTag:1] submenu] itemWithTag:1] submenu];
+ selectEncodingMenu = [[[[[NSApp mainMenu] itemWithTag:SPMainMenuDatabase] submenu] itemWithTag:1] submenu];
// Hide the tabs in the tab view (we only show them to allow switching tabs in interface builder)
[tableTabView setTabViewType:NSNoTabsNoBorder];
- // Add the icon accessory view to the title bar
- NSView *windowFrame = [[tableWindow contentView] superview];
- NSRect av = [titleAccessoryView frame];
- NSRect initialAccessoryViewFrame = NSMakeRect(
- [windowFrame frame].size.width - av.size.width - 30,
- [windowFrame frame].size.height - av.size.height,
- av.size.width,
- av.size.height);
- [titleAccessoryView setFrame:initialAccessoryViewFrame];
- [windowFrame addSubview:titleAccessoryView];
-
// Bind the background color of the create syntax text view to the users preference
[createTableSyntaxTextView setAllowsDocumentBackgroundColorChange:YES];
@@ -229,25 +202,35 @@
withKeyPath:@"values.CustomQueryEditorBackgroundColor"
options:bindingOptions];
- // Load additional nibs
- if (![NSBundle loadNibNamed:@"ConnectionErrorDialog" owner:self]) {
+ // Load additional nibs, keeping track of the top-level objects to allow correct release
+ NSArray *connectionDialogTopLevelObjects = nil;
+ NSNib *nibLoader = [[NSNib alloc] initWithNibNamed:@"ConnectionErrorDialog" bundle:[NSBundle mainBundle]];
+ if (![nibLoader instantiateNibWithOwner:self topLevelObjects:&connectionDialogTopLevelObjects]) {
NSLog(@"Connection error dialog could not be loaded; connection failure handling will not function correctly.");
+ } else {
+ [nibObjectsToRelease addObjectsFromArray:connectionDialogTopLevelObjects];
}
- if (![NSBundle loadNibNamed:@"ProgressIndicatorLayer" owner:self]) {
+ [nibLoader release];
+ NSArray *progressIndicatorLayerTopLevelObjects = nil;
+ nibLoader = [[NSNib alloc] initWithNibNamed:@"ProgressIndicatorLayer" bundle:[NSBundle mainBundle]];
+ if (![nibLoader instantiateNibWithOwner:self topLevelObjects:&progressIndicatorLayerTopLevelObjects]) {
NSLog(@"Progress indicator layer could not be loaded; progress display will not function correctly.");
+ } else {
+ [nibObjectsToRelease addObjectsFromArray:progressIndicatorLayerTopLevelObjects];
}
+ [nibLoader release];
- // Set up the progress indicator child window and layer - add to main window, change indicator color and size
+ // Retain the icon accessory view to allow it to be added and removed from windows
+ [titleAccessoryView retain];
+
+ // Set up the progress indicator child window and layer - change indicator color and size
[taskProgressIndicator setForeColor:[NSColor whiteColor]];
taskProgressWindow = [[NSWindow alloc] initWithContentRect:[taskProgressLayer bounds] styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
+ [taskProgressWindow setReleasedWhenClosed:NO];
[taskProgressWindow setOpaque:NO];
[taskProgressWindow setBackgroundColor:[NSColor clearColor]];
[taskProgressWindow setAlphaValue:0.0];
- [taskProgressWindow orderFront:self];
- [tableWindow addChildWindow:taskProgressWindow ordered:NSWindowAbove];
- [taskProgressWindow setReleasedWhenClosed:YES];
[taskProgressWindow setContentView:taskProgressLayer];
- [self centerTaskWindow];
}
/**
@@ -266,8 +249,7 @@
NSInteger connectionType = -1;
- // Inform about the data source in the window title bar
- [tableWindow setTitle:[self displaySPName]];
+ [self updateWindowTitle:self];
// Clean fields
[connectionController setName:@""];
@@ -305,7 +287,7 @@
[alert setAlertStyle:NSCriticalAlertStyle];
[alert runModal];
if (spf) [spf release];
- [self close];
+ [self closeAndDisconnect];
return;
}
@@ -313,7 +295,7 @@
if(![[spf objectForKey:@"format"] isEqualToString:@"connection"]) {
NSLog(@"SPF file format is not 'connection'.");
[spf release];
- [self close];
+ [self closeAndDisconnect];
return;
}
@@ -327,7 +309,7 @@
[alert setAlertStyle:NSCriticalAlertStyle];
[alert runModal];
[spf release];
- [self close];
+ [self closeAndDisconnect];
return;
}
@@ -339,7 +321,7 @@
[inputTextWindowSecureTextField setStringValue:@""];
[inputTextWindowSecureTextField selectText:nil];
- [NSApp beginSheet:inputTextWindow modalForWindow:tableWindow modalDelegate:self didEndSelector:nil contextInfo:nil];
+ [NSApp beginSheet:inputTextWindow modalForWindow:parentWindow modalDelegate:self didEndSelector:nil contextInfo:nil];
// wait for encryption password
NSModalSession session = [NSApp beginModalSessionForWindow:inputTextWindow];
@@ -366,7 +348,7 @@
if(passwordSheetReturnCode)
encryptpw = [inputTextWindowSecureTextField stringValue];
else {
- [self close];
+ [self closeAndDisconnect];
[spf release];
return;
}
@@ -392,7 +374,7 @@
[alert setAlertStyle:NSCriticalAlertStyle];
[alert runModal];
- [self close];
+ [self closeAndDisconnect];
[spf release];
return;
}
@@ -407,7 +389,7 @@
[alert setAlertStyle:NSCriticalAlertStyle];
[alert runModal];
- [self close];
+ [self closeAndDisconnect];
[spf release];
return;
}
@@ -422,7 +404,7 @@
[alert setAlertStyle:NSCriticalAlertStyle];
[alert runModal];
- [self close];
+ [self closeAndDisconnect];
[spf release];
return;
}
@@ -545,7 +527,7 @@
// Restore toolbar setting
if([spfSession objectForKey:@"isToolbarVisible"])
- [[tableWindow toolbar] setVisible:[[spfSession objectForKey:@"isToolbarVisible"] boolValue]];
+ [mainToolbar setVisible:[[spfSession objectForKey:@"isToolbarVisible"] boolValue]];
// TODO up to now it doesn't work
if([spfSession objectForKey:@"contentSelectedIndexSet"]) {
@@ -592,7 +574,7 @@
[[tablesListInstance valueForKeyPath:@"tablesListView"] scrollRowToVisible:[tables indexOfObject:[spfSession objectForKey:@"selectedTable"]]];
- [tableWindow setTitle:[self displaySPName]];
+ [self updateWindowTitle:self];
// dealloc spfSession data
[spfSession release];
@@ -650,7 +632,7 @@
[self setFileURL:[[SPQueryController sharedQueryController] registerDocumentWithFileURL:[self fileURL] andContextInfo:spfPreferences]];
// ...but hide the icon while the document is temporary
- if ([self isUntitled]) [[tableWindow standardWindowButton:NSWindowDocumentIconButton] setImage:nil];
+ if ([self isUntitled]) [[parentWindow standardWindowButton:NSWindowDocumentIconButton] setImage:nil];
// Set the connection encoding
NSString *encodingName = [prefs objectForKey:SPDefaultEncoding];
@@ -672,6 +654,7 @@
// Update the database list
[self setDatabases:self];
+ [chooseDatabaseButton setEnabled:!_isWorkingLevel];
// For each of the main controllers, assign the current connection
[tablesListInstance setConnection:mySQLConnection];
@@ -690,12 +673,12 @@
// Set the cutom query editor's MySQL version
[customQueryInstance setMySQLversion:mySQLVersion];
- [tableWindow setTitle:[self displaySPName]];
+ [self updateWindowTitle:self];
// Connected Growl notification
[[SPGrowlController sharedGrowlController] notifyWithTitle:@"Connected"
- description:[NSString stringWithFormat:NSLocalizedString(@"Connected to %@",@"description for connected growl notification"), [tableWindow title]]
- window:tableWindow
+ description:[NSString stringWithFormat:NSLocalizedString(@"Connected to %@",@"description for connected growl notification"), [parentWindow title]]
+ document:self
notificationName:@"Connected"];
// Init Custom Query editor with the stored queries in a spf file if given.
@@ -722,9 +705,9 @@
// Set focus to table list filter field if visible
// otherwise set focus to Table List view
if ( [[tablesListInstance tables] count] > 20 )
- [tableWindow makeFirstResponder:listFilterField];
+ [parentWindow makeFirstResponder:listFilterField];
else
- [tableWindow makeFirstResponder:[tablesListInstance valueForKeyPath:@"tablesListView"]];
+ [parentWindow makeFirstResponder:[tablesListInstance valueForKeyPath:@"tablesListView"]];
if(spfSession != nil) {
@@ -764,25 +747,6 @@
return mySQLConnection;
}
-
-/**
- * Set whether the connection controller should automatically start
- * connecting; called by maincontroller, but only for first window.
- */
-- (void)setShouldAutomaticallyConnect:(BOOL)shouldAutomaticallyConnect
-{
- _shouldOpenConnectionAutomatically = shouldAutomaticallyConnect;
-}
-
-/**
- * Allow the connection controller to determine whether connection should
- * be automatically triggered.
- */
-- (BOOL)shouldAutomaticallyConnect
-{
- return _shouldOpenConnectionAutomatically;
-}
-
/**
* Sets this connection's Keychain ID.
*/
@@ -925,7 +889,7 @@
[databaseNameField setStringValue:@""];
[NSApp beginSheet:databaseSheet
- modalForWindow:tableWindow
+ modalForWindow:parentWindow
modalDelegate:self
didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:)
contextInfo:@"addDatabase"];
@@ -943,7 +907,7 @@
[copyDatabaseMessageField setStringValue:[NSString stringWithFormat:NSLocalizedString(@"Duplicate database '%@' to:", @"duplicate database message"), selectedDatabase]];
[NSApp beginSheet:databaseCopySheet
- modalForWindow:tableWindow
+ modalForWindow:parentWindow
modalDelegate:self
didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:)
contextInfo:@"copyDatabase"];
@@ -960,7 +924,7 @@
[renameDatabaseMessageField setStringValue:[NSString stringWithFormat:NSLocalizedString(@"Rename database '%@' to:", @"rename database message"), selectedDatabase]];
[NSApp beginSheet:databaseRenameSheet
- modalForWindow:tableWindow
+ modalForWindow:parentWindow
modalDelegate:self
didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:)
contextInfo:@"renameDatabase"];
@@ -991,7 +955,7 @@
[alert setAlertStyle:NSCriticalAlertStyle];
- [alert beginSheetModalForWindow:tableWindow modalDelegate:self didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) contextInfo:@"removeDatabase"];
+ [alert beginSheetModalForWindow:parentWindow modalDelegate:self didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) contextInfo:@"removeDatabase"];
}
/**
@@ -1008,7 +972,7 @@
[prefs addObserver:serverVariablesController forKeyPath:SPDisplayTableViewVerticalGridlines options:NSKeyValueObservingOptionNew context:NULL];
}
- [serverVariablesController displayServerVariablesSheetAttachedToWindow:tableWindow];
+ [serverVariablesController displayServerVariablesSheetAttachedToWindow:parentWindow];
}
/**
@@ -1108,7 +1072,7 @@
{
// error := first object is the title , second the message, only one button OK
SPBeginAlertSheet([error objectAtIndex:0], NSLocalizedString(@"OK", @"OK button"),
- nil, nil, tableWindow, self, nil, nil,
+ nil, nil, parentWindow, self, nil, nil,
[error objectAtIndex:1]);
}
@@ -1135,12 +1099,12 @@
if (selectedDatabase) [selectedDatabase release], selectedDatabase = nil;
selectedDatabase = [[NSString alloc] initWithString:dbName];
[chooseDatabaseButton selectItemWithTitle:selectedDatabase];
- [tableWindow setTitle:[self displaySPName]];
+ [self updateWindowTitle:self];
}
} else {
if (selectedDatabase) [selectedDatabase release], selectedDatabase = nil;
[chooseDatabaseButton selectItemAtIndex:0];
- [tableWindow setTitle:[self displaySPName]];
+ [self updateWindowTitle:self];
}
}
@@ -1284,6 +1248,7 @@
databaseListIsSelectable = NO;
[[NSNotificationCenter defaultCenter] postNotificationName:SPDocumentTaskStartNotification object:self];
[mainToolbar validateVisibleItems];
+ [chooseDatabaseButton setEnabled:NO];
// Schedule appearance of the task window in the near future
taskDrawTimer = [[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(showTaskProgressWindow:) userInfo:nil repeats:NO] retain];
@@ -1399,6 +1364,7 @@
databaseListIsSelectable = YES;
[[NSNotificationCenter defaultCenter] postNotificationName:SPDocumentTaskEndNotification object:self];
[mainToolbar validateVisibleItems];
+ [chooseDatabaseButton setEnabled:_isConnected];
}
}
@@ -1476,7 +1442,7 @@
- (void) centerTaskWindow
{
NSPoint newBottomLeftPoint;
- NSRect mainWindowRect = [tableWindow frame];
+ NSRect mainWindowRect = [parentWindow frame];
NSRect taskWindowRect = [taskProgressWindow frame];
newBottomLeftPoint.x = round(mainWindowRect.origin.x + mainWindowRect.size.width/2 - taskWindowRect.size.width/2);
@@ -1737,7 +1703,7 @@
defaultButton:NSLocalizedString(@"OK", @"OK button")
alternateButton:nil otherButton:nil
informativeTextWithFormat:NSLocalizedString(@"The creation syntax could not be retrieved due to a permissions error.\n\nPlease check your user permissions with an administrator.", @"Create syntax permission denied detail")]
- beginSheetModalForWindow:tableWindow
+ beginSheetModalForWindow:parentWindow
modalDelegate:self didEndSelector:NULL contextInfo:NULL];
return;
}
@@ -1753,7 +1719,7 @@
// Show variables sheet
[NSApp beginSheet:createTableSyntaxWindow
- modalForWindow:tableWindow
+ modalForWindow:parentWindow
modalDelegate:self
didEndSelector:nil
contextInfo:nil];
@@ -1806,7 +1772,7 @@
defaultButton:NSLocalizedString(@"OK", @"OK button")
alternateButton:nil otherButton:nil
informativeTextWithFormat:NSLocalizedString(@"The creation syntax could not be retrieved due to a permissions error.\n\nPlease check your user permissions with an administrator.", @"Create syntax permission denied detail")]
- beginSheetModalForWindow:tableWindow
+ beginSheetModalForWindow:parentWindow
modalDelegate:self didEndSelector:NULL contextInfo:NULL];
return;
}
@@ -1822,7 +1788,7 @@
// Table syntax copied Growl notification
[[SPGrowlController sharedGrowlController] notifyWithTitle:@"Syntax Copied"
description:[NSString stringWithFormat:NSLocalizedString(@"Syntax for %@ table copied",@"description for table syntax copied growl notification"), [self table]]
- window:tableWindow
+ document:self
notificationName:@"Syntax Copied"];
}
@@ -1851,7 +1817,7 @@
alternateButton:nil
otherButton:nil
informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to check the %@.\n\nMySQL said:%@",@"an error occurred while trying to check the %@.\n\nMySQL said:%@"), what, [mySQLConnection getLastErrorMessage]]]
- beginSheetModalForWindow:tableWindow
+ beginSheetModalForWindow:parentWindow
modalDelegate:self
didEndSelector:NULL
contextInfo:NULL];
@@ -1886,7 +1852,7 @@
alternateButton:nil
otherButton:nil
informativeTextWithFormat:message]
- beginSheetModalForWindow:tableWindow
+ beginSheetModalForWindow:parentWindow
modalDelegate:self
didEndSelector:NULL
contextInfo:NULL];
@@ -1898,7 +1864,7 @@
[alert setInformativeText:message];
[alert setMessageText:NSLocalizedString(@"Error while checking selected items", @"error while checking selected items message")];
[alert setAccessoryView:statusTableAccessoryView];
- [alert beginSheetModalForWindow:tableWindow modalDelegate:self didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) contextInfo:@"statusError"];
+ [alert beginSheetModalForWindow:parentWindow modalDelegate:self didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) contextInfo:@"statusError"];
}
}
@@ -1927,7 +1893,7 @@
alternateButton:nil
otherButton:nil
informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while analyzing the %@.\n\nMySQL said:%@",@"an error occurred while analyzing the %@.\n\nMySQL said:%@"), what, [mySQLConnection getLastErrorMessage]]]
- beginSheetModalForWindow:tableWindow
+ beginSheetModalForWindow:parentWindow
modalDelegate:self
didEndSelector:NULL
contextInfo:NULL];
@@ -1962,7 +1928,7 @@
alternateButton:nil
otherButton:nil
informativeTextWithFormat:message]
- beginSheetModalForWindow:tableWindow
+ beginSheetModalForWindow:parentWindow
modalDelegate:self
didEndSelector:NULL
contextInfo:NULL];
@@ -1974,7 +1940,7 @@
[alert setInformativeText:message];
[alert setMessageText:NSLocalizedString(@"Error while analyzing selected items", @"error while analyzing selected items message")];
[alert setAccessoryView:statusTableAccessoryView];
- [alert beginSheetModalForWindow:tableWindow modalDelegate:self didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) contextInfo:@"statusError"];
+ [alert beginSheetModalForWindow:parentWindow modalDelegate:self didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) contextInfo:@"statusError"];
}
}
@@ -2003,7 +1969,7 @@
alternateButton:nil
otherButton:nil
informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while optimzing the %@.\n\nMySQL said:%@",@"an error occurred while trying to optimze the %@.\n\nMySQL said:%@"), what, [mySQLConnection getLastErrorMessage]]]
- beginSheetModalForWindow:tableWindow
+ beginSheetModalForWindow:parentWindow
modalDelegate:self
didEndSelector:NULL
contextInfo:NULL];
@@ -2038,7 +2004,7 @@
alternateButton:nil
otherButton:nil
informativeTextWithFormat:message]
- beginSheetModalForWindow:tableWindow
+ beginSheetModalForWindow:parentWindow
modalDelegate:self
didEndSelector:NULL
contextInfo:NULL];
@@ -2050,7 +2016,7 @@
[alert setInformativeText:message];
[alert setMessageText:NSLocalizedString(@"Error while optimizing selected items", @"error while optimizing selected items message")];
[alert setAccessoryView:statusTableAccessoryView];
- [alert beginSheetModalForWindow:tableWindow modalDelegate:self didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) contextInfo:@"statusError"];
+ [alert beginSheetModalForWindow:parentWindow modalDelegate:self didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) contextInfo:@"statusError"];
}
}
@@ -2078,7 +2044,7 @@
alternateButton:nil
otherButton:nil
informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while repairing the %@.\n\nMySQL said:%@",@"an error occurred while trying to repair the %@.\n\nMySQL said:%@"), what, [mySQLConnection getLastErrorMessage]]]
- beginSheetModalForWindow:tableWindow
+ beginSheetModalForWindow:parentWindow
modalDelegate:self
didEndSelector:NULL
contextInfo:NULL];
@@ -2113,7 +2079,7 @@
alternateButton:nil
otherButton:nil
informativeTextWithFormat:message]
- beginSheetModalForWindow:tableWindow
+ beginSheetModalForWindow:parentWindow
modalDelegate:self
didEndSelector:NULL
contextInfo:NULL];
@@ -2125,7 +2091,7 @@
[alert setInformativeText:message];
[alert setMessageText:NSLocalizedString(@"Error while repairing selected items", @"error while repairing selected items message")];
[alert setAccessoryView:statusTableAccessoryView];
- [alert beginSheetModalForWindow:tableWindow modalDelegate:self didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) contextInfo:@"statusError"];
+ [alert beginSheetModalForWindow:parentWindow modalDelegate:self didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) contextInfo:@"statusError"];
}
}
@@ -2153,7 +2119,7 @@
alternateButton:nil
otherButton:nil
informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while flushing the %@.\n\nMySQL said:%@",@"an error occurred while trying to flush the %@.\n\nMySQL said:%@"), what, [mySQLConnection getLastErrorMessage]]]
- beginSheetModalForWindow:tableWindow
+ beginSheetModalForWindow:parentWindow
modalDelegate:self
didEndSelector:NULL
contextInfo:NULL];
@@ -2188,7 +2154,7 @@
alternateButton:nil
otherButton:nil
informativeTextWithFormat:message]
- beginSheetModalForWindow:tableWindow
+ beginSheetModalForWindow:parentWindow
modalDelegate:self
didEndSelector:NULL
contextInfo:NULL];
@@ -2200,7 +2166,7 @@
[alert setInformativeText:message];
[alert setMessageText:NSLocalizedString(@"Error while flushing selected items", @"error while flushing selected items message")];
[alert setAccessoryView:statusTableAccessoryView];
- [alert beginSheetModalForWindow:tableWindow modalDelegate:self didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) contextInfo:@"statusError"];
+ [alert beginSheetModalForWindow:parentWindow modalDelegate:self didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) contextInfo:@"statusError"];
}
}
@@ -2227,7 +2193,7 @@
alternateButton:nil
otherButton:nil
informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while performing the checksum on %@.\n\nMySQL said:%@",@"an error occurred while performing the checksum on the %@.\n\nMySQL said:%@"), what, [mySQLConnection getLastErrorMessage]]]
- beginSheetModalForWindow:tableWindow
+ beginSheetModalForWindow:parentWindow
modalDelegate:self
didEndSelector:NULL
contextInfo:NULL];
@@ -2244,7 +2210,7 @@
alternateButton:nil
otherButton:nil
informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"Table checksum: %@",@"table checksum: %@"), message]]
- beginSheetModalForWindow:tableWindow
+ beginSheetModalForWindow:parentWindow
modalDelegate:self
didEndSelector:NULL
contextInfo:NULL];
@@ -2256,7 +2222,7 @@
[alert setInformativeText:[NSString stringWithFormat:NSLocalizedString(@"Checksums of %@",@"Checksums of %@ message"), what]];
[alert setMessageText:NSLocalizedString(@"Table checksum",@"table checksum message")];
[alert setAccessoryView:statusTableAccessoryView];
- [alert beginSheetModalForWindow:tableWindow modalDelegate:self didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) contextInfo:@"statusError"];
+ [alert beginSheetModalForWindow:parentWindow modalDelegate:self didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) contextInfo:@"statusError"];
}
}
@@ -2293,7 +2259,7 @@
// Table syntax copied Growl notification
[[SPGrowlController sharedGrowlController] notifyWithTitle:@"Syntax Copied"
description:[NSString stringWithFormat:NSLocalizedString(@"Syntax for %@ table copied", @"description for table syntax copied growl notification"), [self table]]
- window:tableWindow
+ document:self
notificationName:@"Syntax Copied"];
}
}
@@ -2365,13 +2331,13 @@
[alert setAlertStyle:NSCriticalAlertStyle];
- [alert beginSheetModalForWindow:tableWindow modalDelegate:self didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) contextInfo:@"cannotremovefield"];
+ [alert beginSheetModalForWindow:parentWindow modalDelegate:self didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) contextInfo:@"cannotremovefield"];
return;
}
[NSApp beginSheet:[userManagerInstance window]
- modalForWindow:tableWindow
+ modalForWindow:parentWindow
modalDelegate:userManagerInstance
didEndSelector:@selector(userManagerSheetDidEnd:returnCode:contextInfo:)
contextInfo:nil];
@@ -2382,7 +2348,7 @@
*/
- (void)doPerformQueryService:(NSString *)query
{
- [tableWindow makeKeyAndOrderFront:self];
+ [parentWindow makeKeyAndOrderFront:self];
[tablesListInstance doPerformQueryService:query];
}
@@ -2404,26 +2370,29 @@
if (![mySQLConnection queryErrored]) {
//flushed privileges without errors
- SPBeginAlertSheet(NSLocalizedString(@"Flushed Privileges", @"title of panel when successfully flushed privs"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil, nil, NSLocalizedString(@"Successfully flushed privileges.", @"message of panel when successfully flushed privs"));
+ SPBeginAlertSheet(NSLocalizedString(@"Flushed Privileges", @"title of panel when successfully flushed privs"), NSLocalizedString(@"OK", @"OK button"), nil, nil, parentWindow, self, nil, nil, NSLocalizedString(@"Successfully flushed privileges.", @"message of panel when successfully flushed privs"));
} else {
//error while flushing privileges
- SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil, nil, [NSString stringWithFormat:NSLocalizedString(@"Couldn't flush privileges.\nMySQL said: %@", @"message of panel when flushing privs failed"),
+ SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, parentWindow, self, nil, nil, [NSString stringWithFormat:NSLocalizedString(@"Couldn't flush privileges.\nMySQL said: %@", @"message of panel when flushing privs failed"),
[mySQLConnection getLastErrorMessage]]);
}
}
- (IBAction)openCurrentConnectionInNewWindow:(id)sender
{
- TableDocument *newTableDocument;
+ [[NSApp delegate] newWindow:self];
+ TableDocument *newTableDocument = [[NSApp delegate] frontDocument];
+ [newTableDocument initWithConnectionFile:[[self fileURL] path]];
+}
- // Manually open a new document, setting SPAppController as sender to trigger autoconnection
- if (newTableDocument = [[NSDocumentController sharedDocumentController] makeUntitledDocumentOfType:@"Sequel Pro connection" error:nil]) {
- [newTableDocument setShouldAutomaticallyConnect:NO];
- [[NSDocumentController sharedDocumentController] addDocument:newTableDocument];
- [newTableDocument makeWindowControllers];
- [newTableDocument showWindows];
- [newTableDocument initWithConnectionFile:[[self fileURL] path]];
- }
+/**
+ * Ask the connection controller to initiate connection, if it hasn't
+ * already. Used to support automatic connections on window open,
+ */
+- (void)connect
+{
+ if (mySQLVersion) return;
+ [connectionController initiateConnection:self];
}
- (void)closeConnection
@@ -2433,8 +2402,8 @@
// Disconnected Growl notification
[[SPGrowlController sharedGrowlController] notifyWithTitle:@"Disconnected"
- description:[NSString stringWithFormat:NSLocalizedString(@"Disconnected from %@",@"description for disconnected growl notification"), [tableWindow title]]
- window:tableWindow
+ description:[NSString stringWithFormat:NSLocalizedString(@"Disconnected from %@",@"description for disconnected growl notification"), [parentTabViewItem label]]
+ document:self
notificationName:@"Disconnected"];
}
@@ -2453,7 +2422,7 @@
*/
- (BOOL)isUntitled
{
- return ([[self fileURL] isFileURL]) ? NO : YES;
+ return ([self fileURL] && [[self fileURL] isFileURL]) ? NO : YES;
}
/**
@@ -2463,7 +2432,7 @@
*/
- (BOOL)couldCommitCurrentViewActions
{
- [tableWindow endEditingFor:nil];
+ [parentWindow endEditingFor:nil];
switch ([tableTabView indexOfTabViewItem:[tableTabView selectedTabViewItem]]) {
// Table structure view
@@ -2484,6 +2453,16 @@
#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
*/
@@ -2604,6 +2583,7 @@
*/
- (void)willPerformQuery:(NSNotification *)notification
{
+ isProcessing = YES;
[queryProgressBar startAnimation:self];
}
@@ -2612,6 +2592,7 @@
*/
- (void)hasPerformedQuery:(NSNotification *)notification
{
+ isProcessing = NO;
[queryProgressBar stopAnimation:self];
}
@@ -2686,7 +2667,8 @@
return;
}
- // Load accessory nib each time
+ // Load accessory nib each time.
+ // Note that the top-level objects aren't released automatically, but are released when the panel ends.
if(![NSBundle loadNibNamed:@"SaveSPFAccessory" owner:self]) {
NSLog(@"SaveSPFAccessory accessory dialog could not be loaded.");
return;
@@ -2734,7 +2716,7 @@
[panel beginSheetForDirectory:nil
file:filename
- modalForWindow:tableWindow
+ modalForWindow:parentWindow
modalDelegate:self
didEndSelector:@selector(saveConnectionPanelDidEnd:returnCode:contextInfo:)
contextInfo:contextInfo];
@@ -2763,7 +2745,6 @@
- (void)saveConnectionPanelDidEnd:(NSSavePanel *)panel returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo
{
-
if ( returnCode ) {
NSString *fileName = [panel filename];
@@ -2799,8 +2780,11 @@
[self saveDocumentWithFilePath:fileName inBackground:NO onlyPreferences:NO];
+ // Manually loaded nibs don't have their top-level objects released automatically - do that here.
+ [saveConnectionAccessory release];
+
if(contextInfo == @"saveSPFfileAndClose")
- [self close];
+ [self closeAndDisconnect];
}
}
}
@@ -3010,7 +2994,7 @@
}
[session setObject:aString forKey:@"view"];
- [session setObject:[NSNumber numberWithBool:[[tableWindow toolbar] isVisible]] forKey:@"isToolbarVisible"];
+ [session setObject:[NSNumber numberWithBool:[[parentWindow toolbar] isVisible]] forKey:@"isToolbarVisible"];
[session setObject:[self connectionEncoding] forKey:@"connectionEncoding"];
[session setObject:[NSNumber numberWithBool:[tableContentInstance sortColumnIsAscending]] forKey:@"contentSortColIsAsc"];
@@ -3090,7 +3074,7 @@
[self setFileURL:[NSURL fileURLWithPath:fileName]];
[[NSDocumentController sharedDocumentController] noteNewRecentDocumentURL:[NSURL fileURLWithPath:fileName]];
- [tableWindow setTitle:[self displaySPName]];
+ [self updateWindowTitle:self];
// Store doc data permanently
[spfDocData removeAllObjects];
@@ -3161,7 +3145,7 @@
}
if (!_isConnected || _isWorkingLevel) {
- return ([menuItem action] == @selector(newDocument:) || [menuItem action] == @selector(terminate:));
+ return ([menuItem action] == @selector(newWindow:) || [menuItem action] == @selector(terminate:) || [menuItem action] == @selector(closeTab:) || [menuItem action] == @selector(newTab:));
}
if ([menuItem action] == @selector(openCurrentConnectionInNewWindow:))
@@ -3291,7 +3275,8 @@
return NO;
}
- return [super validateMenuItem:menuItem];
+ // Default to YES for unhandled menus
+ return YES;
}
- (IBAction)viewStructure:(id)sender
@@ -3339,7 +3324,7 @@
[spHistoryControllerInstance updateHistoryEntries];
// Set the focus on the text field
- [tableWindow makeFirstResponder:customQueryTextView];
+ [parentWindow makeFirstResponder:customQueryTextView];
[prefs setInteger:SPQueryEditorViewMode forKey:SPLastViewMode];
}
@@ -3363,7 +3348,7 @@
[extendedTableInfoInstance loadTable:[self table]];
}
- [tableWindow makeFirstResponder:[extendedTableInfoInstance valueForKeyPath:@"tableCreateSyntaxTextView"]];
+ [parentWindow makeFirstResponder:[extendedTableInfoInstance valueForKeyPath:@"tableCreateSyntaxTextView"]];
[prefs setInteger:SPTableInfoViewMode forKey:SPLastViewMode];
}
@@ -3448,6 +3433,72 @@
#pragma mark Titlebar Methods
/**
+ * Update the window title.
+ */
+- (void) updateWindowTitle:(id)sender
+{
+ NSMutableString *tabTitle;
+ NSMutableString *windowTitle;
+ TableDocument *frontTableDocument = [parentWindowController selectedTableDocument];
+
+ // Determine name details
+ NSString *pathName = @"";
+ if ([[[self fileURL] path] length] && ![self isUntitled]) {
+ pathName = [NSString stringWithFormat:@"%@ — ", [[[self fileURL] path] lastPathComponent]];
+ }
+ if (!_isConnected) {
+ windowTitle = [NSString stringWithFormat:@"%@%@", pathName, @"Sequel Pro"];
+ tabTitle = windowTitle;
+ } else {
+ windowTitle = [NSMutableString string];
+ tabTitle = [NSMutableString string];
+
+ // Add the path to the window title
+ [windowTitle appendString:pathName];
+
+ // Add the MySQL version to the window title if enabled in prefs
+ if ([prefs boolForKey:SPDisplayServerVersionInWindowTitle]) [windowTitle appendFormat:@"(MySQL %@) ", mySQLVersion];
+
+ // Add the name to the window
+ [windowTitle appendString:[self name]];
+
+ // Also add to the frontmost tab, and other tabs if the host is different, not connected, or no db is selected
+ if (frontTableDocument == self || [[frontTableDocument name] isNotEqualTo:[self name]] || ![frontTableDocument getConnection] || ![self database]) {
+ [tabTitle appendString:[self name]];
+ }
+
+ // If a database is selected, add to the window - and other tabs if host is the same but table is set
+ if ([self database]) {
+ [windowTitle appendFormat:@"/%@", [self database]];
+ if (frontTableDocument == self
+ || [[frontTableDocument name] isNotEqualTo:[self name]]
+ || ![[self table] length])
+ {
+ if ([tabTitle length]) [tabTitle appendString:@"/"];
+ [tabTitle appendString:[self database]];
+ }
+ }
+
+ // Add the table name if one is selected
+ if ([[self table] length]) {
+ [windowTitle appendFormat:@"/%@", [self table]];
+ if ([tabTitle length]) [tabTitle appendString:@"/"];
+ [tabTitle appendString:[self table]];
+ }
+ }
+
+ // Set the titles
+ [parentTabViewItem setLabel:tabTitle];
+ if ([parentWindowController selectedTableDocument] == self) {
+ [parentWindow setTitle:windowTitle];
+ }
+
+ // If the sender wasn't the window controller, update other tabs in this window
+ // for shared pathname updates
+ if ([sender class] != [SPWindowController class]) [parentWindowController updateAllTabTitles:self];
+}
+
+/**
* Set the connection status icon in the titlebar
*/
- (void)setStatusIconToImageWithName:(NSString *)imageName
@@ -3482,7 +3533,7 @@
- (void)setupToolbar
{
// create a new toolbar instance, and attach it to our document window
- mainToolbar = [[[NSToolbar alloc] initWithIdentifier:@"TableWindowToolbar"] autorelease];
+ mainToolbar = [[NSToolbar alloc] initWithIdentifier:@"TableWindowToolbar"];
// set up toolbar properties
[mainToolbar setAllowsUserCustomization:YES];
@@ -3492,9 +3543,6 @@
// set ourself as the delegate
[mainToolbar setDelegate:self];
- // attach the toolbar to the document window
- [tableWindow setToolbar:mainToolbar];
-
// update the toolbar item size
[self updateChooseDatabaseToolbarItemWidth];
@@ -3525,6 +3573,7 @@
[toolbarItem setMaxSize:NSMakeSize(200,32)];
[chooseDatabaseButton setTarget:self];
[chooseDatabaseButton setAction:@selector(chooseDatabase:)];
+ [chooseDatabaseButton setEnabled:(_isConnected && !_isWorkingLevel)];
if (willBeInsertedIntoToolbar) {
chooseDatabaseToolbarItem = toolbarItem;
@@ -3698,7 +3747,7 @@
/**
* Validates the toolbar items
*/
-- (BOOL)validateToolbarItem:(NSToolbarItem *)toolbarItem;
+- (BOOL)validateToolbarItem:(NSToolbarItem *)toolbarItem
{
if (!_isConnected || _isWorkingLevel) return NO;
@@ -3732,40 +3781,50 @@
}
#pragma mark -
-#pragma mark NSDocument methods
+#pragma mark Tab methods
/**
- * Returns the name of the nib file
+ * Make this document's window frontmost in the application,
+ * and ensure this tab is selected.
*/
-- (NSString *)windowNibName
+- (void)makeKeyDocument
{
- return @"DBView";
+ [[[self parentWindow] onMainThread] makeKeyAndOrderFront:self];
+ [[[[self parentTabViewItem] onMainThread] tabView] selectTabViewItemWithIdentifier:self];
}
/**
- * Code that need to be executed once the windowController has loaded the document's window
- * sets upt the interface (small fonts).
+ * Invoked to determine whether the parent tab is allowed to close
*/
-- (void)windowControllerDidLoadNib:(NSWindowController *)aController
+- (BOOL)parentTabShouldClose
{
- [aController setShouldCascadeWindows:YES];
- [super windowControllerDidLoadNib:aController];
- //register for notifications
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willPerformQuery:)
- name:@"SMySQLQueryWillBePerformed" object:self];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(hasPerformedQuery:)
- name:@"SMySQLQueryHasBeenPerformed" object:self];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillTerminate:)
- name:@"NSApplicationWillTerminateNotification" object:nil];
-}
+ // If no connection is available, always return YES. Covers initial setup and disconnections.
+ if(!_isConnected) return YES;
-// NSWindow delegate methods
+ // If tasks are active, return NO to allow tasks to complete
+ if (_isWorkingLevel) return NO;
+
+ // If the table list considers itself to be working, return NO. This catches open alerts, and
+ // edits in progress in various views.
+ if ( ![tablesListInstance selectionShouldChangeInTableView:nil] ) return NO;
+
+ // Auto-save spf file based connection and return whether the save was successful
+ if([self fileURL] && [[[self fileURL] path] length] && ![self isUntitled]) {
+ BOOL isSaved = [self saveDocumentWithFilePath:nil inBackground:YES onlyPreferences:YES];
+ if(isSaved)
+ [[SPQueryController sharedQueryController] removeRegisteredDocumentWithFileURL:[self fileURL]];
+ return isSaved;
+ }
+
+ // Return YES by default
+ return YES;
+}
/**
- * Invoked when the document window is about to close
+ * Invoked when the parent tab is about to close
*/
-- (void)windowWillClose:(NSNotification *)aNotification
+- (void)parentTabDidClose
{
// Cancel autocompletion trigger
@@ -3787,37 +3846,64 @@
if ([[[SPQueryController sharedQueryController] window] isVisible]) [self toggleConsole:self];
[createTableSyntaxWindow orderOut:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self];
+ [self setParentWindow:nil];
}
/**
- * Invoked when the document window should close
+ * Invoked when the parent tab is currently the active tab in the
+ * window, but is being switched away from, to allow cleaning up
+ * details in the window.
*/
-- (BOOL)windowShouldClose:(id)sender
+- (void)willResignActiveTabInWindow
{
- // If no connection is available, always return YES. Covers initial setup and disconnections.
- if(!_isConnected) return YES;
+ // Remove the icon accessory view from the title bar
+ [titleAccessoryView removeFromSuperview];
- // If tasks are active, return NO to allow tasks to complete
- if (_isWorkingLevel) return NO;
+ // Remove the task progress window
+ [parentWindow removeChildWindow:taskProgressWindow];
+ [taskProgressWindow orderOut:self];
+}
- // If the table list considers itself to be working, return NO. This catches open alerts, and
- // edits in progress in various views.
- if ( ![tablesListInstance selectionShouldChangeInTableView:nil] ) return NO;
+/**
+ * Invoked when the parent tab became the active tab in the window,
+ * to allow the window to reflect the contents of this view.
+ */
+- (void)didBecomeActiveTabInWindow
+{
- // Auto-save spf file based connection and return whether the save was successful
- if([self fileURL] && [[[self fileURL] path] length] && ![self isUntitled]) {
- BOOL isSaved = [self saveDocumentWithFilePath:nil inBackground:YES onlyPreferences:YES];
- if(isSaved)
- [[SPQueryController sharedQueryController] removeRegisteredDocumentWithFileURL:[self fileURL]];
- return isSaved;
- }
+ // Update the toolbar
+ [parentWindow setToolbar:mainToolbar];
- // Return YES by default
- return YES;
+ // Update the window's title and represented document
+ [self updateWindowTitle:self];
+ if (spfFileURL && [spfFileURL isFileURL])
+ [parentWindow setRepresentedURL:spfFileURL];
+ else
+ [parentWindow setRepresentedURL:nil];
+
+ // Add the icon accessory view to the title bar
+ NSView *windowFrame = [[parentWindow contentView] superview];
+ NSRect av = [titleAccessoryView frame];
+ NSRect initialAccessoryViewFrame = NSMakeRect(
+ [windowFrame frame].size.width - av.size.width - 30,
+ [windowFrame frame].size.height - av.size.height,
+ av.size.width,
+ av.size.height);
+ [titleAccessoryView setFrame:initialAccessoryViewFrame];
+ [windowFrame addSubview:titleAccessoryView];
+
+ // Add the progress window to this window
+ [self centerTaskWindow];
+ [taskProgressWindow orderFront:self];
+ [parentWindow addChildWindow:taskProgressWindow ordered:NSWindowAbove];
}
-- (void)windowDidBecomeKey:(NSNotification *)notification
+/**
+ * Invoked when the parent tab became the key tab in the application;
+ * the selected tab in the frontmost window.
+ */
+- (void)tabDidBecomeKey
{
// Synchronize Navigator with current active document if Navigator runs in syncMode
if([[SPNavigatorController sharedNavigatorController] syncMode] && [self connectionID] && ![[self connectionID] isEqualToString:@"_"]) {
@@ -3838,19 +3924,67 @@
/**
* Invoked when the document window is resized
*/
-- (void)windowDidResize:(NSNotification *)notification
+- (void)tabDidResize
{
- // If the task interface is visible, re-center the task child window
- if (_isWorkingLevel) [self centerTaskWindow];
+ // If the task interface is visible, and this tab is frontmost, re-center the task child window
+ if (_isWorkingLevel && [parentWindowController selectedTableDocument] == self) [self centerTaskWindow];
}
/**
- * Invoked when the user command-clicks on the window title to see the document path
+ * Support the tab's progress spinner
*/
-- (BOOL)window:(NSWindow *)window shouldPopUpDocumentPathMenu:(NSMenu *)menu
+- (BOOL)isProcessing
+{
+ return (isProcessing || (_isWorkingLevel > 0));
+}
+- (void)setIsProcessing:(BOOL)value
{
- return ![self isUntitled];
+ isProcessing = value;
+}
+
+/**
+ * Set the parent window
+ */
+- (void)setParentWindow:(NSWindow *)aWindow
+{
+ parentWindow = aWindow;
+ SPSSHTunnel *currentTunnel = [connectionController valueForKeyPath:@"sshTunnel"];
+ if (currentTunnel) [currentTunnel setParentWindow:parentWindow];
+}
+
+/**
+ * Return the parent window
+ */
+- (NSWindow *)parentWindow
+{
+ return parentWindow;
+}
+
+#pragma mark -
+#pragma mark NSDocument compatibility
+
+/**
+ * Set the NSURL for a .spf file for this connection instance.
+ */
+- (void)setFileURL:(NSURL *)theURL
+{
+ if (spfFileURL) [spfFileURL release], spfFileURL = nil;
+ spfFileURL = [theURL retain];
+ if ([parentWindowController selectedTableDocument] == self) {
+ if (spfFileURL && [spfFileURL isFileURL])
+ [parentWindow setRepresentedURL:spfFileURL];
+ else
+ [parentWindow setRepresentedURL:nil];
+ }
+}
+
+/**
+ * Retrieve the NSURL for the .spf file for this connection instance (if any)
+ */
+- (NSURL *)fileURL
+{
+ return [[spfFileURL copy] autorelease];
}
/*
@@ -3883,27 +4017,13 @@
/**
* The window title for this document.
*/
-- (NSString *)displaySPName
+- (NSString *)displayName
{
if (!_isConnected) {
return [NSString stringWithFormat:@"%@%@",
([[[self fileURL] path] length] && ![self isUntitled]) ? [NSString stringWithFormat:@"%@ — ",[[[self fileURL] path] lastPathComponent]] : @"", @"Sequel Pro"];
}
-
- return [NSString stringWithFormat:@"%@%@ %@%@%@",
- ([[[self fileURL] path] length] && ![self isUntitled]) ? [NSString stringWithFormat:@"%@ — ",[self displayName]] : @"",
- ([prefs boolForKey:SPDisplayServerVersionInWindowTitle]) ? [NSString stringWithFormat:@"(MySQL %@)", mySQLVersion] : @"",
- [self name],
- ([self database]?[NSString stringWithFormat:@"/%@",[self database]]:@""),
- ([[self table] length]?[NSString stringWithFormat:@"/%@",[self table]]:@"")];
-}
-/**
- * The window title for this document.
- */
-- (NSString *)displayName
-{
- if(!_isConnected) return [self displaySPName];
return [[[self fileURL] path] lastPathComponent];
}
@@ -3916,7 +4036,10 @@
- (void)connectionControllerInitiatingConnection:(id)controller
{
// Update the window title to indicate that we are try to establish a connection
- [tableWindow setTitle:NSLocalizedString(@"Connecting…", @"window title string indicating that sp is connecting")];
+ [parentTabViewItem setLabel:NSLocalizedString(@"Connecting…", @"window title string indicating that sp is connecting")];
+ if ([parentWindowController selectedTableDocument] == self) {
+ [parentWindow setTitle:NSLocalizedString(@"Connecting…", @"window title string indicating that sp is connecting")];
+ }
}
/**
@@ -3925,7 +4048,7 @@
- (void)connectionControllerConnectAttemptFailed:(id)controller
{
// Reset the window title
- [tableWindow setTitle:[self displaySPName]];
+ [self updateWindowTitle:self];
}
#pragma mark -
@@ -4105,6 +4228,7 @@
*/
- (void)dealloc
{
+NSLog(@"is dealloc'd");
// Unregister observers
[prefs removeObserver:self forKeyPath:SPDisplayTableViewVerticalGridlines];
@@ -4123,6 +4247,9 @@
[[NSNotificationCenter defaultCenter] removeObserver:self];
[NSObject cancelPreviousPerformRequestsWithTarget:self];
+ for (id retainedObject in nibObjectsToRelease) [retainedObject release];
+ [nibObjectsToRelease release];
+
[_encoding release];
[allDatabases release];
[allSystemDatabases release];
@@ -4138,10 +4265,14 @@
if (taskDrawTimer) [taskDrawTimer release];
if (taskFadeAnimator) [taskFadeAnimator release];
if (queryEditorInitString) [queryEditorInitString release];
+ if (spfFileURL) [spfFileURL release];
if (spfPreferences) [spfPreferences release];
if (spfSession) [spfSession release];
if (spfDocData) [spfDocData release];
if (keyChainID) [keyChainID release];
+ if (mainToolbar) [mainToolbar release];
+ if (titleAccessoryView) [titleAccessoryView release];
+ if (taskProgressWindow) [taskProgressWindow release];
[super dealloc];
}
@@ -4152,12 +4283,12 @@
- (void)_copyDatabase {
if ([[databaseCopyNameField stringValue] isEqualToString:@""]) {
- SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil, nil, NSLocalizedString(@"Database must have a name.", @"message of panel when no db name is given"));
+ SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, parentWindow, self, nil, nil, NSLocalizedString(@"Database must have a name.", @"message of panel when no db name is given"));
return;
}
SPDatabaseCopy *dbActionCopy = [[SPDatabaseCopy alloc] init];
[dbActionCopy setConnection: [self getConnection]];
- [dbActionCopy setMessageWindow: tableWindow];
+ [dbActionCopy setMessageWindow: parentWindow];
BOOL copyWithContent = [copyDatabaseDataButton state] == NSOnState;
@@ -4172,12 +4303,12 @@
- (void)_renameDatabase {
if ([[databaseRenameNameField stringValue] isEqualToString:@""]) {
- SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil, nil, NSLocalizedString(@"Database must have a name.", @"message of panel when no db name is given"));
+ SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, parentWindow, self, nil, nil, NSLocalizedString(@"Database must have a name.", @"message of panel when no db name is given"));
return;
}
SPDatabaseRename *dbActionRename = [[SPDatabaseRename alloc] init];
[dbActionRename setConnection: [self getConnection]];
- [dbActionRename setMessageWindow: tableWindow];
+ [dbActionRename setMessageWindow: parentWindow];
if ([dbActionRename renameDatabaseFrom: [self database]
to: [databaseRenameNameField stringValue]]) {
@@ -4195,7 +4326,7 @@
// This check is not necessary anymore as the add database button is now only enabled if the name field
// has a length greater than zero. We'll leave it in just in case.
if ([[databaseNameField stringValue] isEqualToString:@""]) {
- SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil, nil, NSLocalizedString(@"Database must have a name.", @"message of panel when no db name is given"));
+ SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, parentWindow, self, nil, nil, NSLocalizedString(@"Database must have a name.", @"message of panel when no db name is given"));
return;
}
@@ -4211,14 +4342,14 @@
if ([mySQLConnection queryErrored]) {
// An error occurred
- SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil, nil, [NSString stringWithFormat:NSLocalizedString(@"Couldn't create database.\nMySQL said: %@", @"message of panel when creation of db failed"), [mySQLConnection getLastErrorMessage]]);
+ SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, parentWindow, self, nil, nil, [NSString stringWithFormat:NSLocalizedString(@"Couldn't create database.\nMySQL said: %@", @"message of panel when creation of db failed"), [mySQLConnection getLastErrorMessage]]);
return;
}
// Error while selecting the new database (is this even possible?)
if (![mySQLConnection selectDB:[databaseNameField stringValue]] ) {
- SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil, nil, [NSString stringWithFormat:NSLocalizedString(@"Unable to connect to database %@.\nBe sure that you have the necessary privileges.", @"message of panel when connection to db failed after selecting from popupbutton"), [databaseNameField stringValue]]);
+ SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, parentWindow, self, nil, nil, [NSString stringWithFormat:NSLocalizedString(@"Unable to connect to database %@.\nBe sure that you have the necessary privileges.", @"message of panel when connection to db failed after selecting from popupbutton"), [databaseNameField stringValue]]);
[self setDatabases:self];
@@ -4235,7 +4366,7 @@
[tablesListInstance setConnection:mySQLConnection];
[tableDumpInstance setConnection:mySQLConnection];
- [tableWindow setTitle:[self displaySPName]];
+ [self updateWindowTitle:self];
}
/**
@@ -4274,8 +4405,7 @@
[tablesListInstance setConnection:mySQLConnection];
[tableDumpInstance setConnection:mySQLConnection];
- [tableWindow setTitle:[self displaySPName]];
-
+ [self updateWindowTitle:self];
}
/**
@@ -4301,7 +4431,7 @@
|| ![mySQLConnection selectDB:targetDatabaseName])
{
if ( [mySQLConnection isConnected] ) {
- SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil, nil, [NSString stringWithFormat:NSLocalizedString(@"Unable to connect to database %@.\nBe sure that you have the necessary privileges.", @"message of panel when connection to db failed after selecting from popupbutton"), targetDatabaseName]);
+ SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, parentWindow, self, nil, nil, [NSString stringWithFormat:NSLocalizedString(@"Unable to connect to database %@.\nBe sure that you have the necessary privileges.", @"message of panel when connection to db failed after selecting from popupbutton"), targetDatabaseName]);
// Update the database list
[self setDatabases:self];
@@ -4328,7 +4458,7 @@
[tableDumpInstance setConnection:mySQLConnection];
// Update the window title
- [[tableWindow onMainThread] setTitle:[self displaySPName]];
+ [[self onMainThread] updateWindowTitle:self];
// Add a history entry
if (!historyStateChanging) {
@@ -4339,9 +4469,9 @@
// Set focus to table list filter field if visible
// otherwise set focus to Table List view
if ( [[tablesListInstance tables] count] > 20 )
- [[tableWindow onMainThread] makeFirstResponder:listFilterField];
+ [[parentWindow onMainThread] makeFirstResponder:listFilterField];
else
- [[tableWindow onMainThread] makeFirstResponder:[tablesListInstance valueForKeyPath:@"tablesListView"]];
+ [[parentWindow onMainThread] makeFirstResponder:[tablesListInstance valueForKeyPath:@"tablesListView"]];
}
// If a the table has changed, update the selection
2576' href='#n2576'>2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646