aboutsummaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authoravenjamin <avenjamin@gmail.com>2009-04-10 15:11:22 +0000
committeravenjamin <avenjamin@gmail.com>2009-04-10 15:11:22 +0000
commitb69bbf81201e94b82232e73a0d43a96f10af2fa9 (patch)
treef207f57773c968610a89108cbc92dfd4e6b01e2c /Source
parent06bfa0d4c2f79aeda9c3585a80c13845029cfa2d (diff)
downloadsequelpro-b69bbf81201e94b82232e73a0d43a96f10af2fa9.tar.gz
sequelpro-b69bbf81201e94b82232e73a0d43a96f10af2fa9.tar.bz2
sequelpro-b69bbf81201e94b82232e73a0d43a96f10af2fa9.zip
- part 4 of merge from 'avenjamin' branch into trunk.
- committing Source
Diffstat (limited to 'Source')
-rw-r--r--Source/MainController.h52
-rw-r--r--Source/MainController.m756
-rw-r--r--Source/SPExportController.h91
-rw-r--r--Source/SPExportController.m177
-rw-r--r--Source/SPFavoriteTextFieldCell.h44
-rw-r--r--Source/SPFavoriteTextFieldCell.m239
-rw-r--r--Source/SPPreferenceController.h74
-rw-r--r--Source/SPPreferenceController.m574
-rw-r--r--Source/SPTableInfo.m2
-rw-r--r--Source/SPWindowAdditions.h30
-rw-r--r--Source/SPWindowAdditions.m75
-rw-r--r--Source/TableContent.m104
-rw-r--r--Source/TableDocument.h3
-rw-r--r--Source/TableDocument.m42
-rw-r--r--Source/TableDump.h13
-rw-r--r--Source/TableDump.m68
-rw-r--r--Source/TableSource.m16
-rw-r--r--Source/TablesList.m11
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];