aboutsummaryrefslogtreecommitdiffstats
path: root/Source/SPDatabaseDocument.m
diff options
context:
space:
mode:
Diffstat (limited to 'Source/SPDatabaseDocument.m')
-rw-r--r--Source/SPDatabaseDocument.m434
1 files changed, 218 insertions, 216 deletions
diff --git a/Source/SPDatabaseDocument.m b/Source/SPDatabaseDocument.m
index 6b61a99e..d19b3f4c 100644
--- a/Source/SPDatabaseDocument.m
+++ b/Source/SPDatabaseDocument.m
@@ -29,22 +29,13 @@
//
// More info at <https://github.com/sequelpro/sequelpro>
-// Forward-declare for 10.7 compatibility
-#if !defined(MAC_OS_X_VERSION_10_7) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
-enum {
- NSFullScreenWindowMask = 1 << 14
-};
-#endif
-
#import "SPDatabaseDocument.h"
#import "SPConnectionController.h"
#import "SPConnectionHandler.h"
#import "SPConnectionControllerInitializer.h"
-
#import "SPTablesList.h"
#import "SPTableStructure.h"
#import "SPDatabaseStructure.h"
-#ifndef SP_CODA /* headers */
#import "SPFileHandle.h"
#import "SPKeychain.h"
#import "SPTableContent.h"
@@ -55,20 +46,14 @@ enum {
#import "SPGrowlController.h"
#import "SPExportController.h"
#import "SPSplitView.h"
-#endif
#import "SPQueryController.h"
#import "SPQueryDocumentsController.h"
-#ifndef SP_CODA /* headers */
#import "SPWindowController.h"
-#endif
#import "SPNavigatorController.h"
-#ifndef SP_CODA /* headers */
#import "SPSQLParser.h"
#import "SPTableData.h"
-#endif
#import "SPDatabaseData.h"
#import "SPDatabaseStructure.h"
-#ifndef SP_CODA /* headers */
#import "SPAppController.h"
#import "SPWindowManagement.h"
#import "SPExtendedTableInfo.h"
@@ -86,92 +71,56 @@ enum {
#import "SPDatabaseRename.h"
#import "SPTableRelations.h"
#import "SPCopyTable.h"
-#endif
#import "SPServerSupport.h"
-#ifndef SP_CODA /* headers */
#import "SPTooltip.h"
-#endif
#import "SPDatabaseViewController.h"
-#ifndef SP_CODA /* headers */
#import "SPBundleHTMLOutputController.h"
#import "SPConnectionDelegate.h"
-#endif
#import "SPThreadAdditions.h"
#import "RegexKitLite.h"
#import "SPTextView.h"
#import "SPFavoriteColorSupport.h"
-
-#ifdef SP_CODA /* headers */
-#import "SPAlertSheets.h"
-#import "NSNotificationCenterThreadingAdditions.h"
-#import "SPCustomQuery.h"
-#import "SPDatabaseRename.h"
-#endif
-
#import "SPCharsetCollationHelper.h"
#import "SPGotoDatabaseController.h"
#import "SPFunctions.h"
+#import "SPCreateDatabaseInfo.h"
#import <SPMySQL/SPMySQL.h>
#include <libkern/OSAtomic.h>
// Constants
+static NSString *SPCopyDatabaseAction = @"SPCopyDatabase";
+static NSString *SPConfirmCopyDatabaseAction = @"SPConfirmCopyDatabase";
static NSString *SPRenameDatabaseAction = @"SPRenameDatabase";
static NSString *SPAlterDatabaseAction = @"SPAlterDatabase";
+
static int64_t SPDatabaseDocumentInstanceCounter = 0;
@interface SPDatabaseDocument ()
- (void)_addDatabase;
- (void)_alterDatabase;
-
-#ifndef SP_CODA /* method decls */
- (void)_copyDatabase;
-#endif
-
- (void)_renameDatabase;
- (void)_removeDatabase;
- (void)_selectDatabaseAndItem:(NSDictionary *)selectionDetails;
-
-#ifndef SP_CODA /* method decls */
- (void)_processDatabaseChangedBundleTriggerActions;
-#endif
+- (void)_addPreferenceObservers;
+- (void)_removePreferenceObservers;
@end
@implementation SPDatabaseDocument
-#ifndef SP_CODA /* ivars */
@synthesize sqlFileURL;
@synthesize sqlFileEncoding;
@synthesize parentWindowController;
@synthesize parentTabViewItem;
-#endif
@synthesize isProcessing;
@synthesize serverSupport;
@synthesize databaseStructureRetrieval;
-#ifndef SP_CODA /* ivars */
@synthesize processID;
-#endif
-
-#ifdef SP_CODA /* ivars */
-@synthesize allDatabases;
-@synthesize delegate;
-@synthesize tableDataInstance;
-@synthesize customQueryInstance;
-@synthesize queryProgressBar;
-@synthesize databaseSheet;
-@synthesize databaseNameField;
-@synthesize databaseEncodingButton;
-@synthesize addDatabaseButton;
-@synthesize databaseDataInstance;
-@synthesize databaseRenameSheet;
-@synthesize databaseRenameNameField;
-@synthesize renameDatabaseButton;
-@synthesize chooseDatabaseButton;
-@synthesize structureContentSwitcher;
-#endif
@synthesize instanceId;
#pragma mark -
@@ -280,7 +229,6 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0;
- (void)awakeFromNib
{
-#ifndef SP_CODA
if (_mainNibLoaded) return;
_mainNibLoaded = YES;
@@ -313,35 +261,24 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0;
// Set the connection controller's delegate
[connectionController setDelegate:self];
- // Register observers for when the DisplayTableViewVerticalGridlines preference changes
- [prefs addObserver:self forKeyPath:SPDisplayTableViewVerticalGridlines options:NSKeyValueObservingOptionNew context:NULL];
- [prefs addObserver:tableSourceInstance forKeyPath:SPDisplayTableViewVerticalGridlines options:NSKeyValueObservingOptionNew context:NULL];
- [prefs addObserver:tableContentInstance forKeyPath:SPDisplayTableViewVerticalGridlines options:NSKeyValueObservingOptionNew context:NULL];
- [prefs addObserver:customQueryInstance forKeyPath:SPDisplayTableViewVerticalGridlines options:NSKeyValueObservingOptionNew context:NULL];
- [prefs addObserver:tableRelationsInstance forKeyPath:SPDisplayTableViewVerticalGridlines options:NSKeyValueObservingOptionNew context:NULL];
- [prefs addObserver:[SPQueryController sharedQueryController] forKeyPath:SPDisplayTableViewVerticalGridlines options:NSKeyValueObservingOptionNew context:NULL];
-
- // Register observers for the when the UseMonospacedFonts preference changes
- [prefs addObserver:tableSourceInstance forKeyPath:SPUseMonospacedFonts options:NSKeyValueObservingOptionNew context:NULL];
- [prefs addObserver:[SPQueryController sharedQueryController] forKeyPath:SPUseMonospacedFonts options:NSKeyValueObservingOptionNew context:NULL];
+ // Register preference observers to allow live UI-linked preference changes
+ [self _addPreferenceObservers];
- [prefs addObserver:tableContentInstance forKeyPath:SPGlobalResultTableFont options:NSKeyValueObservingOptionNew context:NULL];
- [prefs addObserver:tableContentInstance forKeyPath:SPDisplayBinaryDataAsHex options:NSKeyValueObservingOptionNew context:NULL];
-
- // Register observers for when the logging preference changes
- [prefs addObserver:[SPQueryController sharedQueryController] forKeyPath:SPConsoleEnableLogging options:NSKeyValueObservingOptionNew context:NULL];
+ // Register for notifications
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(willPerformQuery:)
+ name:@"SMySQLQueryWillBePerformed"
+ object:self];
- // 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];
-#endif
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(hasPerformedQuery:)
+ name:@"SMySQLQueryHasBeenPerformed"
+ object:self];
- // 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];
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(applicationWillTerminate:)
+ name:@"NSApplicationWillTerminateNotification"
+ object:nil];
#ifndef SP_CODA
// Find the Database -> Database Encoding menu (it's not in our nib, so we can't use interface builder)
@@ -466,6 +403,10 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0;
#pragma mark -
#pragma mark Connection callback and methods
+/**
+ *
+ * This method *MUST* be called from the UI thread!
+ */
- (void)setConnection:(SPMySQLConnection *)theConnection
{
if ([theConnection userTriggeredDisconnect]) {
@@ -483,7 +424,10 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0;
#ifndef SP_CODA
// Set the fileURL and init the preferences (query favs, filters, and history) if available for that URL
- [self setFileURL:[[SPQueryController sharedQueryController] registerDocumentWithFileURL:[self fileURL] andContextInfo:spfPreferences]];
+ NSURL *newURL = [[SPQueryController sharedQueryController] registerDocumentWithFileURL:[self fileURL] andContextInfo:spfPreferences];
+#warning debug code for #2266
+ if(!newURL) NSLog(@"#2266: Trying to set nil fileURL in %s from queryController=%@ oldFileURL=%@ contextInfo=%@", __func__, [SPQueryController sharedQueryController], [self fileURL], spfPreferences);
+ [self setFileURL:newURL];
// ...but hide the icon while the document is temporary
if ([self isUntitled]) [[parentWindow standardWindowButton:NSWindowDocumentIconButton] setImage:nil];
@@ -652,7 +596,7 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0;
*
* @return The document's connection
*/
-- (SPMySQLConnection *) getConnection
+- (SPMySQLConnection *)getConnection
{
return mySQLConnection;
}
@@ -660,9 +604,9 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0;
/**
* Sets this connection's Keychain ID.
*/
-- (void)setKeychainID:(NSString *)theID
+- (void)setKeychainID:(NSString *)theId
{
- keyChainID = [[NSString stringWithString:theID] retain];
+ keyChainID = [[NSString stringWithString:theId] retain];
}
#pragma mark -
@@ -670,6 +614,8 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0;
/**
* sets up the database select toolbar item
+ *
+ * This method *MUST* be called from the UI thread!
*/
- (IBAction)setDatabases:(id)sender;
{
@@ -928,7 +874,24 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0;
- (IBAction)copyDatabase:(id)sender
{
if (![tablesListInstance selectionShouldChangeInTableView:nil]) return;
-
+
+ // Inform the user that we don't support copying objects other than tables and ask them if they'd like to proceed
+ if ([tablesListInstance hasNonTableObjects]) {
+ [SPAlertSheets beginWaitingAlertSheetWithTitle:NSLocalizedString(@"Only Partially Supported", @"partial copy database support message")
+ defaultButton:NSLocalizedString(@"Continue", "continue button")
+ alternateButton:NSLocalizedString(@"Cancel", @"cancel button")
+ otherButton:nil
+ alertStyle:NSAlertStyleWarning
+ docWindow:parentWindow
+ modalDelegate:self
+ didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:)
+ contextInfo:SPConfirmCopyDatabaseAction
+ infoText:[NSString stringWithFormat:NSLocalizedString(@"Duplicating the database '%@' is only partially supported as it contains objects other tables (i.e. views, procedures, functions, etc.), which will not be copied.\n\nWould you like to continue?", @"partial copy database support informative message"), selectedDatabase]
+ returnCode:&confirmCopyDatabaseReturnCode];
+
+ if (confirmCopyDatabaseReturnCode == NSAlertAlternateReturn) return;
+ }
+
[databaseCopyNameField setStringValue:selectedDatabase];
[copyDatabaseMessageField setStringValue:selectedDatabase];
@@ -936,16 +899,29 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0;
modalForWindow:parentWindow
modalDelegate:self
didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:)
- contextInfo:@"copyDatabase"];
+ contextInfo:SPCopyDatabaseAction];
}
#endif
/**
- * opens the rename database sheet and renames the databsae
+ * Opens the rename database sheet and renames the databsae.
*/
- (IBAction)renameDatabase:(id)sender
{
if (![tablesListInstance selectionShouldChangeInTableView:nil]) return;
+
+ // We currently don't support moving any objects other than tables (i.e. views, functions, procs, etc.) from one database to another
+ // so inform the user and don't allow them to proceed. Copy/duplicate is more appropriate in this case, but with the same limitation.
+ if ([tablesListInstance hasNonTableObjects]) {
+ SPOnewayAlertSheet(
+ NSLocalizedString(@"Database Rename Unsupported", @"databsse rename unsupported message"),
+ parentWindow,
+ [NSString stringWithFormat:NSLocalizedString(
+ @"Ranaming the database '%@' is currently unsupported as it contains objects other than tables (i.e. views, procedures, functions, etc.).\n\nIf you would like to rename a database please use the 'Duplicate Database', move any non-table objects manually then drop the old database.",
+ @"databsse rename unsupported informative message"), selectedDatabase]
+ );
+ return;
+ }
[databaseRenameNameField setStringValue:selectedDatabase];
[renameDatabaseMessageField setStringValue:[NSString stringWithFormat:NSLocalizedString(@"Rename database '%@' to:", @"rename database message"), selectedDatabase]];
@@ -972,8 +948,8 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0;
NSAlert *alert = [NSAlert alertWithMessageText:[NSString stringWithFormat:NSLocalizedString(@"Delete database '%@'?", @"delete database message"), [self database]]
defaultButton:NSLocalizedString(@"Delete", @"delete button")
alternateButton:NSLocalizedString(@"Cancel", @"cancel button")
- otherButton:nil
- informativeTextWithFormat:NSLocalizedString(@"Are you sure you want to delete the database '%@'? This operation cannot be undone.", @"delete database informative message"), [self database]];
+ otherButton:nil
+ informativeTextWithFormat:NSLocalizedString(@"Are you sure you want to delete the database '%@'? This operation cannot be undone.", @"delete database informative message"), [self database]];
NSArray *buttons = [alert buttons];
@@ -1010,9 +986,6 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0;
serverVariablesController = [[SPServerVariablesController alloc] init];
[serverVariablesController setConnection:mySQLConnection];
-
- // Register to obeserve table view vertical grid line pref changes
- [prefs addObserver:serverVariablesController forKeyPath:SPDisplayTableViewVerticalGridlines options:NSKeyValueObservingOptionNew context:NULL];
}
[serverVariablesController displayServerVariablesSheetAttachedToWindow:parentWindow];
@@ -1027,9 +1000,6 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0;
processListController = [[SPProcessListController alloc] init];
[processListController setConnection:mySQLConnection];
-
- // Register to obeserve table view vertical grid line pref changes
- [prefs addObserver:processListController forKeyPath:SPDisplayTableViewVerticalGridlines options:NSKeyValueObservingOptionNew context:NULL];
}
[processListController displayProcessListWindow];
@@ -1088,26 +1058,29 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0;
/**
* Alert sheet method. Invoked when an alert sheet is dismissed.
- *
- * if contextInfo == removeDatabase -> Remove the selected database
- * if contextInfo == addDatabase -> Add a new database
- * if contextInfo == copyDatabase -> Duplicate the selected database
- * if contextInfo == renameDatabase -> Rename the selected database
*/
- (void)sheetDidEnd:(id)sheet returnCode:(NSInteger)returnCode contextInfo:(NSString *)contextInfo
{
#ifndef SP_CODA
- if([contextInfo isEqualToString:@"saveDocPrefSheetStatus"]) {
+
+ // Those that are just setting a return code and don't need to order out the sheet. See SPAlertSheets+beginWaitingAlertSheetWithTitle:
+ if ([contextInfo isEqualToString:@"saveDocPrefSheetStatus"]) {
saveDocPrefSheetStatus = returnCode;
return;
}
+ else if ([contextInfo isEqualToString:SPConfirmCopyDatabaseAction]) {
+ confirmCopyDatabaseReturnCode = returnCode;
+ return;
+ }
#endif
// Order out current sheet to suppress overlapping of sheets
- if ([sheet respondsToSelector:@selector(orderOut:)])
+ if ([sheet respondsToSelector:@selector(orderOut:)]) {
[sheet orderOut:nil];
- else if ([sheet respondsToSelector:@selector(window)])
+ }
+ else if ([sheet respondsToSelector:@selector(window)]) {
[[sheet window] orderOut:nil];
+ }
// Remove the current database
if ([contextInfo isEqualToString:@"removeDatabase"]) {
@@ -1147,7 +1120,7 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0;
}
}
#ifndef SP_CODA
- else if ([contextInfo isEqualToString:@"copyDatabase"]) {
+ else if ([contextInfo isEqualToString:SPCopyDatabaseAction]) {
if (returnCode == NSOKButton) {
[self _copyDatabase];
}
@@ -1197,6 +1170,8 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0;
/**
* Reset the current selected database name
+ *
+ * This method MAY be called from UI and background threads!
*/
- (void)refreshCurrentDatabase
{
@@ -1214,23 +1189,21 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0;
dbName = NSArrayObjectAtIndex(eachRow, 0);
}
- // TODO: there have been crash reports because dbName == nil at this point. When could that happen?
- if(dbName && ![dbName isNSNull]) {
- if(![dbName isEqualToString:selectedDatabase]) {
+ SPMainQSync(^{
+ // TODO: there have been crash reports because dbName == nil at this point. When could that happen?
+ if(dbName && ![dbName isNSNull]) {
+ if(![dbName isEqualToString:selectedDatabase]) {
+ if (selectedDatabase) SPClear(selectedDatabase);
+ selectedDatabase = [[NSString alloc] initWithString:dbName];
+ [chooseDatabaseButton selectItemWithTitle:selectedDatabase];
+ [self updateWindowTitle:self];
+ }
+ } else {
if (selectedDatabase) SPClear(selectedDatabase);
- selectedDatabase = [[NSString alloc] initWithString:dbName];
- [chooseDatabaseButton selectItemWithTitle:selectedDatabase];
-#ifndef SP_CODA /* [self updateWindowTitle:self] */
+ [chooseDatabaseButton selectItemAtIndex:0];
[self updateWindowTitle:self];
-#endif
}
- } else {
- if (selectedDatabase) SPClear(selectedDatabase);
- [chooseDatabaseButton selectItemAtIndex:0];
-#ifndef SP_CODA /* [self updateWindowTitle:self] */
- [self updateWindowTitle:self];
-#endif
- }
+ });
}
//query finished
@@ -3399,7 +3372,7 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0;
if(!spf || ![spf count] || readError != nil || [convError length] || !(format == NSPropertyListXMLFormat_v1_0 || format == NSPropertyListBinaryFormat_v1_0)) {
- [SPAlertSheets beginWaitingAlertSheetWithTitle:@"title"
+ [SPAlertSheets beginWaitingAlertSheetWithTitle:[NSString stringWithFormat:NSLocalizedString(@"Error while reading connection data file", @"error while reading connection data file")]
defaultButton:NSLocalizedString(@"OK", @"OK button")
alternateButton:NSLocalizedString(@"Ignore", @"ignore button")
otherButton:nil
@@ -3408,7 +3381,6 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0;
modalDelegate:self
didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:)
contextInfo:@"saveDocPrefSheetStatus"
- msg:[NSString stringWithFormat:NSLocalizedString(@"Error while reading connection data file", @"error while reading connection data file")]
infoText:[NSString stringWithFormat:NSLocalizedString(@"Connection data file “%@” couldn't be read. Please try to save the document under a different name.", @"message error while reading connection data file and suggesting to save it under a differnet name"), [fileName lastPathComponent]]
returnCode:&saveDocPrefSheetStatus];
@@ -3564,7 +3536,10 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0;
[preferences setObject:[spfStructure objectForKey:SPContentFilters] forKey:SPContentFilters];
[[SPQueryController sharedQueryController] registerDocumentWithFileURL:[NSURL fileURLWithPath:fileName] andContextInfo:preferences];
- [self setFileURL:[NSURL fileURLWithPath:fileName]];
+ NSURL *newURL = [NSURL fileURLWithPath:fileName];
+#warning debug code for #2266
+ if(!newURL) NSLog(@"#2266: Trying to set nil fileURL in %s from fileName=%@", __func__, fileName);
+ [self setFileURL:newURL];
[[NSDocumentController sharedDocumentController] noteNewRecentDocumentURL:[NSURL fileURLWithPath:fileName]];
[self updateWindowTitle:self];
@@ -4008,10 +3983,11 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0;
if (newIsVisible == windowTitleStatusViewIsVisible) return;
if (newIsVisible) {
- if (NSClassFromString(@"NSTitlebarAccessoryViewController")) { // OS X 10.11 and later
+ Class controllerClass;
+ if ((controllerClass = NSClassFromString(@"NSTitlebarAccessoryViewController"))) { // OS X 10.11 and later
[titleAccessoryView setFrame:NSMakeRect(0, 0, titleAccessoryView.frame.size.width, 120)]; // make it really tall, so that it's on the top right of the title/toolbar area, instead of the bottom right (AppKit will not prevent it from going behind the toolbar)
- NSTitlebarAccessoryViewController *accessoryViewController = [[[NSTitlebarAccessoryViewController alloc] init] autorelease];
+ NSTitlebarAccessoryViewController *accessoryViewController = [[[controllerClass alloc] init] autorelease];
accessoryViewController.view = titleAccessoryView;
accessoryViewController.layoutAttribute = NSLayoutAttributeRight;
[parentWindow addTitlebarAccessoryViewController:accessoryViewController];
@@ -4492,6 +4468,7 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0;
{
// Coax the main split view into actually checking its constraints
[contentViewSplitter setPosition:[[[contentViewSplitter subviews] objectAtIndex:0] bounds].size.width ofDividerAtIndex:0];
+
// If the task interface is visible, and this tab is frontmost, re-center the task child window
if (_isWorkingLevel && [parentWindowController selectedTableDocument] == self) [self centerTaskWindow];
}
@@ -4500,17 +4477,19 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0;
/**
* Set the parent window
*/
-- (void)setParentWindow:(NSWindow *)aWindow
+- (void)setParentWindow:(NSWindow *)window
{
-#ifndef SP_CODA
+ NSWindow *favoritesOutlineViewWindow = [(NSView *)[connectionController favoritesOutlineView] window];
+
// If the window is being set for the first time - connection controller is visible - update focus
- if (!parentWindow && !mySQLConnection) {
- [aWindow makeFirstResponder:(NSResponder *)[connectionController favoritesOutlineView]];
+ if (!parentWindow && !mySQLConnection && window == favoritesOutlineViewWindow) {
+ [window makeFirstResponder:(NSResponder *)[connectionController favoritesOutlineView]];
}
-#endif
- parentWindow = aWindow;
+ parentWindow = window;
+
SPSSHTunnel *currentTunnel = [connectionController valueForKeyPath:@"sshTunnel"];
+
if (currentTunnel) [currentTunnel setParentWindow:parentWindow];
}
@@ -5118,7 +5097,10 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0;
}
if (![self isSaveInBundle]) {
- [self setFileURL:[NSURL fileURLWithPath:path]];
+ NSURL *newURL = [NSURL fileURLWithPath:path];
+#warning debug code for #2266
+ if(!newURL) NSLog(@"#2266: Trying to set nil fileURL in %s from path=%@", __func__, path);
+ [self setFileURL:newURL];
}
[spfDocData setObject:[NSNumber numberWithBool:([[data objectForKey:@"connection"] objectForKey:@"password"]) ? YES : NO] forKey:@"save_password"];
@@ -5794,7 +5776,7 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0;
);
}
-- (void)registerActivity:(NSDictionary*)commandDict
+- (void)registerActivity:(NSDictionary *)commandDict
{
[runningActivitiesArray addObject:commandDict];
[[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:SPActivitiesUpdateNotification object:self];
@@ -5832,74 +5814,74 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0;
[[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:SPActivitiesUpdateNotification object:self];
}
-- (void)setActivityPaneHidden:(NSNumber*)hide
+- (void)setActivityPaneHidden:(NSNumber *)hide
{
- if(hide.boolValue) {
- [tableInfoScrollView setHidden:YES];
- [documentActivityScrollView setHidden:NO];
- } else {
+ if (hide.boolValue) {
[documentActivityScrollView setHidden:YES];
[tableInfoScrollView setHidden:NO];
}
+ else {
+ [tableInfoScrollView setHidden:YES];
+ [documentActivityScrollView setHidden:NO];
+ }
}
-- (NSArray*)runningActivities
+- (NSArray *)runningActivities
{
return (NSArray*)runningActivitiesArray;
}
-- (NSDictionary*)shellVariables
+- (NSDictionary *)shellVariables
{
-
- if(!_isConnected) return @{};
+ if (!_isConnected) return @{};
NSMutableDictionary *env = [NSMutableDictionary dictionary];
if (tablesListInstance) {
- if([tablesListInstance selectedDatabase])
+
+ if ([tablesListInstance selectedDatabase]) {
[env setObject:[tablesListInstance selectedDatabase] forKey:SPBundleShellVariableSelectedDatabase];
+ }
- if ([tablesListInstance tableName])
+ if ([tablesListInstance tableName]) {
[env setObject:[tablesListInstance tableName] forKey:SPBundleShellVariableSelectedTable];
+ }
- if ([tablesListInstance selectedTableItems])
+ if ([tablesListInstance selectedTableItems]) {
[env setObject:[[tablesListInstance selectedTableItems] componentsJoinedByString:@"\t"] forKey:SPBundleShellVariableSelectedTables];
+ }
- if ([tablesListInstance allDatabaseNames])
+ if ([tablesListInstance allDatabaseNames]) {
[env setObject:[[tablesListInstance allDatabaseNames] componentsJoinedByString:@"\t"] forKey:SPBundleShellVariableAllDatabases];
+ }
- if ([tablesListInstance allTableNames])
- [env setObject:[[tablesListInstance allTableNames] componentsJoinedByString:@"\t"] forKey:SPBundleShellVariableAllTables];
-
- if ([tablesListInstance allViewNames])
- [env setObject:[[tablesListInstance allViewNames] componentsJoinedByString:@"\t"] forKey:SPBundleShellVariableAllViews];
-
- if ([tablesListInstance allFunctionNames])
- [env setObject:[[tablesListInstance allFunctionNames] componentsJoinedByString:@"\t"] forKey:SPBundleShellVariableAllFunctions];
-
- if ([tablesListInstance allProcedureNames])
- [env setObject:[[tablesListInstance allProcedureNames] componentsJoinedByString:@"\t"] forKey:SPBundleShellVariableAllProcedures];
-
- if ([self user])
+ if ([self user]) {
[env setObject:[self user] forKey:SPBundleShellVariableCurrentUser];
+ }
- if ([self host])
+ if ([self host]) {
[env setObject:[self host] forKey:SPBundleShellVariableCurrentHost];
+ }
- if ([self port])
+ if ([self port]) {
[env setObject:[self port] forKey:SPBundleShellVariableCurrentPort];
+ }
- [env setObject:([self databaseEncoding])?:@"" forKey:SPBundleShellVariableDatabaseEncoding];
+ [env setObject:[[tablesListInstance allTableNames] componentsJoinedByString:@"\t"] forKey:SPBundleShellVariableAllTables];
+ [env setObject:[[tablesListInstance allViewNames] componentsJoinedByString:@"\t"] forKey:SPBundleShellVariableAllViews];
+ [env setObject:[[tablesListInstance allFunctionNames] componentsJoinedByString:@"\t"] forKey:SPBundleShellVariableAllFunctions];
+ [env setObject:[[tablesListInstance allProcedureNames] componentsJoinedByString:@"\t"] forKey:SPBundleShellVariableAllProcedures];
+ [env setObject:([self databaseEncoding]) ? : @"" forKey:SPBundleShellVariableDatabaseEncoding];
}
- if(1)
- [env setObject:@"mysql" forKey:SPBundleShellVariableRDBMSType];
+ [env setObject:@"mysql" forKey:SPBundleShellVariableRDBMSType];
- if([self mySQLVersion])
+ if ([self mySQLVersion]) {
[env setObject:[self mySQLVersion] forKey:SPBundleShellVariableRDBMSVersion];
+ }
- return (NSDictionary*)env;
+ return (NSDictionary *)env;
}
#endif
@@ -6092,6 +6074,10 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0;
#ifndef SP_CODA /* whole database operations */
+/**
+ *
+ * This method *MUST* be called from the UI thread!
+ */
- (void)_copyDatabase
{
if ([[databaseCopyNameField stringValue] isEqualToString:@""]) {
@@ -6124,6 +6110,10 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0;
}
#endif
+/**
+ *
+ * This method *MUST* be called from the UI thread!
+ */
- (void)_renameDatabase
{
NSString *newDatabaseName = [databaseRenameNameField stringValue];
@@ -6168,6 +6158,8 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0;
/**
* Adds a new database.
+ *
+ * This method *MUST* be called from the UI thread!
*/
- (void)_addDatabase
{
@@ -6238,6 +6230,8 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0;
/**
* Removes the current database.
+ *
+ * This method *MUST* be called from the UI thread!
*/
- (void)_removeDatabase
{
@@ -6454,35 +6448,64 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0;
}
#endif
-#pragma mark -
+/**
+ * Add any necessary preference observers to allow live updating on changes.
+ */
+- (void)_addPreferenceObservers
+{
+ // Register observers for when the DisplayTableViewVerticalGridlines preference changes
+ [prefs addObserver:self forKeyPath:SPDisplayTableViewVerticalGridlines options:NSKeyValueObservingOptionNew context:NULL];
+ [prefs addObserver:tableSourceInstance forKeyPath:SPDisplayTableViewVerticalGridlines options:NSKeyValueObservingOptionNew context:NULL];
+ [prefs addObserver:tableContentInstance forKeyPath:SPDisplayTableViewVerticalGridlines options:NSKeyValueObservingOptionNew context:NULL];
+ [prefs addObserver:customQueryInstance forKeyPath:SPDisplayTableViewVerticalGridlines options:NSKeyValueObservingOptionNew context:NULL];
+ [prefs addObserver:tableRelationsInstance forKeyPath:SPDisplayTableViewVerticalGridlines options:NSKeyValueObservingOptionNew context:NULL];
+ [prefs addObserver:[SPQueryController sharedQueryController] forKeyPath:SPDisplayTableViewVerticalGridlines options:NSKeyValueObservingOptionNew context:NULL];
-- (void)dealloc
+ // Register observers for the when the UseMonospacedFonts preference changes
+ [prefs addObserver:tableSourceInstance forKeyPath:SPUseMonospacedFonts options:NSKeyValueObservingOptionNew context:NULL];
+ [prefs addObserver:[SPQueryController sharedQueryController] forKeyPath:SPUseMonospacedFonts options:NSKeyValueObservingOptionNew context:NULL];
+
+ [prefs addObserver:tableContentInstance forKeyPath:SPGlobalResultTableFont options:NSKeyValueObservingOptionNew context:NULL];
+ [prefs addObserver:tableContentInstance forKeyPath:SPDisplayBinaryDataAsHex options:NSKeyValueObservingOptionNew context:NULL];
+
+ // Register observers for when the logging preference changes
+ [prefs addObserver:[SPQueryController sharedQueryController] forKeyPath:SPConsoleEnableLogging options:NSKeyValueObservingOptionNew context:NULL];
+
+ // 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];
+}
+
+/**
+ * Remove any previously added preference observers.
+ */
+- (void)_removePreferenceObservers
{
- NSAssert([NSThread isMainThread], @"Calling %s from a background thread is not supported!",__func__);
-#ifndef SP_CODA /* Unregister observers */
- // Unregister observers
+ [prefs removeObserver:self forKeyPath:SPConsoleEnableLogging];
[prefs removeObserver:self forKeyPath:SPDisplayTableViewVerticalGridlines];
- [prefs removeObserver:tableSourceInstance forKeyPath:SPDisplayTableViewVerticalGridlines];
- [prefs removeObserver:tableContentInstance forKeyPath:SPDisplayTableViewVerticalGridlines];
- [prefs removeObserver:customQueryInstance forKeyPath:SPDisplayTableViewVerticalGridlines];
- [prefs removeObserver:tableRelationsInstance forKeyPath:SPDisplayTableViewVerticalGridlines];
- [prefs removeObserver:[SPQueryController sharedQueryController] forKeyPath:SPDisplayTableViewVerticalGridlines];
+
[prefs removeObserver:tableSourceInstance forKeyPath:SPUseMonospacedFonts];
- [prefs removeObserver:[SPQueryController sharedQueryController] forKeyPath:SPUseMonospacedFonts];
+
[prefs removeObserver:tableContentInstance forKeyPath:SPGlobalResultTableFont];
[prefs removeObserver:tableContentInstance forKeyPath:SPDisplayBinaryDataAsHex];
+
+ [prefs removeObserver:customQueryInstance forKeyPath:SPDisplayTableViewVerticalGridlines];
+ [prefs removeObserver:tableRelationsInstance forKeyPath:SPDisplayTableViewVerticalGridlines];
+ [prefs removeObserver:tableSourceInstance forKeyPath:SPDisplayTableViewVerticalGridlines];
+ [prefs removeObserver:tableContentInstance forKeyPath:SPDisplayTableViewVerticalGridlines];
+
+ [prefs removeObserver:[SPQueryController sharedQueryController] forKeyPath:SPUseMonospacedFonts];
[prefs removeObserver:[SPQueryController sharedQueryController] forKeyPath:SPConsoleEnableLogging];
- [prefs removeObserver:self forKeyPath:SPConsoleEnableLogging];
-
- if (processListController) {
- [processListController close];
- [prefs removeObserver:processListController forKeyPath:SPDisplayTableViewVerticalGridlines];
- }
-
- if (serverVariablesController) {
- [prefs removeObserver:serverVariablesController forKeyPath:SPDisplayTableViewVerticalGridlines];
- }
-#endif
+ [prefs removeObserver:[SPQueryController sharedQueryController] forKeyPath:SPDisplayTableViewVerticalGridlines];
+}
+
+#pragma mark -
+
+- (void)dealloc
+{
+ NSAssert([NSThread isMainThread], @"Calling %s from a background thread is not supported!", __func__);
+
+ // Unregister observers
+ [self _removePreferenceObservers];
[[NSNotificationCenter defaultCenter] removeObserver:self];
[NSObject cancelPreviousPerformRequestsWithTarget:self];
@@ -6490,13 +6513,11 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0;
// see -(void)awakeFromNib for the reasoning behind this.
SPClear(chooseDatabaseButton);
SPClear(historyControl);
-
-#ifndef SP_CODA /* release nib objects */
+
for (id retainedObject in nibObjectsToRelease) [retainedObject release];
SPClear(nibObjectsToRelease);
-#endif
-
+
// Tell listeners that this database document is being closed - fixes retain cycles and allows cleanup
[[NSNotificationCenter defaultCenter] postNotificationName:SPDocumentWillCloseNotification object:self];
@@ -6505,55 +6526,36 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0;
SPClear(allDatabases);
SPClear(allSystemDatabases);
SPClear(gotoDatabaseController);
-#ifndef SP_CODA /* dealloc ivars */
SPClear(undoManager);
SPClear(printWebView);
-#endif
SPClear(selectedDatabaseEncoding);
-#ifndef SP_CODA
+
[taskProgressWindow close];
-#endif
+ if (processListController) [processListController close];
+
if (selectedTableName) SPClear(selectedTableName);
if (connectionController) SPClear(connectionController);
-#ifndef SP_CODA /* dealloc ivars */
if (processListController) SPClear(processListController);
if (serverVariablesController) SPClear(serverVariablesController);
-#endif
if (mySQLConnection) SPClear(mySQLConnection);
if (selectedDatabase) SPClear(selectedDatabase);
if (mySQLVersion) SPClear(mySQLVersion);
-#ifndef SP_CODA
if (taskDrawTimer) [taskDrawTimer invalidate], SPClear(taskDrawTimer);
if (taskFadeInStartDate) SPClear(taskFadeInStartDate);
-#endif
if (queryEditorInitString) SPClear(queryEditorInitString);
-#ifndef SP_CODA
if (sqlFileURL) SPClear(sqlFileURL);
if (spfFileURL) SPClear(spfFileURL);
if (spfPreferences) SPClear(spfPreferences);
if (spfSession) SPClear(spfSession);
if (spfDocData) SPClear(spfDocData);
-#endif
if (keyChainID) SPClear(keyChainID);
-#ifndef SP_CODA
if (mainToolbar) SPClear(mainToolbar);
-#endif
if (titleAccessoryView) SPClear(titleAccessoryView);
-#ifndef SP_CODA
if (taskProgressWindow) SPClear(taskProgressWindow);
-#endif
if (serverSupport) SPClear(serverSupport);
-#ifndef SP_CODA /* dealloc ivars */
if (processID) SPClear(processID);
if (runningActivitiesArray) SPClear(runningActivitiesArray);
-#endif
-
-#ifdef SP_CODA
- if (tablesListInstance) [tablesListInstance release];
- if (customQueryInstance) [customQueryInstance release];
-#endif
-
if (alterDatabaseCharsetHelper) SPClear(alterDatabaseCharsetHelper);
if (addDatabaseCharsetHelper) SPClear(addDatabaseCharsetHelper);