diff options
-rw-r--r-- | Source/MainController.h | 52 | ||||
-rw-r--r-- | Source/MainController.m | 756 | ||||
-rw-r--r-- | Source/SPExportController.h | 91 | ||||
-rw-r--r-- | Source/SPExportController.m | 177 | ||||
-rw-r--r-- | Source/SPFavoriteTextFieldCell.h | 44 | ||||
-rw-r--r-- | Source/SPFavoriteTextFieldCell.m | 239 | ||||
-rw-r--r-- | Source/SPPreferenceController.h | 74 | ||||
-rw-r--r-- | Source/SPPreferenceController.m | 574 | ||||
-rw-r--r-- | Source/SPTableInfo.m | 2 | ||||
-rw-r--r-- | Source/SPWindowAdditions.h | 30 | ||||
-rw-r--r-- | Source/SPWindowAdditions.m | 75 | ||||
-rw-r--r-- | Source/TableContent.m | 104 | ||||
-rw-r--r-- | Source/TableDocument.h | 3 | ||||
-rw-r--r-- | Source/TableDocument.m | 42 | ||||
-rw-r--r-- | Source/TableDump.h | 13 | ||||
-rw-r--r-- | Source/TableDump.m | 68 | ||||
-rw-r--r-- | Source/TableSource.m | 16 | ||||
-rw-r--r-- | Source/TablesList.m | 11 |
18 files changed, 1546 insertions, 825 deletions
diff --git a/Source/MainController.h b/Source/MainController.h index b47bb457..656cf8c0 100644 --- a/Source/MainController.h +++ b/Source/MainController.h @@ -24,63 +24,29 @@ #import <Cocoa/Cocoa.h> +@class SPPreferenceController; + @interface MainController : NSObject { - IBOutlet id keyChainInstance; - - IBOutlet id preferencesWindow; - IBOutlet id favoriteSheet; - IBOutlet id reloadAfterAddingSwitch; - IBOutlet id reloadAfterEditingSwitch; - IBOutlet id reloadAfterRemovingSwitch; - IBOutlet id showErrorSwitch; - IBOutlet id dontShowBlobSwitch; - IBOutlet id useMonospacedFontsSwitch; - IBOutlet id fetchRowCountSwitch; - IBOutlet id limitRowsSwitch; - IBOutlet id limitRowsField; - IBOutlet id nullValueField; - IBOutlet id tableView; - IBOutlet id nameField; - IBOutlet id hostField; - IBOutlet id socketField; - IBOutlet id userField; - IBOutlet id passwordField; - IBOutlet id portField; - IBOutlet id databaseField; - IBOutlet id sshCheckbox; - IBOutlet id sshUserField; - IBOutlet id sshPasswordField; - IBOutlet id sshHostField; - IBOutlet id sshPortField; - IBOutlet id encodingPopUpButton; - + BOOL isNewFavorite; + NSMutableArray *favorites; - NSUserDefaults *prefs; - BOOL isNewFavorite; + SPPreferenceController *prefsController; } -//IBAction methods +// IBAction methods - (IBAction)openPreferences:(id)sender; -- (IBAction)addFavorite:(id)sender; -- (IBAction)removeFavorite:(id)sender; -- (IBAction)copyFavorite:(id)sender; -- (IBAction)chooseLimitRows:(id)sender; -- (IBAction)closeFavoriteSheet:(id)sender; -- (IBAction)toggleUseSSH:(id)sender; -//services menu methods +// Services menu methods - (void)doPerformQueryService:(NSPasteboard *)pboard userData:(NSString *)data error:(NSString **)error; -//menu methods +// Menu methods - (IBAction)donate:(id)sender; - (IBAction)visitWebsite:(id)sender; - (IBAction)visitHelpWebsite:(id)sender; -- (IBAction)checkForUpdates:(id)sender; -//SSHTunnel methods -- (id)authenticate:(NSScriptCommand *)command; +// Other - (id)handleQuitScriptCommand:(NSScriptCommand *)command; @end diff --git a/Source/MainController.m b/Source/MainController.m index 47a55ca5..06f5d739 100644 --- a/Source/MainController.m +++ b/Source/MainController.m @@ -25,747 +25,119 @@ #import "MainController.h" #import "KeyChain.h" #import "TableDocument.h" +#import "SPPreferenceController.h" + +#define SEQUEL_PRO_HOME_PAGE_URL @"http://www.sequelpro.com/" +#define SEQUEL_PRO_DONATIONS_URL @"http://code.google.com/p/sequel-pro/wiki/Donations" +#define SEQUEL_PRO_FAQ_URL @"http://www.sequelpro.com/frequently-asked-questions.html" @implementation MainController -/* -opens the preferences window -*/ -- (IBAction)openPreferences:(id)sender +/** + * Called even before init so we can register our preference defaults + */ ++ (void)initialize { - - // Synchronize the prefs to disk to pick up any changes made to favourites in connection sheets - [prefs synchronize]; - - //get favorites if they exist - [favorites release]; - if ( [prefs objectForKey:@"favorites"] != nil ) { - favorites = [[NSMutableArray alloc] initWithArray:[prefs objectForKey:@"favorites"]]; - } else { - favorites = [[NSMutableArray array] retain]; - } - [tableView reloadData]; - - if ( [prefs boolForKey:@"reloadAfterAdding"] ) { - [reloadAfterAddingSwitch setState:NSOnState]; - } else { - [reloadAfterAddingSwitch setState:NSOffState]; - } - if ( [prefs boolForKey:@"reloadAfterEditing"] ) { - [reloadAfterEditingSwitch setState:NSOnState]; - } else { - [reloadAfterEditingSwitch setState:NSOffState]; - } - if ( [prefs boolForKey:@"reloadAfterRemoving"] ) { - [reloadAfterRemovingSwitch setState:NSOnState]; - } else { - [reloadAfterRemovingSwitch setState:NSOffState]; - } - if ( [prefs boolForKey:@"showError"] ) { - [showErrorSwitch setState:NSOnState]; - } else { - [showErrorSwitch setState:NSOffState]; - } - if ( [prefs boolForKey:@"dontShowBlob"] ) { - [dontShowBlobSwitch setState:NSOnState]; - } else { - [dontShowBlobSwitch setState:NSOffState]; - } - if ( [prefs boolForKey:@"limitRows"] ) { - [limitRowsSwitch setState:NSOnState]; - } else { - [limitRowsSwitch setState:NSOffState]; - } - if ( [prefs boolForKey:@"useMonospacedFonts"] ) { - [useMonospacedFontsSwitch setState:NSOnState]; - } else { - [useMonospacedFontsSwitch setState:NSOffState]; - } - if ( [prefs boolForKey:@"fetchRowCount"] ) { - [fetchRowCountSwitch setState:NSOnState]; - } else { - [fetchRowCountSwitch setState:NSOffState]; - } - [nullValueField setStringValue:[prefs stringForKey:@"nullValue"]]; - [limitRowsField setStringValue:[prefs stringForKey:@"limitRowsValue"]]; - [self chooseLimitRows:self]; - [encodingPopUpButton selectItemWithTitle:[prefs stringForKey:@"encoding"]]; - - [preferencesWindow makeKeyAndOrderFront:self]; + // Register application defaults + [[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"PreferenceDefaults" ofType:@"plist"]]]; } -/* -adds a favorite -*/ -- (IBAction)addFavorite:(id)sender +/** + * Initialisation stuff upon nib awakening + */ +- (void)awakeFromNib { - int code; - - isNewFavorite = YES; - - [nameField setStringValue:@""]; - [hostField setStringValue:@""]; - [socketField setStringValue:@""]; - [userField setStringValue:@""]; - [passwordField setStringValue:@""]; - [portField setStringValue:@""]; - [databaseField setStringValue:@""]; - [sshCheckbox setState:NSOffState]; - [sshUserField setEnabled:NO]; - [sshPasswordField setEnabled:NO]; - [sshHostField setEnabled:NO]; - [sshPortField setEnabled:NO]; - [sshHostField setStringValue:@""]; - [sshUserField setStringValue:@""]; - [sshPortField setStringValue:@"8888"]; - [sshPasswordField setStringValue:@""]; - - [NSApp beginSheet:favoriteSheet - modalForWindow:preferencesWindow - modalDelegate:self - didEndSelector:nil - contextInfo:nil]; + prefsController = [[SPPreferenceController alloc] init]; - code = [NSApp runModalForWindow:favoriteSheet]; - - [NSApp endSheet:favoriteSheet]; - [favoriteSheet orderOut:nil]; + // Register MainController as services provider + [NSApp setServicesProvider:self]; - if ( code == 1 ) { - if ( ![[socketField stringValue] isEqualToString:@""] ) { - //set host to localhost if socket is used - [hostField setStringValue:@"localhost"]; - } - - // get ssh settings - NSString *sshHost, *sshUser, *sshPassword, *sshPort; - NSNumber *ssh; - if ( [sshCheckbox state] == NSOnState ) { - if ( [[sshHostField stringValue] isEqualToString:@""] ) { - sshHost = [hostField stringValue]; - } else { - sshHost = [sshHostField stringValue]; - } - if ( [[sshUserField stringValue] isEqualToString:@""] ) { - sshUser = [userField stringValue]; - } else { - sshUser = [sshUserField stringValue]; - } - if ( [[sshPasswordField stringValue] isEqualToString:@""] ) { - sshPassword = [passwordField stringValue]; - } else { - sshPassword = [sshPasswordField stringValue]; - } - if ( [[sshPortField stringValue] isEqualToString:@""] ) { - sshPort = [portField stringValue]; - } else { - sshPort = [sshPortField stringValue]; - } - ssh = [NSNumber numberWithInt:1]; - } else { - sshHost = @""; - sshUser = @""; - sshPassword = @""; - sshPort = @""; - ssh = [NSNumber numberWithInt:0]; - } - - NSDictionary *favorite = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:[nameField stringValue], [hostField stringValue], [socketField stringValue], [userField stringValue], [portField stringValue], [databaseField stringValue], ssh, sshHost, sshUser, sshPort, nil] - forKeys:[NSArray arrayWithObjects:@"name", @"host", @"socket", @"user", @"port", @"database", @"useSSH", @"sshHost", @"sshUser", @"sshPort", nil]]; - [favorites addObject:favorite]; - - if ( ![[passwordField stringValue] isEqualToString:@""] ) - [keyChainInstance addPassword:[passwordField stringValue] - forName:[NSString stringWithFormat:@"Sequel Pro : %@", [nameField stringValue]] - account:[NSString stringWithFormat:@"%@@%@/%@", [userField stringValue], [hostField stringValue], [databaseField stringValue]]]; - - if ( ![sshPassword isEqualToString:@""] ) - [keyChainInstance addPassword:sshPassword - forName:[NSString stringWithFormat:@"Sequel Pro SSHTunnel : %@", [nameField stringValue]] - account:[NSString stringWithFormat:@"%@@%@/%@", [userField stringValue], [hostField stringValue], [databaseField stringValue]]]; - - [tableView reloadData]; - [tableView selectRow:[tableView numberOfRows]-1 byExtendingSelection:NO]; - } + // Register MainController for AppleScript events + [[NSScriptExecutionContext sharedScriptExecutionContext] setTopLevelObject:self]; isNewFavorite = NO; } -/* -removes a favorite -*/ -- (IBAction)removeFavorite:(id)sender -{ - if ( ![tableView numberOfSelectedRows] ) - return; - - NSString *name = [[favorites objectAtIndex:[tableView selectedRow]] objectForKey:@"name"]; - NSString *user = [[favorites objectAtIndex:[tableView selectedRow]] objectForKey:@"user"]; - NSString *host = [[favorites objectAtIndex:[tableView selectedRow]] objectForKey:@"host"]; - NSString *database = [[favorites objectAtIndex:[tableView selectedRow]] objectForKey:@"database"]; - - [keyChainInstance deletePasswordForName:[NSString stringWithFormat:@"Sequel Pro : %@", name] - account:[NSString stringWithFormat:@"%@@%@/%@", user, host, database]]; - [keyChainInstance deletePasswordForName:[NSString stringWithFormat:@"Sequel Pro SSHTunnel : %@", name] - account:[NSString stringWithFormat:@"%@@%@/%@", user, host, database]]; - [favorites removeObjectAtIndex:[tableView selectedRow]]; - [tableView reloadData]; -} - -/* -copies a favorite -*/ -- (IBAction)copyFavorite:(id)sender -{ - if ( ![tableView numberOfSelectedRows] ) - return; - - NSMutableDictionary *tempDictionary = [NSMutableDictionary dictionaryWithDictionary:[favorites objectAtIndex:[tableView selectedRow]]]; - [tempDictionary setObject:[NSString stringWithFormat:@"%@Copy", [tempDictionary objectForKey:@"name"]] forKey:@"name"]; -// [tempDictionary setObject:[NSString stringWithFormat:@"%@Copy", [tempDictionary objectForKey:@"user"]] forKey:@"user"]; - - [favorites insertObject:tempDictionary atIndex:[tableView selectedRow]+1]; - [tableView selectRow:[tableView selectedRow]+1 byExtendingSelection:NO]; - - [tableView reloadData]; -} - -/* -enables or disables limitRowsField (depending on the state of limitRowsSwitch) -*/ -- (IBAction)chooseLimitRows:(id)sender -{ - if ( [limitRowsSwitch state] == NSOnState ) { - [limitRowsField setEnabled:YES]; - [limitRowsField selectText:self]; - } else { - [limitRowsField setEnabled:NO]; - } -} +#pragma mark - +#pragma mark IBAction methods -/* -close the favoriteSheet and save favorite if user hit save -*/ -- (IBAction)closeFavoriteSheet:(id)sender -{ - NSEnumerator *enumerator = [favorites objectEnumerator]; - id favorite; - int count; - - //test if user has entered at least name and host/socket - if ( [sender tag] && - ([[nameField stringValue] isEqualToString:@""] || ([[hostField stringValue] isEqualToString:@""] && [[socketField stringValue] isEqualToString:@""])) ) { - NSRunAlertPanel(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"Please enter at least name and host or socket!", @"message of panel when name/host/socket are missing"), NSLocalizedString(@"OK", @"OK button"), nil, nil); - return; - } - - //test if favorite name isn't used by another favorite - count = 0; - if ( [sender tag] ) { - while ( (favorite = [enumerator nextObject]) ) { - if ( [[favorite objectForKey:@"name"] isEqualToString:[nameField stringValue]] ) - { - if ( isNewFavorite || (!isNewFavorite && (count != [tableView selectedRow])) ) { - NSRunAlertPanel(NSLocalizedString(@"Error", @"error"), [NSString stringWithFormat:NSLocalizedString(@"Favorite %@ has already been saved!\nPlease specify another name.", @"message of panel when favorite name has already been used"), [nameField stringValue]], NSLocalizedString(@"OK", @"OK button"), nil, nil); - return; - } - } -/* - if ( [[favorite objectForKey:@"host"] isEqualToString:[hostField stringValue]] && - [[favorite objectForKey:@"user"] isEqualToString:[userField stringValue]] && - [[favorite objectForKey:@"database"] isEqualToString:[databaseField stringValue]] ) { - if ( isNewFavorite || (!isNewFavorite && (count != [tableView selectedRow])) ) { - NSRunAlertPanel(@"Error", @"There is already a favorite with the same host, user and database!", @"OK", nil, nil); - return; - } - } -*/ - count++; - } - } - - [NSApp stopModalWithCode:[sender tag]]; -} - -/* -enables/disables ssh tunneling -*/ -- (IBAction)toggleUseSSH:(id)sender +/** + * Opens the preferences window + */ +- (IBAction)openPreferences:(id)sender { - if ( [sshCheckbox state] == NSOnState ) { - [sshUserField setEnabled:YES]; - [sshPasswordField setEnabled:YES]; - [sshHostField setEnabled:YES]; - [sshPortField setEnabled:YES]; - } else { - [sshUserField setEnabled:NO]; - [sshPasswordField setEnabled:NO]; - [sshHostField setEnabled:NO]; - [sshPortField setEnabled:NO]; - } + [prefsController showWindow:self]; } +#pragma mark - #pragma mark Services menu methods -/* -passes the query to the last created document -*/ +/** + * Passes the query to the last created document + */ - (void)doPerformQueryService:(NSPasteboard *)pboard userData:(NSString *)data error:(NSString **)error { NSString *pboardString; - NSArray *types; - - types = [pboard types]; - - if (![types containsObject:NSStringPboardType] || !(pboardString = [pboard stringForType:NSStringPboardType])) { + + NSArray *types = [pboard types]; + + if ((![types containsObject:NSStringPboardType]) || (!(pboardString = [pboard stringForType:NSStringPboardType]))) { *error = @"Pasteboard couldn't give string."; + return; } - - //check if there exists a document - if ( ![[[NSDocumentController sharedDocumentController] documents] count] ) { + + // Check if at least one document exists + if (![[[NSDocumentController sharedDocumentController] documents] count]) { *error = @"No Documents open!"; + return; } - - //pass query to last created document -// [[[NSDocumentController sharedDocumentController] currentDocument] doPerformQueryService:pboardString]; - [[[[NSDocumentController sharedDocumentController] documents] objectAtIndex:[[[NSDocumentController sharedDocumentController] documents] count]-1] doPerformQueryService:pboardString]; - + + // Pass query to last created document + [[[[NSDocumentController sharedDocumentController] documents] objectAtIndex:([[[NSDocumentController sharedDocumentController] documents] count] - 1)] doPerformQueryService:pboardString]; + return; } - +#pragma mark - #pragma mark Sequel Pro menu methods -/* -opens donate link in default browser -*/ +/** + * Opens donate link in default browser + */ - (IBAction)donate:(id)sender { - [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://www.sequelpro.com/donate.html"]]; -} - -/* -opens website link in default browser -*/ -- (IBAction)visitWebsite:(id)sender -{ - [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://www.sequelpro.com/"]]; -} - -/* -opens help link in default browser -*/ -- (IBAction)visitHelpWebsite:(id)sender -{ - [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://www.sequelpro.com/frequently-asked-questions.html"]]; -} - -/* -checks for updates and opens download page in default browser -*/ -- (IBAction)checkForUpdates:(id)sender -{ - NSLog(@"[MainController checkForUpdates:] is not currently functional."); -} - - -#pragma mark TableView datasource methods - -- (int)numberOfRowsInTableView:(NSTableView *)aTableView -{ - return [favorites count]; -} - -- (id)tableView:(NSTableView *)aTableView - objectValueForTableColumn:(NSTableColumn *)aTableColumn - row:(int)rowIndex -{ - return [[favorites objectAtIndex:rowIndex] objectForKey:[aTableColumn identifier]]; -} - - -#pragma mark TableView drag & drop datasource methods - -- (BOOL)tableView:(NSTableView *)tv writeRows:(NSArray*)rows toPasteboard:(NSPasteboard*)pboard -{ - int originalRow; - NSArray *pboardTypes; - - if ( [rows count] == 1 ) { - pboardTypes=[NSArray arrayWithObjects:@"SequelProPreferencesPasteboard", nil]; - originalRow = [[rows objectAtIndex:0] intValue]; - - [pboard declareTypes:pboardTypes owner:nil]; - [pboard setString:[[NSNumber numberWithInt:originalRow] stringValue] forType:@"SequelProPreferencesPasteboard"]; - - return YES; - } else { - return NO; - } -} - -- (NSDragOperation)tableView:(NSTableView*)tv validateDrop:(id <NSDraggingInfo>)info proposedRow:(int)row - proposedDropOperation:(NSTableViewDropOperation)operation -{ - NSArray *pboardTypes = [[info draggingPasteboard] types]; - int originalRow; - - if ([pboardTypes count] == 1 && row != -1) - { - if ([[pboardTypes objectAtIndex:0] isEqualToString:@"SequelProPreferencesPasteboard"]==YES && operation==NSTableViewDropAbove) - { - originalRow = [[[info draggingPasteboard] stringForType:@"SequelProPreferencesPasteboard"] intValue]; - - if (row != originalRow && row != (originalRow+1)) - { - return NSDragOperationMove; - } - } - } - - return NSDragOperationNone; + [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:SEQUEL_PRO_DONATIONS_URL]]; } -- (BOOL)tableView:(NSTableView*)tv acceptDrop:(id <NSDraggingInfo>)info row:(int)row dropOperation:(NSTableViewDropOperation)operation -{ - int originalRow; - int destinationRow; - NSMutableDictionary *draggedRow; - - originalRow = [[[info draggingPasteboard] stringForType:@"SequelProPreferencesPasteboard"] intValue]; - destinationRow = row; - - if ( destinationRow > originalRow ) - destinationRow--; - - draggedRow = [NSMutableDictionary dictionaryWithDictionary:[favorites objectAtIndex:originalRow]]; - [favorites removeObjectAtIndex:originalRow]; - [favorites insertObject:draggedRow atIndex:destinationRow]; - - [tableView reloadData]; - [tableView selectRow:destinationRow byExtendingSelection:NO]; - - return YES; -} - -/* - opens sheet to edit favorite and saves favorite if user hit OK +/** + * Opens website link in default browser */ -- (BOOL)tableView:(NSTableView *)aTableView shouldEditTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex +- (IBAction)visitWebsite:(id)sender { - int code; - NSDictionary *favorite = [favorites objectAtIndex:rowIndex]; - - // set up fields - [nameField setStringValue:[favorite objectForKey:@"name"]]; - [hostField setStringValue:[favorite objectForKey:@"host"]]; - [socketField setStringValue:[favorite objectForKey:@"socket"]]; - [userField setStringValue:[favorite objectForKey:@"user"]]; - [portField setStringValue:[favorite objectForKey:@"port"]]; - [databaseField setStringValue:[favorite objectForKey:@"database"]]; - [passwordField setStringValue:[keyChainInstance getPasswordForName:[NSString stringWithFormat:@"Sequel Pro : %@", [nameField stringValue]] - account:[NSString stringWithFormat:@"%@@%@/%@", [userField stringValue], [hostField stringValue], [databaseField stringValue]]]]; - - // set up ssh fields - if ( [[favorite objectForKey:@"useSSH"] intValue] == 1 ) { - [sshCheckbox setState:NSOnState]; - [sshUserField setEnabled:YES]; - [sshPasswordField setEnabled:YES]; - [sshHostField setEnabled:YES]; - [sshPortField setEnabled:YES]; - [sshHostField setStringValue:[favorite objectForKey:@"sshHost"]]; - [sshUserField setStringValue:[favorite objectForKey:@"sshUser"]]; - [sshPortField setStringValue:[favorite objectForKey:@"sshPort"]]; - [sshPasswordField setStringValue:[keyChainInstance getPasswordForName:[NSString stringWithFormat:@"Sequel Pro SSHTunnel : %@", [nameField stringValue]] - account:[NSString stringWithFormat:@"%@@%@/%@", [userField stringValue], [hostField stringValue], [databaseField stringValue]]]]; - } else { - [sshCheckbox setState:NSOffState]; - [sshUserField setEnabled:NO]; - [sshPasswordField setEnabled:NO]; - [sshHostField setEnabled:NO]; - [sshPortField setEnabled:NO]; - [sshHostField setStringValue:@""]; - [sshUserField setStringValue:@""]; - [sshPortField setStringValue:@""]; - [sshPasswordField setStringValue:@""]; - } - - // run sheet - [NSApp beginSheet:favoriteSheet - modalForWindow:preferencesWindow - modalDelegate:self - didEndSelector:nil - contextInfo:nil]; - - code = [NSApp runModalForWindow:favoriteSheet]; - - [NSApp endSheet:favoriteSheet]; - [favoriteSheet orderOut:nil]; - - if ( code == 1 ) { - if ( ![[socketField stringValue] isEqualToString:@""] ) { - //set host to localhost if socket is used - [hostField setStringValue:@"localhost"]; - } - - //get ssh settings - NSString *sshHost, *sshUser, *sshPassword, *sshPort; - NSNumber *ssh; - if ( [sshCheckbox state] == NSOnState ) { - if ( [[sshHostField stringValue] isEqualToString:@""] ) { - sshHost = [hostField stringValue]; - } else { - sshHost = [sshHostField stringValue]; - } - if ( [[sshUserField stringValue] isEqualToString:@""] ) { - sshUser = [userField stringValue]; - } else { - sshUser = [sshUserField stringValue]; - } - if ( [[sshPasswordField stringValue] isEqualToString:@""] ) { - sshPassword = [passwordField stringValue]; - } else { - sshPassword = [sshPasswordField stringValue]; - } - if ( [[sshPortField stringValue] isEqualToString:@""] ) { - sshPort = [portField stringValue]; - } else { - sshPort = [sshPortField stringValue]; - } - ssh = [NSNumber numberWithInt:1]; - } else { - sshHost = @""; - sshUser = @""; - sshPassword = @""; - sshPort = @""; - ssh = [NSNumber numberWithInt:0]; - } - - //replace password - [keyChainInstance deletePasswordForName:[NSString stringWithFormat:@"Sequel Pro : %@", [favorite objectForKey:@"name"]] - account:[NSString stringWithFormat:@"%@@%@/%@", [favorite objectForKey:@"user"], [favorite objectForKey:@"host"], [favorite objectForKey:@"database"]]]; - - if ( ![[passwordField stringValue] isEqualToString:@""] ) - [keyChainInstance addPassword:[passwordField stringValue] - forName:[NSString stringWithFormat:@"Sequel Pro : %@", [nameField stringValue]] - account:[NSString stringWithFormat:@"%@@%@/%@", [userField stringValue], [hostField stringValue], [databaseField stringValue]]]; - - //replace ssh password - [keyChainInstance deletePasswordForName:[NSString stringWithFormat:@"Sequel Pro SSHTunnel : %@", [favorite objectForKey:@"name"]] - account:[NSString stringWithFormat:@"%@@%@/%@", [favorite objectForKey:@"user"], [favorite objectForKey:@"host"], [favorite objectForKey:@"database"]]]; - - if ( ([sshCheckbox state] == NSOnState) && ![sshPassword isEqualToString:@""] ) { - [keyChainInstance addPassword:sshPassword - forName:[NSString stringWithFormat:@"Sequel Pro SSHTunnel : %@", [nameField stringValue]] - account:[NSString stringWithFormat:@"%@@%@/%@", [userField stringValue], [hostField stringValue], - [databaseField stringValue]]]; - } - - //replace favorite - favorite = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:[nameField stringValue], [hostField stringValue], [socketField stringValue], [userField stringValue], [portField stringValue], [databaseField stringValue], ssh, sshHost, sshUser, sshPort, nil] - forKeys:[NSArray arrayWithObjects:@"name", @"host", @"socket", @"user", @"port", @"database", @"useSSH", @"sshHost", @"sshUser", @"sshPort", nil]]; - [favorites replaceObjectAtIndex:rowIndex withObject:favorite]; - [tableView reloadData]; - } - - return NO; + [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:SEQUEL_PRO_HOME_PAGE_URL]]; } - -#pragma mark Window delegate methods - -/* - saves the preferences +/** + * Opens help link in default browser */ -- (BOOL)windowShouldClose:(id)sender +- (IBAction)visitHelpWebsite:(id)sender { - if ( sender == preferencesWindow ) { - if ( [reloadAfterAddingSwitch state] == NSOnState ) { - [prefs setBool:YES forKey:@"reloadAfterAdding"]; - } else { - [prefs setBool:NO forKey:@"reloadAfterAdding"]; - } - if ( [reloadAfterEditingSwitch state] == NSOnState ) { - [prefs setBool:YES forKey:@"reloadAfterEditing"]; - } else { - [prefs setBool:NO forKey:@"reloadAfterEditing"]; - } - if ( [reloadAfterRemovingSwitch state] == NSOnState ) { - [prefs setBool:YES forKey:@"reloadAfterRemoving"]; - } else { - [prefs setBool:NO forKey:@"reloadAfterRemoving"]; - } - if ( [showErrorSwitch state] == NSOnState ) { - [prefs setBool:YES forKey:@"showError"]; - } else { - [prefs setBool:NO forKey:@"showError"]; - } - if ( [dontShowBlobSwitch state] == NSOnState ) { - [prefs setBool:YES forKey:@"dontShowBlob"]; - } else { - [prefs setBool:NO forKey:@"dontShowBlob"]; - } - if ( [limitRowsSwitch state] == NSOnState ) { - [prefs setBool:YES forKey:@"limitRows"]; - } else { - [prefs setBool:NO forKey:@"limitRows"]; - } - if ( [useMonospacedFontsSwitch state] == NSOnState ) { - [prefs setBool:YES forKey:@"useMonospacedFonts"]; - } else { - [prefs setBool:NO forKey:@"useMonospacedFonts"]; - } - if ( [fetchRowCountSwitch state] == NSOnState ) { - [prefs setBool:YES forKey:@"fetchRowCount"]; - } else { - [prefs setBool:NO forKey:@"fetchRowCount"]; - } - [prefs setObject:[nullValueField stringValue] forKey:@"nullValue"]; - if ( [limitRowsField intValue] > 0 ) { - [prefs setInteger:[limitRowsField intValue] forKey:@"limitRowsValue"]; - } else { - [prefs setInteger:1 forKey:@"limitRowsValue"]; - } - [prefs setObject:[encodingPopUpButton titleOfSelectedItem] forKey:@"encoding"]; - - [prefs setObject:favorites forKey:@"favorites"]; - [prefs synchronize]; - } - return YES; + [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:SEQUEL_PRO_FAQ_URL]]; } - +#pragma mark - #pragma mark Other methods -- (void)awakeFromNib -{ - int currentVersionNumber; - - // Register MainController as services provider - [NSApp setServicesProvider:self]; - - // Register MainController for AppleScript events - [[NSScriptExecutionContext sharedScriptExecutionContext] setTopLevelObject:self]; - - // Get the current bundle version number (the SVN build number) for per-version upgrades - currentVersionNumber = [[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"] intValue]; - - prefs = [[NSUserDefaults standardUserDefaults] retain]; - isNewFavorite = NO; - [prefs registerDefaults:[NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithBool:YES], @"reloadAfterAdding", - [NSNumber numberWithBool:YES], @"reloadAfterEditing", - [NSNumber numberWithBool:NO], @"reloadAfterRemoving", - [NSString stringWithString:@"NULL"], @"nullValue", - [NSNumber numberWithBool:YES], @"showError", - [NSNumber numberWithBool:NO], @"dontShowBlob", - [NSString stringWithString:NSHomeDirectory()], @"savePath", - [NSString stringWithString:NSHomeDirectory()], @"openPath", - [NSString stringWithString:@"Autodetect"], @"encoding", - [NSNumber numberWithBool:NO], @"useMonospacedFonts", - [NSNumber numberWithBool:YES], @"fetchRowCount", - [NSNumber numberWithBool:YES], @"limitRows", - [NSNumber numberWithInt:1000], @"limitRowsValue", - [NSNumber numberWithInt:10], @"connectionTimeout", - [NSNumber numberWithInt:60], @"keepAliveInterval", - [NSNumber numberWithInt:0], @"lastUsedVersion", - [NSNumber numberWithBool:YES], @"CustomQueryAutopair", - [NSNumber numberWithBool:YES], @"CustomQueryAutoindent", - [NSNumber numberWithBool:NO], @"CustomQueryAutouppercaseKeywords", - [NSArchiver archivedDataWithRootObject:[NSFont fontWithName:@"Monaco" size:10.0]], @"CustomQueryEditorFont", - nil]]; - - // For versions prior to r336, where column widths have been saved, walk through them and remove - // any table widths set to 15 or less (fix for mangled columns caused by Issue #140) - if ([[prefs objectForKey:@"lastUsedVersion"] intValue] < 336 && [prefs objectForKey:@"tableColumnWidths"] != nil) { - NSEnumerator *databaseEnumerator, *tableEnumerator, *columnEnumerator; - NSString *databaseKey, *tableKey, *columnKey; - NSMutableDictionary *newDatabase, *newTable; - float columnWidth; - NSMutableDictionary *newTableColumnWidths = [[NSMutableDictionary alloc] init]; - - databaseEnumerator = [[prefs objectForKey:@"tableColumnWidths"] keyEnumerator]; - while (databaseKey = [databaseEnumerator nextObject]) { - newDatabase = [[NSMutableDictionary alloc] init]; - tableEnumerator = [[[prefs objectForKey:@"tableColumnWidths"] objectForKey:databaseKey] keyEnumerator]; - while (tableKey = [tableEnumerator nextObject]) { - newTable = [[NSMutableDictionary alloc] init]; - columnEnumerator = [[[[prefs objectForKey:@"tableColumnWidths"] objectForKey:databaseKey] objectForKey:tableKey] keyEnumerator]; - while (columnKey = [columnEnumerator nextObject]) { - columnWidth = [[[[[prefs objectForKey:@"tableColumnWidths"] objectForKey:databaseKey] objectForKey:tableKey] objectForKey:columnKey] floatValue]; - if (columnWidth >= 15) { - [newTable setObject:[NSNumber numberWithFloat:columnWidth] forKey:[NSString stringWithString:columnKey]]; - } - } - if ([newTable count]) { - [newDatabase setObject:[NSDictionary dictionaryWithDictionary:newTable] forKey:[NSString stringWithString:tableKey]]; - } - [newTable release]; - } - if ([newDatabase count]) { - [newTableColumnWidths setObject:[NSDictionary dictionaryWithDictionary:newDatabase] forKey:[NSString stringWithString:databaseKey]]; - } - [newDatabase release]; - } - [prefs setObject:[NSDictionary dictionaryWithDictionary:newTableColumnWidths] forKey:@"tableColumnWidths"]; - [newTableColumnWidths release]; - } - - // Write the current bundle version to the prefs - [prefs setObject:[NSNumber numberWithInt:currentVersionNumber] forKey:@"lastUsedVersion"]; - - [tableView registerForDraggedTypes:[NSArray arrayWithObjects:@"SequelProPreferencesPasteboard", nil]]; - [tableView reloadData]; -} - - -// SSHTunnel methods -- (id)authenticate:(NSScriptCommand *)command { - NSDictionary *args = [command evaluatedArguments]; - NSString *givenQuery = [ args objectForKey:@"query"]; - NSString *tunnelName = [ args objectForKey:@"tunnelName"]; - NSString *fifo = [ args objectForKey:@"fifo"]; - - NSLog(@"tunnel: %@ / query: %@ / fifo: %@",tunnelName,givenQuery,fifo); - NSFileHandle *fh = [ NSFileHandle fileHandleForWritingAtPath: fifo ]; - [ fh writeData: [ @"xy" dataUsingEncoding: NSASCIIStringEncoding]]; - [ fh closeFile ]; - - NSLog(@"password written"); - return @"OK"; - -/* - [ query setStringValue: givenQuery ]; - [NSApp beginSheet: alertSheet - modalForWindow: mainWindow - modalDelegate: nil - didEndSelector: nil - contextInfo: nil]; - [NSApp runModalForWindow: alertSheet]; - // Sheet is up here. - [NSApp endSheet: alertSheet]; - [alertSheet orderOut: self]; - if ( sheetStatus == 0) - { - password = [ passwd stringValue ]; - [ passwd setStringValue: @"" ]; - return password ; - } - else - { - [[tunnelTask objectForKey: @"task" ] terminate ]; - } - sheetStatus = nil; - return @""; -*/ -} - -// Method used for Applescript hooks to quit the application +/** + * What exactly is this for? + */ - (id)handleQuitScriptCommand:(NSScriptCommand *)command { - [ NSApp terminate: self ]; + [NSApp terminate:self]; + + // Suppress warning return nil; } diff --git a/Source/SPExportController.h b/Source/SPExportController.h new file mode 100644 index 00000000..ee2b651e --- /dev/null +++ b/Source/SPExportController.h @@ -0,0 +1,91 @@ +// +// SPExportController.h +// sequel-pro +// +// Created by Ben Perry (benperry.com.au) on 21/02/09. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at <http://code.google.com/p/sequel-pro/> + +#import <Cocoa/Cocoa.h> +#import "CMMCPConnection.h" +#import "CMMCPResult.h" + +@interface SPExportController : NSObject { + + // Table Document + IBOutlet id tableDocumentInstance; + IBOutlet id tableWindow; + + // Tables List + IBOutlet id tablesListInstance; + + // Export Window + IBOutlet id exportWindow; + IBOutlet id exportToolbar; + IBOutlet id exportTableList; + IBOutlet id exportTabBar; + IBOutlet id exportInputMatrix; + IBOutlet id exportFilePerTableCheck; + IBOutlet id exportFilePerTableNote; + + // SQL + IBOutlet id exportSQLIncludeStructureCheck; + IBOutlet id exportSQLIncludeDropSyntaxCheck; + IBOutlet id exportSQLIncludeErrorsCheck; + + // Excel + IBOutlet id exportExcelSheetOrFilePerTableMatrix; + + // CSV + IBOutlet id exportCSVIncludeFieldNamesCheck; + IBOutlet id exportCSVFieldsTerminatedField; + IBOutlet id exportCSVFieldsWrappedField; + IBOutlet id exportCSVFieldsEscapedField; + IBOutlet id exportCSVLinesTerminatedField; + + // HTML + IBOutlet id exportHTMLIncludeStructureCheck; + IBOutlet id exportHTMLIncludeHeadAndBodyTagsCheck; + + // XML + IBOutlet id exportXMLIncludeStructureCheck; + + // PDF + IBOutlet id exportPDFIncludeStructureCheck; + + // Token Name View + IBOutlet id tokenNameView; + IBOutlet id tokenNameField; + IBOutlet id tokenNameTokensField; + IBOutlet id exampleNameLabel; + + // Local Variables + CMMCPConnection *mySQLConnection; + NSMutableArray *tables; +} + +// Export Methods +- (void)export; +- (IBAction)closeSheet:(id)sender; + +// Utility Methods +- (void)setConnection:(CMMCPConnection *)theConnection; +- (void)loadTables; +- (IBAction)switchTab:(id)sender; +- (IBAction)switchInput:(id)sender; + +@end diff --git a/Source/SPExportController.m b/Source/SPExportController.m new file mode 100644 index 00000000..a10fe7b1 --- /dev/null +++ b/Source/SPExportController.m @@ -0,0 +1,177 @@ +// +// SPExportController.m +// sequel-pro +// +// Created by Ben Perry (benperry.com.au) on 21/02/09. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at <http://code.google.com/p/sequel-pro/> + +#import "SPExportController.h" +#import "TablesList.h" + +@implementation SPExportController + +#pragma mark - +#pragma mark Export Methods + +-(void)export +{ + if ([NSBundle loadNibNamed:@"ExportDialog" owner:self]) { + [self loadTables]; + [NSApp beginSheet:exportWindow modalForWindow:tableWindow modalDelegate:self didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) contextInfo:nil]; + } +} + +- (IBAction)closeSheet:(id)sender +{ + [NSApp endSheet:exportWindow]; + [NSApp stopModalWithCode:[sender tag]]; +} + +- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo +{ + [sheet orderOut:self]; +} + +#pragma mark - +#pragma mark Utility Methods + +- (void)setConnection:(CMMCPConnection *)theConnection +{ + mySQLConnection = theConnection; +} + +- (void)loadTables +{ + CMMCPResult *queryResult; + int i; + + [tables removeAllObjects]; + queryResult = (CMMCPResult *)[mySQLConnection listTables]; + + if ([queryResult numOfRows]) + [queryResult dataSeek:0]; + + for ( i = 0 ; i < [queryResult numOfRows] ; i++ ) { + [tables addObject:[NSMutableArray arrayWithObjects: + [NSNumber numberWithBool:YES], + [[queryResult fetchRowAsArray] objectAtIndex:0], + nil + ]]; + } + + [exportTableList reloadData]; +} + +- (IBAction)switchTab:(id)sender +{ + if ([sender isKindOfClass:[NSToolbarItem class]]) { + [exportTabBar selectTabViewItemWithIdentifier:[[sender label] lowercaseString]]; + + [exportFilePerTableCheck setHidden:[[sender label] isEqualToString:@"Excel"]]; + [exportFilePerTableNote setHidden:[[sender label] isEqualToString:@"Excel"]]; + } +} + +- (IBAction)switchInput:(id)sender +{ + if ([sender isKindOfClass:[NSMatrix class]]) { + [exportTableList setEnabled:([[sender selectedCell] tag] == 3)]; + } +} + +#pragma mark - +#pragma mark Table View Datasource methods + +- (int)numberOfRowsInTableView:(NSTableView *)aTableView; +{ + return [tables count]; +} + +- (id)tableView:(NSTableView *)aTableView +objectValueForTableColumn:(NSTableColumn *)aTableColumn + row:(int)rowIndex +{ + id returnObject = nil; + + if ( [[aTableColumn identifier] isEqualToString:@"switch"] ) { + returnObject = [[tables objectAtIndex:rowIndex] objectAtIndex:0]; + } else { + returnObject = [[tables objectAtIndex:rowIndex] objectAtIndex:1]; + } + + return returnObject; +} + +- (void)tableView:(NSTableView *)aTableView + setObjectValue:(id)anObject + forTableColumn:(NSTableColumn *)aTableColumn + row:(int)rowIndex +{ + [[tables objectAtIndex:rowIndex] replaceObjectAtIndex:0 withObject:anObject]; +} + +#pragma mark - +#pragma mark Table View Delegate methods + +- (BOOL)tableView:(NSTableView *)aTableView shouldSelectRow:(NSInteger)rowIndex +{ + return (aTableView != exportTableList); +} + +- (BOOL)tableView:(NSTableView *)aTableView shouldTrackCell:(NSCell *)cell forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row +{ + return (aTableView == exportTableList); +} + +- (void)tableView:(NSTableView *)aTableView + willDisplayCell:(id)aCell + forTableColumn:(NSTableColumn *)aTableColumn + row:(int)rowIndex +{ + [aCell setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; +} + +#pragma mark - +#pragma mark Toolbar Delegate Methods + +- (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar +{ + NSArray *array = [toolbar items]; + NSMutableArray *items = [NSMutableArray arrayWithCapacity:6]; + + for (NSToolbarItem *item in array) + { + [items addObject:[item itemIdentifier]]; + } + + return items; +} + +- (BOOL)validateToolbarItem:(NSToolbarItem *)toolbarItem +{ + return YES; +} + +- (id)init; +{ + self = [super init]; + tables = [[NSMutableArray alloc] init]; + return self; +} + +@end diff --git a/Source/SPFavoriteTextFieldCell.h b/Source/SPFavoriteTextFieldCell.h new file mode 100644 index 00000000..c6c597fa --- /dev/null +++ b/Source/SPFavoriteTextFieldCell.h @@ -0,0 +1,44 @@ +// +// SPFavoriteTextFieldCell.h +// sequel-pro +// +// Created by Stuart Connolly (stuconnolly.com) on Dec 29, 2008 +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at <http://code.google.com/p/sequel-pro/> + +#import <Cocoa/Cocoa.h> +#import "ImageAndTextCell.h" + +@interface SPFavoriteTextFieldCell : ImageAndTextCell +{ + NSString *favoriteName; + NSString *favoriteHost; + + NSColor *mainStringColor; + NSColor *subStringColor; +} + +- (NSString *)favoriteName; +- (void)setFavoriteName:(NSString *)name; + +- (NSString *)favoriteHost; +- (void)setFavoriteHost:(NSString *)host; + +- (void)invertFontColors; +- (void)restoreFontColors; + +@end diff --git a/Source/SPFavoriteTextFieldCell.m b/Source/SPFavoriteTextFieldCell.m new file mode 100644 index 00000000..897ad278 --- /dev/null +++ b/Source/SPFavoriteTextFieldCell.m @@ -0,0 +1,239 @@ +// +// SPFavoriteTextFieldCell.m +// sequel-pro +// +// Created by Stuart Connolly (stuconnolly.com) on Dec 29, 2008 +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at <http://code.google.com/p/sequel-pro/> + +#import "SPFavoriteTextFieldCell.h" + +#define FAVORITE_NAME_FONT_SIZE 12.0 + +@interface SPFavoriteTextFieldCell (PrivateAPI) + +- (NSAttributedString *)constructSubStringAttributedString; +- (NSAttributedString *)attributedStringForFavoriteName; +- (NSDictionary *)mainStringAttributedStringAttributes; +- (NSDictionary *)subStringAttributedStringAttributes; + +@end + +@implementation SPFavoriteTextFieldCell + +// ------------------------------------------------------------------------------- +// init +// ------------------------------------------------------------------------------- +- (id)init +{ + if ((self = [super init])) { + mainStringColor = [NSColor blackColor]; + subStringColor = [NSColor grayColor]; + } + + return self; +} + +// ------------------------------------------------------------------------------- +// copyWithZone: +// ------------------------------------------------------------------------------- +- (id)copyWithZone:(NSZone *)zone +{ + SPFavoriteTextFieldCell *cell = (SPFavoriteTextFieldCell *)[super copyWithZone:zone]; + + cell->favoriteName = nil; + + cell->favoriteName = [favoriteName retain]; + + return cell; +} + +// ------------------------------------------------------------------------------- +// favoriteName +// +// Get the cell's favorite name. +// ------------------------------------------------------------------------------- +- (NSString *)favoriteName +{ + return favoriteName; +} + +// ------------------------------------------------------------------------------- +// setFavoriteName: +// +// Set the cell's favorite name to the supplied name. +// ------------------------------------------------------------------------------- +- (void)setFavoriteName:(NSString *)name +{ + if (favoriteName != name) { + [favoriteName release]; + favoriteName = [name retain]; + } +} + +// ------------------------------------------------------------------------------- +// favoriteHost +// +// Get the cell's favorite host. +// ------------------------------------------------------------------------------- +- (NSString *)favoriteHost +{ + return favoriteHost; +} + +// ------------------------------------------------------------------------------- +// setFavoriteHost: +// +// Set the cell's favorite host to the supplied name. +// ------------------------------------------------------------------------------- +- (void)setFavoriteHost:(NSString *)host +{ + if (favoriteHost != host) { + [favoriteHost release]; + favoriteHost = [host retain]; + } +} + +// ------------------------------------------------------------------------------- +// drawInteriorWithFrame:inView: +// +// Draws the actual cell. +// ------------------------------------------------------------------------------- +- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView +{ + (([self isHighlighted]) && (![[self highlightColorWithFrame:cellFrame inView:controlView] isEqualTo:[NSColor secondarySelectedControlColor]])) ? [self invertFontColors] : [self restoreFontColors]; + + // Construct and get the sub text attributed string + NSAttributedString *mainString = [[self attributedStringForFavoriteName] autorelease]; + NSAttributedString *subString = [[self constructSubStringAttributedString] autorelease]; + + NSRect subFrame = NSMakeRect(0.0, 0.0, [subString size].width, [subString size].height); + + // Total height of both strings with a 2 pixel separation space + float totalHeight = [mainString size].height + [subString size].height + 1.0; + + cellFrame.origin.y += (cellFrame.size.height - totalHeight) / 2.0; + cellFrame.origin.x += 10.0; // Indent main string from image + + // Position the sub text's frame rect + subFrame.origin.y = [mainString size].height + cellFrame.origin.y + 1.0; + subFrame.origin.x = cellFrame.origin.x; + + cellFrame.size.height = totalHeight; + + int i; + float maxWidth = cellFrame.size.width; + float mainStringWidth = [mainString size].width; + float subStringWidth = [subString size].width; + + if (maxWidth < mainStringWidth) { + for (i = 0; i <= [mainString length]; i++) { + if ([[mainString attributedSubstringFromRange:NSMakeRange(0, i)] size].width >= maxWidth) { + mainString = [[[NSMutableAttributedString alloc] initWithString:[[[mainString attributedSubstringFromRange:NSMakeRange(0, i - 3)] string] stringByAppendingString:@"..."] attributes:[self mainStringAttributedStringAttributes]] autorelease]; + } + } + } + + if (maxWidth < subStringWidth) { + for (i = 0; i <= [subString length]; i++) { + if ([[subString attributedSubstringFromRange:NSMakeRange(0, i)] size].width >= maxWidth) { + subString = [[[NSMutableAttributedString alloc] initWithString:[[[subString attributedSubstringFromRange:NSMakeRange(0, i - 3)] string] stringByAppendingString:@"..."] attributes:[self subStringAttributedStringAttributes]] autorelease]; + } + } + } + + [mainString drawInRect:cellFrame]; + [subString drawInRect:subFrame]; +} + +// ------------------------------------------------------------------------------- +// invertFontColors +// +// Inverts the displayed font colors when the cell is selected. +// ------------------------------------------------------------------------------- +- (void)invertFontColors +{ + mainStringColor = [NSColor whiteColor]; + subStringColor = [NSColor whiteColor]; +} + +// ------------------------------------------------------------------------------- +// restoreFontColors +// +// Restores the displayed font colors once the cell is no longer selected. +// ------------------------------------------------------------------------------- +- (void)restoreFontColors +{ + mainStringColor = [NSColor blackColor]; + subStringColor = [NSColor grayColor]; +} + +// ------------------------------------------------------------------------------- +// dealloc +// ------------------------------------------------------------------------------- +- (void)dealloc +{ + [favoriteName release], favoriteName = nil; + + [super dealloc]; +} + +@end + +@implementation SPFavoriteTextFieldCell (PrivateAPI) + +// ------------------------------------------------------------------------------- +// constructSubStringAttributedString +// +// Constructs the attributed string to be used as the cell's substring. +// ------------------------------------------------------------------------------- +- (NSAttributedString *)constructSubStringAttributedString +{ + return [[NSAttributedString alloc] initWithString:favoriteHost attributes:[self subStringAttributedStringAttributes]]; +} + +// ------------------------------------------------------------------------------- +// attributedStringForFavoriteName +// +// Constructs the attributed string for the cell's favorite name. +// ------------------------------------------------------------------------------- +- (NSAttributedString *)attributedStringForFavoriteName +{ + return [[NSAttributedString alloc] initWithString:favoriteName attributes:[self mainStringAttributedStringAttributes]]; +} + +// ------------------------------------------------------------------------------- +// mainStringAttributedStringAttributes +// +// Returns the attributes of the cell's main string. +// ------------------------------------------------------------------------------- +- (NSDictionary *)mainStringAttributedStringAttributes +{ + return [NSDictionary dictionaryWithObjectsAndKeys:mainStringColor, NSForegroundColorAttributeName, [NSFont systemFontOfSize:FAVORITE_NAME_FONT_SIZE], NSFontAttributeName, nil]; +} + +// ------------------------------------------------------------------------------- +// subStringAttributedStringAttributes +// +// Returns the attributes of the cell's sub string. +// ------------------------------------------------------------------------------- +- (NSDictionary *)subStringAttributedStringAttributes +{ + return [NSDictionary dictionaryWithObjectsAndKeys:subStringColor, NSForegroundColorAttributeName, [NSFont systemFontOfSize:[NSFont smallSystemFontSize]], NSFontAttributeName, nil]; +} + +@end diff --git a/Source/SPPreferenceController.h b/Source/SPPreferenceController.h new file mode 100644 index 00000000..0198303c --- /dev/null +++ b/Source/SPPreferenceController.h @@ -0,0 +1,74 @@ +// +// SPPreferenceController.h +// sequel-pro +// +// Created by Stuart Connolly (stuconnolly.com) on Dec 10, 2008 +// Modified by Ben Perry (benperry.com.au) on Mar 28, 2009 +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at <http://code.google.com/p/sequel-pro/> + +#import <Cocoa/Cocoa.h> + +@class KeyChain; + +@interface SPPreferenceController : NSWindowController +{ + IBOutlet NSWindow *preferencesWindow; + + IBOutlet NSView *generalView; + IBOutlet NSView *notificationsView; + IBOutlet NSView *tablesView; + IBOutlet NSView *favoritesView; + IBOutlet NSView *autoUpdateView; + IBOutlet NSView *networkView; + + IBOutlet NSPopUpButton *defaultFavoritePopup; + + IBOutlet NSTableView *favoritesTableView; + IBOutlet NSArrayController *favoritesController; + + IBOutlet NSSecureTextField *passwordField; + KeyChain *keychain; + + NSToolbar *toolbar; + + NSToolbarItem *generalItem; + NSToolbarItem *notificationsItem; + NSToolbarItem *tablesItem; + NSToolbarItem *favoritesItem; + NSToolbarItem *autoUpdateItem; + NSToolbarItem *networkItem; + + NSUserDefaults *prefs; +} + +// IBAction methods +- (IBAction)addFavorite:(id)sender; +- (IBAction)removeFavorite:(id)sender; +- (IBAction)duplicateFavorite:(id)sender; +- (IBAction)saveFavorite:(id)sender; +- (IBAction)updateDefaultFavorite:(id)sender; + +// Toolbar item IBAction methods +- (IBAction)displayGeneralPreferences:(id)sender; +- (IBAction)displayTablePreferences:(id)sender; +- (IBAction)displayFavoritePreferences:(id)sender; +- (IBAction)displayNotificationPreferences:(id)sender; +- (IBAction)displayAutoUpdatePreferences:(id)sender; +- (IBAction)displayNetworkPreferences:(id)sender; + +@end diff --git a/Source/SPPreferenceController.m b/Source/SPPreferenceController.m new file mode 100644 index 00000000..657bcd3f --- /dev/null +++ b/Source/SPPreferenceController.m @@ -0,0 +1,574 @@ +// +// SPPreferenceController.m +// sequel-pro +// +// Created by Stuart Connolly (stuconnolly.com) on Dec 10, 2008 +// Modified by Ben Perry (benperry.com.au) on Mar 28, 2009 +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at <http://code.google.com/p/sequel-pro/> + +#import "SPPreferenceController.h" +#import "SPWindowAdditions.h" +#import "SPFavoriteTextFieldCell.h" +#import "KeyChain.h" + +#define FAVORITES_PB_DRAG_TYPE @"SequelProPreferencesPasteboard" + +#define PREFERENCE_TOOLBAR_GENERAL @"Preference Toolbar General" +#define PREFERENCE_TOOLBAR_TABLES @"Preference Toolbar Tables" +#define PREFERENCE_TOOLBAR_FAVORITES @"Preference Toolbar Favorites" +#define PREFERENCE_TOOLBAR_NOTIFICATIONS @"Preference Toolbar Notifications" +#define PREFERENCE_TOOLBAR_AUTOUPDATE @"Preference Toolbar Auto Update" +#define PREFERENCE_TOOLBAR_NETWORK @"Preference Toolbar Network" + +#pragma mark - + +@interface SPPreferenceController (PrivateAPI) + +- (void)_setupToolbar; +- (void)_resizeWindowForContentView:(NSView *)view; +- (void)_updateDefaultFavoritePopup; + +@end + +#pragma mark - + +@implementation SPPreferenceController + +// ------------------------------------------------------------------------------- +// init +// ------------------------------------------------------------------------------- +- (id)init +{ + return [super initWithWindowNibName:@"Preferences"]; +} + +// ------------------------------------------------------------------------------- +// windowDidLoad +// ------------------------------------------------------------------------------- +- (void)windowDidLoad +{ + [self _setupToolbar]; + + prefs = [NSUserDefaults standardUserDefaults]; + keychain = [[KeyChain alloc] init]; + + SPFavoriteTextFieldCell *tableCell = [[[SPFavoriteTextFieldCell alloc] init] autorelease]; + + [tableCell setImage:[NSImage imageNamed:@"database"]]; + + // Replace column's NSTextFieldCell with custom SWProfileTextFieldCell + [[[favoritesTableView tableColumns] objectAtIndex:0] setDataCell:tableCell]; + + [favoritesTableView registerForDraggedTypes:[NSArray arrayWithObject:FAVORITES_PB_DRAG_TYPE]]; + + [favoritesTableView selectRowIndexes:[NSIndexSet indexSetWithIndex:0] byExtendingSelection:NO]; + [favoritesTableView reloadData]; + + [self _updateDefaultFavoritePopup]; +} + +#pragma mark - +#pragma mark IBAction methods + +// ------------------------------------------------------------------------------- +// addFavorite: +// ------------------------------------------------------------------------------- +- (IBAction)addFavorite:(id)sender +{ + // Create default favorite + NSMutableDictionary *favorite = [NSMutableDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"New Favorite", @"", @"", @"", @"", @"", nil] + forKeys:[NSArray arrayWithObjects:@"name", @"host", @"socket", @"user", @"port", @"database", nil]]; + + [favoritesController addObject:favorite]; + + [favoritesTableView reloadData]; + [self _updateDefaultFavoritePopup]; +} + +// ------------------------------------------------------------------------------- +// removeFavorite: +// ------------------------------------------------------------------------------- +- (IBAction)removeFavorite:(id)sender +{ + if ([favoritesTableView numberOfSelectedRows] == 1) { + + // Get selected favorite's details + NSString *name = [favoritesController valueForKeyPath:@"selection.name"]; + NSString *user = [favoritesController valueForKeyPath:@"selection.user"]; + NSString *host = [favoritesController valueForKeyPath:@"selection.host"]; + NSString *database = [favoritesController valueForKeyPath:@"selection.database"]; + + // Remove passwords from the Keychain + [keychain deletePasswordForName:[NSString stringWithFormat:@"Sequel Pro : %@", name] + account:[NSString stringWithFormat:@"%@@%@/%@", user, host, database]]; + [keychain deletePasswordForName:[NSString stringWithFormat:@"Sequel Pro SSHTunnel : %@", name] + account:[NSString stringWithFormat:@"%@@%@/%@", user, host, database]]; + + // Reset last used favorite + if ([favoritesTableView selectedRow] == [prefs integerForKey:@"LastFavoriteIndex"]) { + [prefs setInteger:0 forKey:@"LastFavoriteIndex"]; + } + + // Reset default favorite + if ([favoritesTableView selectedRow] == [prefs integerForKey:@"DefaultFavorite"]) { + [prefs setInteger:[prefs integerForKey:@"LastFavoriteIndex"] forKey:@"DefaultFavorite"]; + } + + [favoritesController removeObjectAtArrangedObjectIndex:[favoritesTableView selectedRow]]; + + [favoritesTableView reloadData]; + [self _updateDefaultFavoritePopup]; + } +} + +// ------------------------------------------------------------------------------- +// duplicateFavorite: +// ------------------------------------------------------------------------------- +- (IBAction)duplicateFavorite:(id)sender +{ + if ([favoritesTableView numberOfSelectedRows] == 1) { + NSMutableDictionary *favorite = [NSMutableDictionary dictionaryWithDictionary:[[favoritesController arrangedObjects] objectAtIndex:[favoritesTableView selectedRow]]]; + + [favoritesController addObject:favorite]; + + [favoritesTableView reloadData]; + [self _updateDefaultFavoritePopup]; + } +} + +// ------------------------------------------------------------------------------- +// saveFavorite: +// ------------------------------------------------------------------------------- +- (IBAction)saveFavorite:(id)sender +{ + +} + + +// ------------------------------------------------------------------------------- +// updateDefaultFavorite: +// ------------------------------------------------------------------------------- +- (IBAction)updateDefaultFavorite:(id)sender +{ + if ([defaultFavoritePopup indexOfSelectedItem] == 0) { + [prefs setBool:YES forKey:@"SelectLastFavoriteUsed"]; + } else { + [prefs setBool:NO forKey:@"SelectLastFavoriteUsed"]; + + // Minus 2 from index to account for the "Last Used" and separator items + [prefs setInteger:[defaultFavoritePopup indexOfSelectedItem]-2 forKey:@"DefaultFavorite"]; + } +} + + +#pragma mark - +#pragma mark Toolbar item IBAction methods + +// ------------------------------------------------------------------------------- +// displayGeneralPreferences: +// ------------------------------------------------------------------------------- +- (IBAction)displayGeneralPreferences:(id)sender +{ + [toolbar setSelectedItemIdentifier:PREFERENCE_TOOLBAR_GENERAL]; + [self _resizeWindowForContentView:generalView]; +} + +// ------------------------------------------------------------------------------- +// displayTablePreferences: +// ------------------------------------------------------------------------------- +- (IBAction)displayTablePreferences:(id)sender +{ + [toolbar setSelectedItemIdentifier:PREFERENCE_TOOLBAR_TABLES]; + [self _resizeWindowForContentView:tablesView]; +} + +// ------------------------------------------------------------------------------- +// displayFavoritePreferences: +// ------------------------------------------------------------------------------- +- (IBAction)displayFavoritePreferences:(id)sender +{ + [toolbar setSelectedItemIdentifier:PREFERENCE_TOOLBAR_FAVORITES]; + [self _resizeWindowForContentView:favoritesView]; + + // Set the default favorite popup back to preference + if (sender == [defaultFavoritePopup lastItem]) { + if (![prefs boolForKey:@"SelectLastFavoriteUsed"]) { + [defaultFavoritePopup selectItemAtIndex:[prefs integerForKey:@"DefaultFavorite"]+2]; + } else { + [defaultFavoritePopup selectItemAtIndex:0]; + } + } +} + +// ------------------------------------------------------------------------------- +// displayNotificationPreferences: +// ------------------------------------------------------------------------------- +- (IBAction)displayNotificationPreferences:(id)sender +{ + [toolbar setSelectedItemIdentifier:PREFERENCE_TOOLBAR_NOTIFICATIONS]; + [self _resizeWindowForContentView:notificationsView]; +} + +// ------------------------------------------------------------------------------- +// displayAutoUpdatePreferences: +// ------------------------------------------------------------------------------- +- (IBAction)displayAutoUpdatePreferences:(id)sender +{ + [toolbar setSelectedItemIdentifier:PREFERENCE_TOOLBAR_AUTOUPDATE]; + [self _resizeWindowForContentView:autoUpdateView]; +} + +// ------------------------------------------------------------------------------- +// displayNetworkPreferences: +// ------------------------------------------------------------------------------- +- (IBAction)displayNetworkPreferences:(id)sender +{ + [toolbar setSelectedItemIdentifier:PREFERENCE_TOOLBAR_NETWORK]; + [self _resizeWindowForContentView:networkView]; +} + +#pragma mark - +#pragma mark TableView datasource methods + +// ------------------------------------------------------------------------------- +// numberOfRowsInTableView: +// ------------------------------------------------------------------------------- +- (int)numberOfRowsInTableView:(NSTableView *)aTableView +{ + return [[favoritesController arrangedObjects] count]; +} + +// ------------------------------------------------------------------------------- +// tableView:objectValueForTableColumn:row: +// ------------------------------------------------------------------------------- +- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex +{ + return [[[favoritesController arrangedObjects] objectAtIndex:rowIndex] objectForKey:[aTableColumn identifier]]; +} + +#pragma mark - +#pragma mark TableView drag & drop datasource methods + +// ------------------------------------------------------------------------------- +// tableView:writeRows:toPasteboard: +// ------------------------------------------------------------------------------- +- (BOOL)tableView:(NSTableView *)tv writeRows:(NSArray *)rows toPasteboard:(NSPasteboard *)pboard +{ + int originalRow; + NSArray *pboardTypes; + + if ([rows count] == 1) { + pboardTypes = [NSArray arrayWithObject:FAVORITES_PB_DRAG_TYPE]; + originalRow = [[rows objectAtIndex:0] intValue]; + + [pboard declareTypes:pboardTypes owner:nil]; + [pboard setString:[[NSNumber numberWithInt:originalRow] stringValue] forType:FAVORITES_PB_DRAG_TYPE]; + + return YES; + } + else { + return NO; + } +} + +// ------------------------------------------------------------------------------- +// tableView:validateDrop:proposedRow:proposedDropOperation: +// ------------------------------------------------------------------------------- +- (NSDragOperation)tableView:(NSTableView *)tv validateDrop:(id <NSDraggingInfo>)info proposedRow:(int)row proposedDropOperation:(NSTableViewDropOperation)operation +{ + int originalRow; + NSArray *pboardTypes = [[info draggingPasteboard] types]; + + if (([pboardTypes count] > 1) && (row != -1)) { + if (([pboardTypes containsObject:FAVORITES_PB_DRAG_TYPE]) && (operation == NSTableViewDropAbove)) { + originalRow = [[[info draggingPasteboard] stringForType:FAVORITES_PB_DRAG_TYPE] intValue]; + + if ((row != originalRow) && (row != (originalRow + 1))) { + return NSDragOperationMove; + } + } + } + + return NSDragOperationNone; +} + +// ------------------------------------------------------------------------------- +// tableView:acceptDrop:row:dropOperation: +// ------------------------------------------------------------------------------- +- (BOOL)tableView:(NSTableView *)tv acceptDrop:(id <NSDraggingInfo>)info row:(int)row dropOperation:(NSTableViewDropOperation)operation +{ + int originalRow; + int destinationRow; + NSMutableDictionary *draggedRow; + + originalRow = [[[info draggingPasteboard] stringForType:FAVORITES_PB_DRAG_TYPE] intValue]; + destinationRow = row; + + if (destinationRow > originalRow) { + destinationRow--; + } + + draggedRow = [NSMutableDictionary dictionaryWithDictionary:[[favoritesController arrangedObjects] objectAtIndex:originalRow]]; + + [favoritesController removeObjectAtArrangedObjectIndex:originalRow]; + [favoritesController insertObject:draggedRow atArrangedObjectIndex:destinationRow]; + + [favoritesTableView reloadData]; + [favoritesTableView selectRowIndexes:[NSIndexSet indexSetWithIndex:destinationRow] byExtendingSelection:NO]; + + // Update default favorite to take on new value + if ([prefs integerForKey:@"LastFavoriteIndex"] == originalRow) { + [prefs setInteger:destinationRow forKey:@"LastFavoriteIndex"]; + } + + // Update default favorite to take on new value + if ([prefs integerForKey:@"DefaultFavorite"] == originalRow) { + [prefs setInteger:destinationRow forKey:@"DefaultFavorite"]; + } + [self _updateDefaultFavoritePopup]; + + return YES; +} + + +#pragma mark - +#pragma mark TableView delegate methods + +// ------------------------------------------------------------------------------- +// tableView:willDisplayCell:forTableColumn:row: +// ------------------------------------------------------------------------------- +- (void)tableView:(NSTableView *)tableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn row:(int)index +{ + if ([cell isKindOfClass:[SPFavoriteTextFieldCell class]]) { + [cell setFavoriteName:[[[favoritesController arrangedObjects] objectAtIndex:index] objectForKey:@"name"]]; + [cell setFavoriteHost:[[[favoritesController arrangedObjects] objectAtIndex:index] objectForKey:@"host"]]; + } +} + +// ------------------------------------------------------------------------------- +// tableViewSelectionDidChange: +// ------------------------------------------------------------------------------- +- (void)tableViewSelectionDidChange:(NSNotification *)notification +{ + if ([[favoritesTableView selectedRowIndexes] count] > 0) { + [favoritesController setSelectionIndexes:[favoritesTableView selectedRowIndexes]]; + } + + NSString *keychainName = [NSString stringWithFormat:@"Sequel Pro : %@", [favoritesController valueForKeyPath:@"selection.name"]]; + NSString *keychainAccount = [NSString stringWithFormat:@"%@@%@/%@", + [favoritesController valueForKeyPath:@"selection.user"], + [favoritesController valueForKeyPath:@"selection.host"], + [favoritesController valueForKeyPath:@"selection.database"]]; + + [passwordField setStringValue:[keychain getPasswordForName:keychainName account:keychainAccount]]; +} + +#pragma mark - +#pragma mark Toolbar delegate methods + +// ------------------------------------------------------------------------------- +// toolbar:itemForItemIdentifier:willBeInsertedIntoToolbar: +// ------------------------------------------------------------------------------- +- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag +{ + if ([itemIdentifier isEqualToString:PREFERENCE_TOOLBAR_GENERAL]) { + return generalItem; + } + else if ([itemIdentifier isEqualToString:PREFERENCE_TOOLBAR_TABLES]) { + return tablesItem; + } + else if ([itemIdentifier isEqualToString:PREFERENCE_TOOLBAR_FAVORITES]) { + return favoritesItem; + } + else if ([itemIdentifier isEqualToString:PREFERENCE_TOOLBAR_NOTIFICATIONS]) { + return notificationsItem; + } + else if ([itemIdentifier isEqualToString:PREFERENCE_TOOLBAR_AUTOUPDATE]) { + return autoUpdateItem; + } + else if ([itemIdentifier isEqualToString:PREFERENCE_TOOLBAR_NETWORK]) { + return networkItem; + } + + return [[[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier] autorelease]; +} + +// ------------------------------------------------------------------------------- +// toolbarAllowedItemIdentifiers: +// ------------------------------------------------------------------------------- +- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar +{ + return [NSArray arrayWithObjects:PREFERENCE_TOOLBAR_GENERAL, PREFERENCE_TOOLBAR_TABLES, PREFERENCE_TOOLBAR_FAVORITES, PREFERENCE_TOOLBAR_NOTIFICATIONS, PREFERENCE_TOOLBAR_AUTOUPDATE, PREFERENCE_TOOLBAR_NETWORK, nil]; +} + +// ------------------------------------------------------------------------------- +// toolbarDefaultItemIdentifiers: +// ------------------------------------------------------------------------------- +- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar +{ + return [NSArray arrayWithObjects:PREFERENCE_TOOLBAR_GENERAL, PREFERENCE_TOOLBAR_TABLES, PREFERENCE_TOOLBAR_FAVORITES, PREFERENCE_TOOLBAR_NOTIFICATIONS, PREFERENCE_TOOLBAR_AUTOUPDATE, PREFERENCE_TOOLBAR_NETWORK, nil]; +} + +// ------------------------------------------------------------------------------- +// toolbarSelectableItemIdentifiers: +// ------------------------------------------------------------------------------- +- (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar +{ + return [NSArray arrayWithObjects:PREFERENCE_TOOLBAR_GENERAL, PREFERENCE_TOOLBAR_TABLES, PREFERENCE_TOOLBAR_FAVORITES, PREFERENCE_TOOLBAR_NOTIFICATIONS, PREFERENCE_TOOLBAR_AUTOUPDATE, PREFERENCE_TOOLBAR_NETWORK, nil]; +} + +// ------------------------------------------------------------------------------- +// dealloc +// ------------------------------------------------------------------------------- +- (void)dealloc +{ + [keychain release], keychain = nil; + + [super dealloc]; +} + +@end + +#pragma mark - + +@implementation SPPreferenceController (PrivateAPI) + +// ------------------------------------------------------------------------------- +// _setupToolbar +// +// Constructs the preferences' window toolbar. +// ------------------------------------------------------------------------------- +- (void)_setupToolbar +{ + toolbar = [[[NSToolbar alloc] initWithIdentifier:@"Preference Toolbar"] autorelease]; + + // General preferences + generalItem = [[NSToolbarItem alloc] initWithItemIdentifier:PREFERENCE_TOOLBAR_GENERAL]; + + [generalItem setLabel:NSLocalizedString(@"General", @"")]; + [generalItem setImage:[NSImage imageNamed:@"toolbar-preferences-general"]]; + [generalItem setTarget:self]; + [generalItem setAction:@selector(displayGeneralPreferences:)]; + + // Table preferences + tablesItem = [[NSToolbarItem alloc] initWithItemIdentifier:PREFERENCE_TOOLBAR_TABLES]; + + [tablesItem setLabel:NSLocalizedString(@"Tables", @"")]; + [tablesItem setImage:[NSImage imageNamed:@"toolbar-preferences-tables"]]; + [tablesItem setTarget:self]; + [tablesItem setAction:@selector(displayTablePreferences:)]; + + // Favorite preferences + favoritesItem = [[NSToolbarItem alloc] initWithItemIdentifier:PREFERENCE_TOOLBAR_FAVORITES]; + + [favoritesItem setLabel:NSLocalizedString(@"Favorites", @"")]; + [favoritesItem setImage:[NSImage imageNamed:@"toolbar-preferences-favorites"]]; + [favoritesItem setTarget:self]; + [favoritesItem setAction:@selector(displayFavoritePreferences:)]; + + // Notification preferences + notificationsItem = [[NSToolbarItem alloc] initWithItemIdentifier:PREFERENCE_TOOLBAR_NOTIFICATIONS]; + + [notificationsItem setLabel:NSLocalizedString(@"Notifications", @"")]; + [notificationsItem setImage:[NSImage imageNamed:@"toolbar-preferences-notifications"]]; + [notificationsItem setTarget:self]; + [notificationsItem setAction:@selector(displayNotificationPreferences:)]; + + // AutoUpdate preferences + autoUpdateItem = [[NSToolbarItem alloc] initWithItemIdentifier:PREFERENCE_TOOLBAR_AUTOUPDATE]; + + [autoUpdateItem setLabel:NSLocalizedString(@"Auto Update", @"")]; + [autoUpdateItem setImage:[NSImage imageNamed:@"toolbar-preferences-autoupdate"]]; + [autoUpdateItem setTarget:self]; + [autoUpdateItem setAction:@selector(displayAutoUpdatePreferences:)]; + + // Network preferences + networkItem = [[NSToolbarItem alloc] initWithItemIdentifier:PREFERENCE_TOOLBAR_NETWORK]; + + [networkItem setLabel:NSLocalizedString(@"Network", @"")]; + [networkItem setImage:[NSImage imageNamed:@"toolbar-preferences-network"]]; + [networkItem setTarget:self]; + [networkItem setAction:@selector(displayNetworkPreferences:)]; + + [toolbar setDelegate:self]; + [toolbar setSelectedItemIdentifier:PREFERENCE_TOOLBAR_GENERAL]; + [toolbar setAllowsUserCustomization:NO]; + + [preferencesWindow setToolbar:toolbar]; + [preferencesWindow setShowsToolbarButton:NO]; + + [self displayGeneralPreferences:nil]; +} + +// ------------------------------------------------------------------------------- +// _resizeWindowForContentView: +// +// Resizes the window to the size of the supplied view. +// ------------------------------------------------------------------------------- +- (void)_resizeWindowForContentView:(NSView *)view +{ + // remove all current views + NSEnumerator *en = [[[preferencesWindow contentView] subviews] objectEnumerator]; + NSView *subview; + while (subview = [en nextObject]) { + [subview removeFromSuperview]; + } + + // resize window + [preferencesWindow resizeForContentView:view titleBarVisible:YES]; + + // add view + [[preferencesWindow contentView] addSubview:view]; + [view setFrameOrigin:NSMakePoint(0, 0)]; +} + + + +// ------------------------------------------------------------------------------- +// _updateDefaultFavoritePopup: +// +// Build the default favorite popup button +// ------------------------------------------------------------------------------- +- (void)_updateDefaultFavoritePopup; +{ + [defaultFavoritePopup removeAllItems]; + + // Use the last used favorite + [defaultFavoritePopup addItemWithTitle:@"Last Used"]; + [[defaultFavoritePopup menu] addItem:[NSMenuItem separatorItem]]; + + // Load in current favorites + [defaultFavoritePopup addItemsWithTitles:[[favoritesController arrangedObjects] valueForKeyPath:@"name"]]; + + // Add item to switch to edit favorites pane + [[defaultFavoritePopup menu] addItem:[NSMenuItem separatorItem]]; + [defaultFavoritePopup addItemWithTitle:@"Edit Favorites…"]; + [[[defaultFavoritePopup menu] itemWithTitle:@"Edit Favorites…"] setAction:@selector(displayFavoritePreferences:)]; + [[[defaultFavoritePopup menu] itemWithTitle:@"Edit Favorites…"] setTarget:self]; + + // Select the default favorite from prefs + if (![prefs boolForKey:@"SelectLastFavoriteUsed"]) { + [defaultFavoritePopup selectItemAtIndex:[prefs integerForKey:@"DefaultFavorite"] + 2]; + } else { + [defaultFavoritePopup selectItemAtIndex:0]; + } +} + + + +@end diff --git a/Source/SPTableInfo.m b/Source/SPTableInfo.m index cb494ea1..c87a337d 100644 --- a/Source/SPTableInfo.m +++ b/Source/SPTableInfo.m @@ -155,7 +155,7 @@ - (void)tableView:(NSTableView *)aTableView willDisplayCell:(id)aCell forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex { if ((rowIndex > 0) && [[aTableColumn identifier] isEqualToString:@"info"]) { - [(ImageAndTextCell*)aCell setImage:[NSImage imageNamed:@"TablePropertyIcon"]]; + [(ImageAndTextCell*)aCell setImage:[NSImage imageNamed:@"table-property"]]; [(ImageAndTextCell*)aCell setIndentationLevel:1]; } else { [(ImageAndTextCell*)aCell setImage:nil]; diff --git a/Source/SPWindowAdditions.h b/Source/SPWindowAdditions.h new file mode 100644 index 00000000..af247427 --- /dev/null +++ b/Source/SPWindowAdditions.h @@ -0,0 +1,30 @@ +// +// SPWindowAdditions.h +// sequel-pro +// +// Created by Stuart Connolly (stuconnolly.com) on Dec 10, 2008 +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at <http://code.google.com/p/sequel-pro/> + +#import <Cocoa/Cocoa.h> + +@interface NSWindow (SPWindowAdditions) + +- (float)toolbarHeight; +- (void)resizeForContentView:(NSView *)view titleBarVisible:(BOOL)visible; + +@end diff --git a/Source/SPWindowAdditions.m b/Source/SPWindowAdditions.m new file mode 100644 index 00000000..d5992a86 --- /dev/null +++ b/Source/SPWindowAdditions.m @@ -0,0 +1,75 @@ +// +// SPWindowAdditions.m +// sequel-pro +// +// Created by Stuart Connolly (stuconnolly.com) on Dec 10, 2008 +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at <http://code.google.com/p/sequel-pro/> + +#import "SPWindowAdditions.h" + +@implementation NSWindow (SPWindowAdditions) + +// ------------------------------------------------------------------------------- +// toolbarHeight +// +// Returns the height of the currently visible toolbar. +// ------------------------------------------------------------------------------- +- (float)toolbarHeight +{ + NSRect windowFrame; + float toolbarHeight = 0.0; + + if (([self toolbar]) && ([[self toolbar] isVisible])) { + windowFrame = [NSWindow contentRectForFrameRect:[self frame] styleMask:[self styleMask]]; + + toolbarHeight = NSHeight(windowFrame) - NSHeight([[self contentView] frame]); + } + + return toolbarHeight; +} + +// ------------------------------------------------------------------------------- +// resizeForContentView:titleBarVisible +// +// Resizes this window to the size of the supplied view. +// ------------------------------------------------------------------------------- +- (void)resizeForContentView:(NSView *)view titleBarVisible:(BOOL)visible +{ + NSSize viewSize = [view frame].size; + NSRect frame = [self frame]; + + if ((viewSize.height) < [self contentMinSize].height) { + viewSize.height = [self contentMinSize].height; + } + + float newHeight = (viewSize.height + [self toolbarHeight]); + + // If the title bar is visible add 22 pixels to new height of window. + if (visible) { + newHeight += 22; + } + + frame.origin.y += frame.size.height - newHeight; + + frame.size.height = newHeight; + frame.size.width = viewSize.width; + + [self setFrame:frame display:YES animate:YES]; +} + +@end diff --git a/Source/TableContent.m b/Source/TableContent.m index c3cb3b8f..dfe9b24c 100644 --- a/Source/TableContent.m +++ b/Source/TableContent.m @@ -180,7 +180,7 @@ } // Set the data cell font according to the preferences - if ( [prefs boolForKey:@"useMonospacedFonts"] ) { + if ( [prefs boolForKey:@"UseMonospacedFonts"] ) { [dataCell setFont:[NSFont fontWithName:@"Monaco" size:10]]; } else { [dataCell setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; @@ -254,7 +254,7 @@ } // Enable or disable the limit fields according to preference setting - if ( [prefs boolForKey:@"limitRows"] ) { + if ( [prefs boolForKey:@"LimitResults"] ) { // Attempt to preserve the limit value if it's still valid if (!preserveCurrentView || [limitRowsField intValue] < 1 || [limitRowsField intValue] >= numRows) { @@ -264,8 +264,8 @@ [limitRowsButton setEnabled:YES]; [limitRowsStepper setEnabled:YES]; [limitRowsText setStringValue:[NSString stringWithFormat:NSLocalizedString(@"Limited to %d rows starting with row", @"text showing the number of rows the result is limited to"), - [prefs integerForKey:@"limitRowsValue"]]]; - if ([prefs integerForKey:@"limitRowsValue"] < numRows) + [prefs integerForKey:@"LimitResultsValue"]]]; + if ([prefs integerForKey:@"LimitResultsValue"] < numRows) areShowingAllRows = NO; } else { [limitRowsField setEnabled:NO]; @@ -288,13 +288,13 @@ query = [query stringByAppendingString:@" DESC"]; } - if ( [prefs boolForKey:@"limitRows"] ) { + if ( [prefs boolForKey:@"LimitResults"] ) { if ( [limitRowsField intValue] <= 0 ) { [limitRowsField setStringValue:@"1"]; } query = [query stringByAppendingString: [NSString stringWithFormat:@" LIMIT %d,%d", - [limitRowsField intValue]-1, [prefs integerForKey:@"limitRowsValue"]]]; + [limitRowsField intValue]-1, [prefs integerForKey:@"LimitResultsValue"]]]; } queryResult = [mySQLConnection queryString:query]; @@ -362,12 +362,12 @@ [[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryWillBePerformed" object:self]; //enable or disable limit fields - if ( [prefs boolForKey:@"limitRows"] ) { + if ( [prefs boolForKey:@"LimitResults"] ) { [limitRowsField setEnabled:YES]; [limitRowsButton setEnabled:YES]; [limitRowsStepper setEnabled:YES]; [limitRowsText setStringValue:[NSString stringWithFormat:NSLocalizedString(@"Limited to %d rows starting with row", @"text showing the number of rows the result is limited to"), - [prefs integerForKey:@"limitRowsValue"]]]; + [prefs integerForKey:@"LimitResultsValue"]]]; } else { [limitRowsField setEnabled:NO]; [limitRowsButton setEnabled:NO]; @@ -384,13 +384,13 @@ if ( isDesc ) queryString = [queryString stringByAppendingString:@" DESC"]; } - if ( [prefs boolForKey:@"limitRows"] ) { + if ( [prefs boolForKey:@"LimitResults"] ) { if ( [limitRowsField intValue] <= 0 ) { [limitRowsField setStringValue:@"1"]; } queryString = [queryString stringByAppendingString: [NSString stringWithFormat:@" LIMIT %d,%d", - [limitRowsField intValue]-1, [prefs integerForKey:@"limitRowsValue"]]]; + [limitRowsField intValue]-1, [prefs integerForKey:@"LimitResultsValue"]]]; [limitRowsField selectText:self]; } queryResult = [mySQLConnection queryString:queryString]; @@ -435,15 +435,15 @@ } // If limitRowsField > number of total found rows show the last limitRowsValue rows - if ( [prefs boolForKey:@"limitRows"] && [limitRowsField intValue] >= maxNumRowsOfCurrentTable ) { - int newLimit = maxNumRowsOfCurrentTable - [prefs integerForKey:@"limitRowsValue"]; + if ( [prefs boolForKey:@"LimitResults"] && [limitRowsField intValue] >= maxNumRowsOfCurrentTable ) { + int newLimit = maxNumRowsOfCurrentTable - [prefs integerForKey:@"LimitResultsValue"]; [limitRowsField setStringValue:[[NSNumber numberWithInt:(newLimit<1)?1:newLimit] stringValue]]; } // If the filter field is empty, the limit field is at 1, and the selected filter is not looking // for NULLs or NOT NULLs, then don't allow filtering. - if (([argument length] == 0) && (![[[compareField selectedItem] title] hasSuffix:@"NULL"]) && (![prefs boolForKey:@"limitRows"] || [limitRowsField intValue] == 1)) { + if (([argument length] == 0) && (![[[compareField selectedItem] title] hasSuffix:@"NULL"]) && (![prefs boolForKey:@"LimitResults"] || [limitRowsField intValue] == 1)) { [argument release]; [self showAll:sender]; return; @@ -599,19 +599,19 @@ // to redo the query if nothing found for LIMIT > 1 NSString* tempQueryString; // LIMIT if appropriate - if ( [prefs boolForKey:@"limitRows"] ) { + if ( [prefs boolForKey:@"LimitResults"] ) { tempQueryString = [NSString stringWithString:queryString]; queryString = [NSString stringWithFormat:@"%@ LIMIT %d,%d", queryString, - [limitRowsField intValue]-1, [prefs integerForKey:@"limitRowsValue"]]; + [limitRowsField intValue]-1, [prefs integerForKey:@"LimitResultsValue"]]; } theResult = [mySQLConnection queryString:queryString]; [filteredResult setArray:[self fetchResultAsArray:theResult]]; // try it again if theResult is empty and limitRowsField > 1 by setting LIMIT to 0, limitRowsValue - if([prefs boolForKey:@"limitRows"] && [limitRowsField intValue] > 1 && [filteredResult count] == 0) { + if([prefs boolForKey:@"LimitResults"] && [limitRowsField intValue] > 1 && [filteredResult count] == 0) { queryString = [NSString stringWithFormat:@"%@ LIMIT %d,%d", tempQueryString, - 0, [prefs integerForKey:@"limitRowsValue"]]; + 0, [prefs integerForKey:@"LimitResultsValue"]]; theResult = [mySQLConnection queryString:queryString]; [limitRowsField setStringValue:@"1"]; [filteredResult setArray:[self fetchResultAsArray:theResult]]; @@ -673,7 +673,7 @@ for ( i = 0 ; i < [columns count] ; i++ ) { column = [columns objectAtIndex:i]; if ([column objectForKey:@"default"] == nil) { - [newRow setObject:[prefs stringForKey:@"nullValue"] forKey:[column objectForKey:@"name"]]; + [newRow setObject:[prefs stringForKey:@"NullValue"] forKey:[column objectForKey:@"name"]]; } else { [newRow setObject:[column objectForKey:@"default"] forKey:[column objectForKey:@"name"]]; } @@ -715,7 +715,7 @@ [filteredResult insertObject:tempRow atIndex:[tableContentView selectedRow]+1]; //if we don't show blobs, read data for this duplicate column from db - if ([prefs boolForKey:@"dontShowBlob"]) { + if ([prefs boolForKey:@"LoadBlobsAsNeeded"]) { // Abort if there are no indices on this table - argumentForRow will display an error. if (![[self argumentForRow:[tableContentView selectedRow]] length]){ return; @@ -732,12 +732,12 @@ for ( i = 0 ; i < [queryResult numOfRows] ; i++ ) { row = [queryResult fetchRowAsDictionary]; if ( [[row objectForKey:@"Extra"] isEqualToString:@"auto_increment"] ) { - [tempRow setObject:[prefs stringForKey:@"nullValue"] forKey:[row objectForKey:@"Field"]]; - } else if ( [tableDataInstance columnIsBlobOrText:[row objectForKey:@"Field"]] && [prefs boolForKey:@"dontShowBlob"] && dbDataRow) { + [tempRow setObject:[prefs stringForKey:@"NullValue"] forKey:[row objectForKey:@"Field"]]; + } else if ( [tableDataInstance columnIsBlobOrText:[row objectForKey:@"Field"]] && [prefs boolForKey:@"LoadBlobsAsNeeded"] && dbDataRow) { NSString *valueString = nil; //if what we read from DB is NULL (NSNull), we replace it with the string NULL if([[dbDataRow objectForKey:[row objectForKey:@"Field"]] isKindOfClass:[NSNull class]]) - valueString = [prefs objectForKey:@"nullValue"]; + valueString = [prefs objectForKey:@"NullValue"]; else valueString = [dbDataRow objectForKey:[row objectForKey:@"Field"]]; [tempRow setObject:valueString forKey:[row objectForKey:@"Field"]]; @@ -767,11 +767,11 @@ /* if ( ([tableContentView numberOfSelectedRows] == [self numberOfRowsInTableView:tableContentView]) && areShowingAllRows && - (![prefs boolForKey:@"limitRows"] || ([tableContentView numberOfSelectedRows] < [prefs integerForKey:@"limitRowsValue"])) ) { + (![prefs boolForKey:@"LimitResults"] || ([tableContentView numberOfSelectedRows] < [prefs integerForKey:@"LimitResultsValue"])) ) { */ if ( ([tableContentView numberOfSelectedRows] == [tableContentView numberOfRows]) && - (([prefs boolForKey:@"limitRows"] && [tableContentView numberOfSelectedRows] == [self fetchNumberOfRows]) || - (![prefs boolForKey:@"limitRows"] && [tableContentView numberOfSelectedRows] == [self getNumberOfRows])) ) { + (([prefs boolForKey:@"LimitResults"] && [tableContentView numberOfSelectedRows] == [self fetchNumberOfRows]) || + (![prefs boolForKey:@"LimitResults"] && [tableContentView numberOfSelectedRows] == [self getNumberOfRows])) ) { NSBeginAlertSheet(NSLocalizedString(@"Warning", @"warning"), NSLocalizedString(@"Delete", @"delete button"), NSLocalizedString(@"Cancel", @"cancel button"), nil, tableWindow, self, @selector(sheetDidEnd:returnCode:contextInfo:), nil, @"removeallrows", NSLocalizedString(@"Do you really want to delete all rows?", @"message of panel asking for confirmation for deleting all rows")); } else if ( [tableContentView numberOfSelectedRows] == 1 ) { @@ -1051,7 +1051,7 @@ [tableContentView setVerticalMotionCanBeginDrag:NO]; prefs = [[NSUserDefaults standardUserDefaults] retain]; - if ( [prefs boolForKey:@"useMonospacedFonts"] ) { + if ( [prefs boolForKey:@"UseMonospacedFonts"] ) { [argumentField setFont:[NSFont fontWithName:@"Monaco" size:10]]; [limitRowsField setFont:[NSFont fontWithName:@"Monaco" size:[NSFont smallSystemFontSize]]]; [editTextView setFont:[NSFont fontWithName:@"Monaco" size:[NSFont smallSystemFontSize]]]; @@ -1062,9 +1062,9 @@ } [hexTextView setFont:[NSFont fontWithName:@"Monaco" size:[NSFont smallSystemFontSize]]]; [limitRowsStepper setEnabled:NO]; - if ( [prefs boolForKey:@"limitRows"] ) { + if ( [prefs boolForKey:@"LimitResults"] ) { [limitRowsText setStringValue:[NSString stringWithFormat:NSLocalizedString(@"Limited to %d rows starting with row", @"text showing the number of rows the result is limited to"), - [prefs integerForKey:@"limitRowsValue"]]]; + [prefs integerForKey:@"LimitResultsValue"]]]; } else { [limitRowsText setStringValue:NSLocalizedString(@"No limit", @"text showing that the result isn't limited")]; [limitRowsField setStringValue:@""]; @@ -1145,14 +1145,14 @@ */ { if ( [limitRowsStepper intValue] > 0 ) { - int newStep = [limitRowsField intValue]+[prefs integerForKey:@"limitRowsValue"]; + int newStep = [limitRowsField intValue]+[prefs integerForKey:@"LimitResultsValue"]; // if newStep > the total number of rows in the current table retain the old value [limitRowsField setIntValue:(newStep>maxNumRowsOfCurrentTable)?[limitRowsField intValue]:newStep]; } else { - if ( ([limitRowsField intValue]-[prefs integerForKey:@"limitRowsValue"]) < 1 ) { + if ( ([limitRowsField intValue]-[prefs integerForKey:@"LimitResultsValue"]) < 1 ) { [limitRowsField setIntValue:1]; } else { - [limitRowsField setIntValue:[limitRowsField intValue]-[prefs integerForKey:@"limitRowsValue"]]; + [limitRowsField setIntValue:[limitRowsField intValue]-[prefs integerForKey:@"LimitResultsValue"]]; } } [limitRowsStepper setIntValue:0]; @@ -1180,14 +1180,14 @@ while ( key = [enumerator nextObject] ) { if ( [[tempRow objectForKey:key] isMemberOfClass:[NSNull class]] ) { - [modifiedRow setObject:[prefs stringForKey:@"nullValue"] forKey:key]; + [modifiedRow setObject:[prefs stringForKey:@"NullValue"] forKey:key]; } else { [modifiedRow setObject:[tempRow objectForKey:key] forKey:key]; } } // Add values for hidden blob and text fields if appropriate - if ( [prefs boolForKey:@"dontShowBlob"] ) { + if ( [prefs boolForKey:@"LoadBlobsAsNeeded"] ) { for ( j = 0 ; j < [columns count] ; j++ ) { if ( [tableDataInstance columnIsBlobOrText:[[columns objectAtIndex:j] objectForKey:@"name"] ] ) { [modifiedRow setObject:NSLocalizedString(@"(not loaded)", @"value shown for hidden blob and text fields") forKey:[[columns objectAtIndex:j] objectForKey:@"name"]]; @@ -1240,7 +1240,7 @@ for ( i = 0 ; i < [columnNames count] ; i++ ) { rowObject = [[filteredResult objectAtIndex:currentlyEditingRow] objectForKey:[columnNames objectAtIndex:i]]; // Convert the object to a string (here we can add special treatment for date-, number- and data-fields) - if ( [[rowObject description] isEqualToString:[prefs stringForKey:@"nullValue"]] + if ( [[rowObject description] isEqualToString:[prefs stringForKey:@"NullValue"]] || ([rowObject isMemberOfClass:[NSString class]] && [[rowObject description] isEqualToString:@""]) ) { //NULL when user entered the nullValue string defined in the prefs or when a number field isn't set @@ -1291,7 +1291,7 @@ // If no rows have been changed, show error if appropriate. if ( ![mySQLConnection affectedRows] ) { - if ( [prefs boolForKey:@"showError"] ) { + if ( [prefs boolForKey:@"ShowNoAffectedRowsError"] ) { NSBeginAlertSheet(NSLocalizedString(@"Warning", @"warning"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil, nil, nil, NSLocalizedString(@"The row was not written to the MySQL database. You probably haven't changed anything.\nReload the table to be sure that the row exists and use a primary key for your table.\n(This error can be turned off in the preferences.)", @"message of panel when no rows have been affected after writing to the db")); } else { @@ -1310,7 +1310,7 @@ // New row created successfully if ( isEditingNewRow ) { - if ( [prefs boolForKey:@"reloadAfterAdding"] ) { + if ( [prefs boolForKey:@"ReloadAfterAddingRow"] ) { [self reloadTableValues:self]; [tableContentView deselectAll:self]; [tableWindow endEditingFor:nil]; @@ -1329,7 +1329,7 @@ // Existing row edited successfully } else { - if ( [prefs boolForKey:@"reloadAfterEditing"] ) { + if ( [prefs boolForKey:@"ReloadAfterEditingRow"] ) { [self reloadTableValues:self]; [tableContentView deselectAll:self]; [tableWindow endEditingFor:nil]; @@ -1342,13 +1342,13 @@ if ( isDesc ) query = [query stringByAppendingString:@" DESC"]; } - if ( [prefs boolForKey:@"limitRows"] ) { + if ( [prefs boolForKey:@"LimitResults"] ) { if ( [limitRowsField intValue] <= 0 ) { [limitRowsField setStringValue:@"1"]; } query = [query stringByAppendingString: [NSString stringWithFormat:@" LIMIT %d,%d", - [limitRowsField intValue]-1, [prefs integerForKey:@"limitRowsValue"]]]; + [limitRowsField intValue]-1, [prefs integerForKey:@"LimitResultsValue"]]]; } queryResult = [mySQLConnection queryString:query]; [fullResult setArray:[self fetchResultAsArray:queryResult]]; @@ -1438,7 +1438,7 @@ // When the option to not show blob or text options is set, we have a problem - we don't have // the right values to use in the WHERE statement. Throw an error if this is the case. - if ( [prefs boolForKey:@"dontShowBlob"] && [self tableContainsBlobOrTextColumns] ) { + if ( [prefs boolForKey:@"LoadBlobsAsNeeded"] && [self tableContainsBlobOrTextColumns] ) { NSBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil, nil, nil, NSLocalizedString(@"You can't hide blob and text fields when working with tables without index.", @"message of panel when trying to edit tables without index and with hidden blob/text fields")); [keys removeAllObjects]; @@ -1471,7 +1471,7 @@ [value setString:[tempValue description]]; } - if ( [value isEqualToString:[prefs stringForKey:@"nullValue"]] ) { + if ( [value isEqualToString:[prefs stringForKey:@"NullValue"]] ) { [argument appendString:[NSString stringWithFormat:@"%@ IS NULL", [[keys objectAtIndex:i] backtickQuotedString]]]; } else { @@ -1535,7 +1535,7 @@ NSArray *columns = [tableDataInstance columns]; NSArray *columnNames = [tableDataInstance columnNames]; - if ( [prefs boolForKey:@"dontShowBlob"] ) { + if ( [prefs boolForKey:@"LoadBlobsAsNeeded"] ) { for ( i = 0 ; i < [columnNames count] ; i++ ) { if (![tableDataInstance columnIsBlobOrText:[[columns objectAtIndex:i] objectForKey:@"name"]] ) { [fields addObject:[columnNames objectAtIndex:i]]; @@ -1591,7 +1591,7 @@ /* if ( ([tableContentView numberOfSelectedRows] == [self numberOfRowsInTableView:tableContentView]) && areShowingAllRows && - ([tableContentView numberOfSelectedRows] < [prefs integerForKey:@"limitRowsValue"]) ) { + ([tableContentView numberOfSelectedRows] < [prefs integerForKey:@"LimitResultsValue"]) ) { */ [mySQLConnection queryString:[NSString stringWithFormat:@"DELETE FROM %@", [selectedTable backtickQuotedString]]]; if ( [[mySQLConnection getLastErrorMessage] isEqualToString:@""] ) { @@ -1632,7 +1632,7 @@ } //do deleting (after enumerating) - if ( [prefs boolForKey:@"reloadAfterRemoving"] ) { + if ( [prefs boolForKey:@"ReloadAfterRemovingRow"] ) { [self reloadTableValues:self]; } else { for ( i = 0 ; i < [filteredResult count] ; i++ ) { @@ -1650,13 +1650,13 @@ if ( isDesc ) queryString = [queryString stringByAppendingString:@" DESC"]; } - if ( [prefs boolForKey:@"limitRows"] ) { + if ( [prefs boolForKey:@"LimitResults"] ) { if ( [limitRowsField intValue] <= 0 ) { [limitRowsField setStringValue:@"1"]; } queryString = [queryString stringByAppendingString: [NSString stringWithFormat:@" LIMIT %d,%d", - [limitRowsField intValue]-1, [prefs integerForKey:@"limitRowsValue"]]]; + [limitRowsField intValue]-1, [prefs integerForKey:@"LimitResultsValue"]]]; } queryResult = [mySQLConnection queryString:queryString]; @@ -1682,7 +1682,7 @@ */ - (int)getNumberOfRows { - if ([prefs boolForKey:@"limitRows"] && [prefs boolForKey:@"fetchRowCount"]) { + if ([prefs boolForKey:@"LimitResults"] && [prefs boolForKey:@"FetchCorrectRowCount"]) { numRows = [self fetchNumberOfRows]; } else { numRows = [fullResult count]; @@ -1737,7 +1737,7 @@ objectValueForTableColumn:(NSTableColumn *)aTableColumn { // Check if loading of text/blob fields is disabled // If not, all text fields are loaded and we don't have to make them gray - if ([prefs boolForKey:@"dontShowBlob"]) + if ([prefs boolForKey:@"LoadBlobsAsNeeded"]) { // Make sure that the cell actually responds to setTextColor: // In the future, we might use different cells for the table view @@ -1838,13 +1838,13 @@ objectValueForTableColumn:(NSTableColumn *)aTableColumn [selectedTable backtickQuotedString], [sortField backtickQuotedString]]; if ( isDesc ) queryString = [queryString stringByAppendingString:@" DESC"]; - if ( [prefs boolForKey:@"limitRows"] ) { + if ( [prefs boolForKey:@"LimitResults"] ) { if ( [limitRowsField intValue] <= 0 ) { [limitRowsField setStringValue:@"1"]; } queryString = [queryString stringByAppendingString: [NSString stringWithFormat:@" LIMIT %d,%d", - [limitRowsField intValue]-1, [prefs integerForKey:@"limitRowsValue"]]]; + [limitRowsField intValue]-1, [prefs integerForKey:@"LimitResultsValue"]]]; } queryResult = [mySQLConnection queryString:queryString]; @@ -1967,7 +1967,7 @@ objectValueForTableColumn:(NSTableColumn *)aTableColumn CMMCPResult *tempResult; // If not isEditingRow and the preference value for not showing blobs is set, check whether the row contains any blobs. - if ( [prefs boolForKey:@"dontShowBlob"] && !isEditingRow ) { + if ( [prefs boolForKey:@"LoadBlobsAsNeeded"] && !isEditingRow ) { // If the table does contain blob or text fields, load the values ready for editing. if ( [self tableContainsBlobOrTextColumns] ) { @@ -1985,7 +1985,7 @@ objectValueForTableColumn:(NSTableColumn *)aTableColumn enumerator = [tempRow keyEnumerator]; while ( key = [enumerator nextObject] ) { if ( [[tempRow objectForKey:key] isMemberOfClass:[NSNull class]] ) { - [modifiedRow setObject:[prefs stringForKey:@"nullValue"] forKey:key]; + [modifiedRow setObject:[prefs stringForKey:@"NullValue"] forKey:key]; } else { [modifiedRow setObject:[tempRow objectForKey:key] forKey:key]; } diff --git a/Source/TableDocument.h b/Source/TableDocument.h index de062124..7c9ce223 100644 --- a/Source/TableDocument.h +++ b/Source/TableDocument.h @@ -42,6 +42,7 @@ IBOutlet id tableDumpInstance; IBOutlet id tableDataInstance; IBOutlet id tableStatusInstance; + IBOutlet id spExportControllerInstance; IBOutlet id tableWindow; IBOutlet id connectSheet; @@ -85,7 +86,7 @@ NSString *selectedDatabase; NSString *mySQLVersion; NSUserDefaults *prefs; - NSString *favoriteNamebBeingChanged; + NSString *favoriteNameBeingChanged; NSMenu *selectEncodingMenu; BOOL _supportsEncoding; diff --git a/Source/TableDocument.m b/Source/TableDocument.m index e8599c47..7f674341 100644 --- a/Source/TableDocument.m +++ b/Source/TableDocument.m @@ -33,6 +33,7 @@ #import "TableStatus.h" #import "ImageAndTextCell.h" #import "SPGrowlController.h" +#import "SPExportController.h" #import "SPQueryConsole.h" #import "SPSQLParser.h" #import "SPTableData.h" @@ -98,12 +99,12 @@ NSString *TableDocumentFavoritesControllerFavoritesDidChange = @"TableDocum - (NSPrintOperation *)printOperationWithSettings:(NSDictionary *)ps error:(NSError **)e { - NSPrintInfo *printInfo = [self printInfo]; [printInfo setHorizontalPagination:NSFitPagination]; [printInfo setVerticalPagination:NSAutoPagination]; NSPrintOperation *printOp = [NSPrintOperation printOperationWithView:[[tableTabView selectedTabViewItem] view] printInfo:printInfo]; return printOp; + } - (CMMCPConnection *)sharedConnection @@ -120,7 +121,7 @@ NSString *TableDocumentFavoritesControllerFavoritesDidChange = @"TableDocum - (IBAction)connectToDB:(id)sender { - // load the details of the curretnly selected favorite into the text boxes in connect sheet + // load the details of the currently selected favorite into the text boxes in connect sheet [self chooseFavorite:self]; // run the connect sheet (modal) @@ -129,6 +130,14 @@ NSString *TableDocumentFavoritesControllerFavoritesDidChange = @"TableDocum modalDelegate:self didEndSelector:@selector(connectSheetDidEnd:returnCode:contextInfo:) contextInfo:nil]; + + // Connect automatically to the last used or default favourite + // connectSheet must open first. + // TODO: Auto connect on startup only. New connections should NOT automatically connect. + if ([prefs boolForKey:@"AutoConnectToDefault"]) { + [self connect:self]; + } + } @@ -206,7 +215,7 @@ NSString *TableDocumentFavoritesControllerFavoritesDidChange = @"TableDocum //register as delegate [mySQLConnection setDelegate:self]; // set encoding - NSString *encodingName = [prefs objectForKey:@"encoding"]; + NSString *encodingName = [prefs objectForKey:@"DefaultEncoding"]; if ( [encodingName isEqualToString:@"Autodetect"] ) { [self setConnectionEncoding:[self databaseEncoding] reloadingViews:NO]; } else { @@ -227,6 +236,7 @@ NSString *TableDocumentFavoritesControllerFavoritesDidChange = @"TableDocum [tableContentInstance setConnection:mySQLConnection]; [customQueryInstance setConnection:mySQLConnection]; [tableDumpInstance setConnection:mySQLConnection]; + [spExportControllerInstance setConnection:mySQLConnection]; [tableStatusInstance setConnection:mySQLConnection]; [tableDataInstance setConnection:mySQLConnection]; [self setFileName:[NSString stringWithFormat:@"(MySQL %@) %@@%@ %@", mySQLVersion, [userField stringValue], @@ -243,7 +253,7 @@ NSString *TableDocumentFavoritesControllerFavoritesDidChange = @"TableDocum //can't connect to host NSBeginAlertSheet(NSLocalizedString(@"Connection failed!", @"connection failed"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil, @selector(sheetDidEnd:returnCode:contextInfo:), @"connect", - [NSString stringWithFormat:NSLocalizedString(@"Unable to connect to host %@, or the request timed out.\n\nBe sure that the address is correct and that you have the necessary privileges, or try increasing the connection timeout (currently %i seconds).\n\nMySQL said: %@", @"message of panel when connection to host failed"), [hostField stringValue], [[prefs objectForKey:@"connectionTimeout"] intValue], [mySQLConnection getLastErrorMessage]]); + [NSString stringWithFormat:NSLocalizedString(@"Unable to connect to host %@, or the request timed out.\n\nBe sure that the address is correct and that you have the necessary privileges, or try increasing the connection timeout (currently %i seconds).\n\nMySQL said: %@", @"message of panel when connection to host failed"), [hostField stringValue], [[prefs objectForKey:@"ConnectionTimeoutValue"] intValue], [mySQLConnection getLastErrorMessage]]); } else if (code == 3) { //can't connect to db NSBeginAlertSheet(NSLocalizedString(@"Connection failed!", @"connection failed"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil, @@ -288,7 +298,7 @@ NSString *TableDocumentFavoritesControllerFavoritesDidChange = @"TableDocum [databaseField setStringValue:[self valueForKeyPath:@"selectedFavorite.database"]]; [passwordField setStringValue:[self selectedFavoritePassword]]; - [prefs setInteger:[favoritesController selectionIndex] forKey:@"lastFavoriteIndex"]; + [prefs setInteger:[favoritesController selectionIndex] forKey:@"LastFavoriteIndex"]; } /** @@ -1309,7 +1319,13 @@ NSString *TableDocumentFavoritesControllerFavoritesDidChange = @"TableDocum */ - (IBAction)export:(id)sender { - [tableDumpInstance exportFile:[sender tag]]; + if ([sender tag] == -1) { + //[tableDumpInstance export]; + + [spExportControllerInstance export]; + } else { + [tableDumpInstance exportFile:[sender tag]]; + } } - (IBAction)exportTable:(id)sender @@ -1685,7 +1701,7 @@ NSString *TableDocumentFavoritesControllerFavoritesDidChange = @"TableDocum name:@"NSApplicationWillTerminateNotification" object:nil]; //set up interface - if ( [prefs boolForKey:@"useMonospacedFonts"] ) { + if ( [prefs boolForKey:@"UseMonospacedFonts"] ) { [[SPQueryConsole sharedQueryConsole] setConsoleFont:[NSFont fontWithName:@"Monaco" size:[NSFont smallSystemFontSize]]]; [syntaxViewContent setFont:[NSFont fontWithName:@"Monaco" size:[NSFont smallSystemFontSize]]]; @@ -1705,8 +1721,10 @@ NSString *TableDocumentFavoritesControllerFavoritesDidChange = @"TableDocum // [self connectToDB:nil]; [self performSelector:@selector(connectToDB:) withObject:tableWindow afterDelay:0.0f]; - if([prefs boolForKey:@"selectLastFavoriteUsed"] == YES){ - [favoritesController setSelectionIndexes:[NSIndexSet indexSetWithIndex:[prefs integerForKey:@"lastFavoriteIndex"]]]; + if([prefs boolForKey:@"SelectLastFavoriteUsed"] == YES){ + [favoritesController setSelectionIndex:[prefs integerForKey:@"LastFavoriteIndex"]]; + } else { + [favoritesController setSelectionIndex:[prefs integerForKey:@"DefaultFavorite"]]; } } @@ -1870,14 +1888,14 @@ NSString *TableDocumentFavoritesControllerFavoritesDidChange = @"TableDocum { NSDictionary *favorite = [favorites objectAtIndex:rowIndex]; - [keyChainInstance deletePasswordForName:[NSString stringWithFormat:@"Sequel Pro : %@", favoriteNamebBeingChanged] + [keyChainInstance deletePasswordForName:[NSString stringWithFormat:@"Sequel Pro : %@", favoriteNameBeingChanged] account:[NSString stringWithFormat:@"%@@%@/%@", [favorite objectForKey:@"user"], [favorite objectForKey:@"host"], [favorite objectForKey:@"database"]]]; [keyChainInstance addPassword:[passwordField stringValue] forName:[NSString stringWithFormat:@"Sequel Pro : %@", object] account:[NSString stringWithFormat:@"%@@%@/%@", [favorite objectForKey:@"user"], [favorite objectForKey:@"host"], [favorite objectForKey:@"database"]]]; - favoriteNamebBeingChanged = nil; + favoriteNameBeingChanged = nil; } /** @@ -1887,7 +1905,7 @@ NSString *TableDocumentFavoritesControllerFavoritesDidChange = @"TableDocum */ - (BOOL)tableView:(NSTableView *)tableView shouldEditTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)rowIndex { - favoriteNamebBeingChanged = [[favorites objectAtIndex:rowIndex] objectForKey:@"name"]; + favoriteNameBeingChanged = [[favorites objectAtIndex:rowIndex] objectForKey:@"name"]; return YES; } diff --git a/Source/TableDump.h b/Source/TableDump.h index 4575444b..d35b40c4 100644 --- a/Source/TableDump.h +++ b/Source/TableDump.h @@ -58,6 +58,12 @@ IBOutlet id exportMultipleFieldsEscapedField; IBOutlet id exportMultipleLinesTerminatedField; + // New Export Window + IBOutlet id exportWindow; + IBOutlet id exportTabBar; + IBOutlet id exportToolbar; + IBOutlet id exportTableList; + IBOutlet id importCSVView; IBOutlet NSPopUpButton *importFormatPopup; IBOutlet id importCSVBox; @@ -104,8 +110,9 @@ - (IBAction)closeSheet:(id)sender; - (IBAction)stepRow:(id)sender; - (IBAction)cancelProgressBar:(id)sender; + //export methods -//- (IBAction)saveDump:(id)sender; +- (void)export; - (void)exportFile:(int)tag; - (void)savePanelDidEnd:(NSSavePanel *)sheet returnCode:(int)returnCode contextInfo:(NSString *)contextInfo; @@ -136,6 +143,10 @@ - (BOOL)exportTables:(NSArray *)selectedTables toFileHandle:(NSFileHandle *)fileHandle usingFormat:(NSString *)type usingMulti:(BOOL)multi; - (BOOL)exportSelectedTablesToFileHandle:(NSFileHandle *)fileHandle usingFormat:(NSString *)type; +// New Export methods +- (IBAction)switchTab:(id)sender; +- (IBAction)switchInput:(id)sender; + //additional methods - (void)setConnection:(CMMCPConnection *)theConnection; diff --git a/Source/TableDump.m b/Source/TableDump.m index 3f543d4b..5d1cb19e 100644 --- a/Source/TableDump.m +++ b/Source/TableDump.m @@ -90,12 +90,24 @@ ends the modal session */ { + [NSApp endSheet:exportWindow]; [NSApp stopModalWithCode:[sender tag]]; } #pragma mark - #pragma mark export methods +- (void)export +{ + [self reloadTables:self]; + [NSApp beginSheet:exportWindow modalForWindow:tableWindow modalDelegate:self didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) contextInfo:nil]; +} + +- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo +{ + [sheet orderOut:self]; +} + - (void)exportFile:(int)tag /* invoked when user clicks on an export menuItem @@ -735,7 +747,7 @@ [fieldMappingButtonOptions setArray:[importArray objectAtIndex:currentRow]]; for (i = 0; i < [fieldMappingButtonOptions count]; i++) { if ([[fieldMappingButtonOptions objectAtIndex:i] isNSNull]) { - [fieldMappingButtonOptions replaceObjectAtIndex:i withObject:[NSString stringWithFormat:@"%i. %@", i+1, [prefs objectForKey:@"nullValue"]]]; + [fieldMappingButtonOptions replaceObjectAtIndex:i withObject:[NSString stringWithFormat:@"%i. %@", i+1, [prefs objectForKey:@"NullValue"]]]; } else { [fieldMappingButtonOptions replaceObjectAtIndex:i withObject:[NSString stringWithFormat:@"%i. %@", i+1, [fieldMappingButtonOptions objectAtIndex:i]]]; } @@ -1090,7 +1102,7 @@ NSMutableString *csvCell = [NSMutableString string]; NSMutableArray *csvRow = [NSMutableArray array]; NSMutableString *csvString = [NSMutableString string]; - NSString *nullString = [NSString stringWithString:[prefs objectForKey:@"nullValue"]]; + NSString *nullString = [NSString stringWithString:[prefs objectForKey:@"NullValue"]]; NSString *escapedEscapeString, *escapedFieldSeparatorString, *escapedEnclosingString, *escapedLineEndString; NSString *dataConversionString; NSScanner *csvNumericTester; @@ -1381,14 +1393,14 @@ fieldCount = [tempRowArray count]; } else { while ( [tempRowArray count] < fieldCount ) { - [tempRowArray addObject:[NSString stringWithString:[prefs objectForKey:@"nullValue"]]]; + [tempRowArray addObject:[NSString stringWithString:[prefs objectForKey:@"NullValue"]]]; } } for ( i = 0 ; i < [tempRowArray count] ; i++ ) { // Insert a NSNull object if the cell contains an unescaped null character or an unescaped string // which matches the NULL string set in preferences. - if ( [[tempRowArray objectAtIndex:i] isEqualToString:@"\\N"] || [[tempRowArray objectAtIndex:i] isEqualToString:[prefs objectForKey:@"nullValue"]] ) { + if ( [[tempRowArray objectAtIndex:i] isEqualToString:@"\\N"] || [[tempRowArray objectAtIndex:i] isEqualToString:[prefs objectForKey:@"NullValue"]] ) { [tempRowArray replaceObjectAtIndex:i withObject:[NSNull null]]; } else { @@ -1889,7 +1901,7 @@ [[exportDumpTableView tableColumnWithIdentifier:@"switch"] setDataCell:switchButton]; [[exportMultipleCSVTableView tableColumnWithIdentifier:@"switch"] setDataCell:switchButton]; [[exportMultipleXMLTableView tableColumnWithIdentifier:@"switch"] setDataCell:switchButton]; - if ( [prefs boolForKey:@"useMonospacedFonts"] ) { + if ( [prefs boolForKey:@"UseMonospacedFonts"] ) { [[[exportDumpTableView tableColumnWithIdentifier:@"tables"] dataCell] setFont:[NSFont fontWithName:@"Monaco" size:[NSFont smallSystemFontSize]]]; [[[exportMultipleCSVTableView tableColumnWithIdentifier:@"tables"] dataCell] @@ -1930,7 +1942,7 @@ forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex { - if ( [[NSUserDefaults standardUserDefaults] boolForKey:@"useMonospacedFonts"] ) { + if ( [[NSUserDefaults standardUserDefaults] boolForKey:@"UseMonospacedFonts"] ) { [aCell setFont:[NSFont fontWithName:@"Monaco" size:[NSFont smallSystemFontSize]]]; } else @@ -2007,6 +2019,13 @@ objectValueForTableColumn:(NSTableColumn *)aTableColumn #pragma mark - #pragma mark other + +- (void)awakeFromNib +{ + [self switchTab:[[exportToolbar items] objectAtIndex:0]]; + [exportToolbar setSelectedItemIdentifier:[[[exportToolbar items] objectAtIndex:0] itemIdentifier]]; +} + //last but not least - (id)init; { @@ -2028,7 +2047,7 @@ objectValueForTableColumn:(NSTableColumn *)aTableColumn [fieldMappingArray release]; [savePath release]; [openPath release]; - [prefs release]; + [prefs release]; [super dealloc]; } @@ -2038,4 +2057,39 @@ objectValueForTableColumn:(NSTableColumn *)aTableColumn progressCancelled = YES; } +- (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar +{ + NSArray *array = [toolbar items]; + NSMutableArray *items = [NSMutableArray arrayWithCapacity:6]; + + for (NSToolbarItem *item in array) + { + [items addObject:[item itemIdentifier]]; + } + + return items; +} + +#pragma mark New Export methods + +- (IBAction)switchTab:(id)sender +{ + if ([sender isKindOfClass:[NSToolbarItem class]]) { + [exportTabBar selectTabViewItemWithIdentifier:[[sender label] lowercaseString]]; + } +} + +- (IBAction)switchInput:(id)sender +{ + if ([sender isKindOfClass:[NSMatrix class]]) { + [exportTableList setEnabled:([[sender selectedCell] tag] == 3)]; + } +} + + +- (BOOL)validateToolbarItem:(NSToolbarItem *)toolbarItem +{ + return YES; +} + @end diff --git a/Source/TableSource.m b/Source/TableSource.m index 117ce99b..92aa9811 100644 --- a/Source/TableSource.m +++ b/Source/TableSource.m @@ -236,7 +236,7 @@ adds an empty row to the tableSource-array and goes into edit mode if ( ![self saveRowOnDeselect] ) return; [tableFields addObject:[NSMutableDictionary - dictionaryWithObjects:[NSArray arrayWithObjects:@"",@"int",@"",@"0",@"0",@"0",@"YES",@"",[prefs stringForKey:@"nullValue"],@"None",nil] + dictionaryWithObjects:[NSArray arrayWithObjects:@"",@"int",@"",@"0",@"0",@"0",@"YES",@"",[prefs stringForKey:@"NullValue"],@"None",nil] forKeys:[NSArray arrayWithObjects:@"Field",@"Type",@"Length",@"unsigned",@"zerofill",@"binary",@"Null",@"Key",@"Default",@"Extra",nil]]]; [tableSourceView reloadData]; @@ -503,7 +503,7 @@ sets the connection (received from TableDocument) and makes things that have to [tableSourceView registerForDraggedTypes:[NSArray arrayWithObjects:@"SequelProPasteboard", nil]]; while ( (indexColumn = [indexColumnsEnumerator nextObject]) ) { - if ( [prefs boolForKey:@"useMonospacedFonts"] ) { + if ( [prefs boolForKey:@"UseMonospacedFonts"] ) { [[indexColumn dataCell] setFont:[NSFont fontWithName:@"Monaco" size:10]]; } else @@ -512,7 +512,7 @@ sets the connection (received from TableDocument) and makes things that have to } } while ( (fieldColumn = [fieldColumnsEnumerator nextObject]) ) { - if ( [prefs boolForKey:@"useMonospacedFonts"] ) { + if ( [prefs boolForKey:@"UseMonospacedFonts"] ) { [[fieldColumn dataCell] setFont:[NSFont fontWithName:@"Monaco" size:[NSFont smallSystemFontSize]]]; } else @@ -542,7 +542,7 @@ fetches the result as an array with a dictionary for each row in it for (int i = 0; i < [keys count] ; i++) { key = [keys objectAtIndex:i]; if ( [[tempRow objectForKey:key] isMemberOfClass:[NSNull class]] ) - [tempRow setObject:[prefs objectForKey:@"nullValue"] forKey:key]; + [tempRow setObject:[prefs objectForKey:@"NullValue"] forKey:key]; } // change some fields to be more human-readable or GUI compatible if ( [[tempRow objectForKey:@"Extra"] isEqualToString:@""] ) { @@ -646,7 +646,7 @@ returns YES if no row is beeing edited and nothing has to be written to db if ( [[theRow objectForKey:@"Null"] isEqualToString:@"NO"] ) [queryString appendString:@" NOT NULL"]; if ( ![[theRow objectForKey:@"Extra"] isEqualToString:@"auto_increment"] && !([[theRow objectForKey:@"Type"] isEqualToString:@"timestamp"] && [[theRow objectForKey:@"Default"] isEqualToString:@"NULL"]) ) { - if ( [[theRow objectForKey:@"Default"] isEqualToString:[prefs objectForKey:@"nullValue"]] ) { + if ( [[theRow objectForKey:@"Default"] isEqualToString:[prefs objectForKey:@"NullValue"]] ) { if ([[theRow objectForKey:@"Null"] isEqualToString:@"YES"] ) { [queryString appendString:@" DEFAULT NULL "]; } @@ -793,9 +793,9 @@ get the default value for a specified field - (NSString *)defaultValueForField:(NSString *)field { if ( ![defaultValues objectForKey:field] ) { - return [prefs objectForKey:@"nullValue"]; + return [prefs objectForKey:@"NullValue"]; } else if ( [[defaultValues objectForKey:field] isMemberOfClass:[NSNull class]] ) { - return [prefs objectForKey:@"nullValue"]; + return [prefs objectForKey:@"NullValue"]; } else { return [defaultValues objectForKey:field]; } @@ -980,7 +980,7 @@ would result in a position change. } // Add the default value - if ([[originalRow objectForKey:@"Default"] isEqualToString:[prefs objectForKey:@"nullValue"]]) { + if ([[originalRow objectForKey:@"Default"] isEqualToString:[prefs objectForKey:@"NullValue"]]) { if ([[originalRow objectForKey:@"Null"] isEqualToString:@"YES"]) { [queryString appendString:@" DEFAULT NULL"]; } diff --git a/Source/TablesList.m b/Source/TablesList.m index 8f51c0bf..148c7ab2 100644 --- a/Source/TablesList.m +++ b/Source/TablesList.m @@ -656,7 +656,7 @@ // 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:@"encoding"] isEqualToString:@"Autodetect"]) { + if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"DefaultEncoding"] isEqualToString:@"Autodetect"]) { if (![[tableDataInstance tableEncoding] isEqualToString:[tableDocumentInstance connectionEncoding]]) { [tableDocumentInstance setConnectionEncoding:[tableDataInstance tableEncoding] reloadingViews:NO]; [tableDataInstance resetAllData]; @@ -728,14 +728,9 @@ } else { [(ImageAndTextCell*)aCell setImage:[NSImage imageNamed:@"table-small"]]; } + [(ImageAndTextCell*)aCell setIndentationLevel:1]; - if ( [[NSUserDefaults standardUserDefaults] boolForKey:@"useMonospacedFonts"] ) { - [(ImageAndTextCell*)aCell setFont:[NSFont fontWithName:@"Monaco" size:[NSFont smallSystemFontSize]]]; - } - else - { - [(ImageAndTextCell*)aCell setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; - } + [(ImageAndTextCell*)aCell setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; } else { [(ImageAndTextCell*)aCell setImage:nil]; [(ImageAndTextCell*)aCell setIndentationLevel:0]; |