aboutsummaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/SPDataImport.h1
-rw-r--r--Source/SPDataImport.m39
-rw-r--r--Source/SPFieldMapperController.h4
-rw-r--r--Source/SPFieldMapperController.m182
-rw-r--r--Source/SPTableView.m10
-rw-r--r--Source/SPTablesList.m2
6 files changed, 220 insertions, 18 deletions
diff --git a/Source/SPDataImport.h b/Source/SPDataImport.h
index 9a9dedf5..97ba134f 100644
--- a/Source/SPDataImport.h
+++ b/Source/SPDataImport.h
@@ -94,6 +94,7 @@
BOOL csvImportMethodHasTail;
BOOL insertRemainingRowsAfterUpdate;
BOOL importMethodIsUpdate;
+ BOOL importIntoNewTable;
NSUInteger exportMode;
NSUserDefaults *prefs;
diff --git a/Source/SPDataImport.m b/Source/SPDataImport.m
index c9b5664b..efc85bbc 100644
--- a/Source/SPDataImport.m
+++ b/Source/SPDataImport.m
@@ -76,8 +76,10 @@
fieldMappingImportArrayIsPreview = NO;
fieldMappingArrayHasGlobalVariables = NO;
importMethodIsUpdate = NO;
+ importIntoNewTable = NO;
insertRemainingRowsAfterUpdate = NO;
numberOfImportDataColumns = 0;
+ selectedTableTarget = nil;
prefs = nil;
lastFilename = nil;
@@ -1074,15 +1076,34 @@
document:tableDocumentInstance
notificationName:@"Import Finished"];
- // If the table selected for import is also selected in the content view,
- // update the content view - on the main thread to avoid crashes.
- if ([tablesListInstance tableName] && [selectedTableTarget isEqualToString:[tablesListInstance tableName]]) {
- if ([[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:SPMainToolbarTableContent]) {
- [tableContentInstance performSelectorOnMainThread:@selector(reloadTable:) withObject:nil waitUntilDone:YES];
- } else {
- [tablesListInstance setContentRequiresReload:YES];
+
+ if(importIntoNewTable) {
+
+ // Select the new table
+
+ // Update current database tables
+ [tablesListInstance performSelectorOnMainThread:@selector(updateTables:) withObject:self waitUntilDone:YES];
+
+ // Re-query the structure of all databases in the background
+ [NSThread detachNewThreadSelector:@selector(queryDbStructureWithUserInfo:) toTarget:mySQLConnection withObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"forceUpdate", nil]];
+
+ // Select the new table
+ [tablesListInstance selectItemWithName:selectedTableTarget];
+
+ } else {
+
+ // If import was done into a new table or the table selected for import is also selected in the content view,
+ // update the content view - on the main thread to avoid crashes.
+ if ([tablesListInstance tableName] && [selectedTableTarget isEqualToString:[tablesListInstance tableName]]) {
+ if ([[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:SPMainToolbarTableContent]) {
+ [tableContentInstance performSelectorOnMainThread:@selector(reloadTable:) withObject:nil waitUntilDone:YES];
+ } else {
+ [tablesListInstance setContentRequiresReload:YES];
+ }
}
+
}
+
}
/**
@@ -1165,13 +1186,14 @@
// Get mapping settings and preset some global variables
fieldMapperOperator = [[NSArray arrayWithArray:[fieldMapperController fieldMapperOperator]] retain];
fieldMappingArray = [[NSArray arrayWithArray:[fieldMapperController fieldMappingArray]] retain];
- selectedTableTarget = [NSString stringWithString:[fieldMapperController selectedTableTarget]];
+ selectedTableTarget = [[NSString stringWithString:[fieldMapperController selectedTableTarget]] retain];
selectedImportMethod = [NSString stringWithString:[fieldMapperController selectedImportMethod]];
fieldMappingTableColumnNames = [[NSArray arrayWithArray:[fieldMapperController fieldMappingTableColumnNames]] retain];
fieldMappingGlobalValueArray = [[NSArray arrayWithArray:[fieldMapperController fieldMappingGlobalValueArray]] retain];
fieldMappingTableDefaultValues = [[NSArray arrayWithArray:[fieldMapperController fieldMappingTableDefaultValues]] retain];
csvImportHeaderString = [[NSString stringWithString:[fieldMapperController importHeaderString]] retain];
csvImportTailString = [[NSString stringWithString:[fieldMapperController onupdateString]] retain];
+ importIntoNewTable = [fieldMapperController importIntoNewTable];
fieldMappingArrayHasGlobalVariables = [fieldMapperController globalValuesInUsage];
csvImportMethodHasTail = ([csvImportTailString length] == 0) ? NO : YES;
insertRemainingRowsAfterUpdate = [fieldMapperController insertRemainingRowsAfterUpdate];
@@ -1475,6 +1497,7 @@
if (fieldMappingImportArray) [fieldMappingImportArray release];
if (lastFilename) [lastFilename release];
if (prefs) [prefs release];
+ if(selectedTableTarget) [selectedTableTarget release];
for (id retainedObject in nibObjectsToRelease) [retainedObject release];
diff --git a/Source/SPFieldMapperController.h b/Source/SPFieldMapperController.h
index 15efd595..da5b6ca2 100644
--- a/Source/SPFieldMapperController.h
+++ b/Source/SPFieldMapperController.h
@@ -24,12 +24,13 @@
#import <Cocoa/Cocoa.h>
#import <MCPKit/MCPKit.h>
+#import "SPTableView.h"
@class SPTextView;
@interface SPFieldMapperController : NSWindowController
{
- IBOutlet NSTableView *fieldMapperTableView;
+ IBOutlet id fieldMapperTableView;
IBOutlet id fieldMapperTableScrollView;
IBOutlet NSTableView *globalValuesTableView;
IBOutlet NSPopUpButton *tableTargetPopup;
@@ -138,6 +139,7 @@
- (BOOL)importFieldNamesHeader;
- (BOOL)insertRemainingRowsAfterUpdate;
- (BOOL)globalValuesInUsage;
+- (BOOL)importIntoNewTable;
- (NSString*)onupdateString;
- (NSString*)importHeaderString;
diff --git a/Source/SPFieldMapperController.m b/Source/SPFieldMapperController.m
index 1018ff4e..b9f41935 100644
--- a/Source/SPFieldMapperController.m
+++ b/Source/SPFieldMapperController.m
@@ -77,6 +77,8 @@
prefs = [NSUserDefaults standardUserDefaults];
tablesListInstance = [theDelegate valueForKeyPath:@"tablesListInstance"];
+ [fieldMapperTableView setDelegate:self];
+ [fieldMapperTableView setDataSource:self];
}
@@ -218,7 +220,11 @@
- (NSString*)selectedTableTarget
{
+
+ if(newTableMode) return [newTableNameTextField stringValue];
+
return ([tableTargetPopup titleOfSelectedItem] == nil) ? @"" : [tableTargetPopup titleOfSelectedItem];
+
}
- (NSArray*)fieldMapperOperator
@@ -259,6 +265,11 @@
return NO;
}
+- (BOOL)importIntoNewTable
+{
+ return newTableMode;
+}
+
- (NSArray*)fieldMappingTableColumnNames
{
return fieldMappingTableColumnNames;
@@ -318,6 +329,38 @@
- (IBAction)closeSheet:(id)sender
{
+
+ // Try to create the new TABLE
+ if(newTableMode && [sender tag] == 1) {
+
+ [[self window] endEditingFor:nil];
+
+ NSMutableString *createString = [NSMutableString string];
+ [createString appendFormat:@"CREATE TABLE %@ (\n", [[newTableNameTextField stringValue] backtickQuotedString]];
+ NSInteger columnIndex = 0;
+ NSInteger numberOfColumns = [fieldMappingTableColumnNames count];
+ for(columnIndex = 0; columnIndex < numberOfColumns; columnIndex++) {
+ [createString appendFormat:@"\t%@ %@", [[fieldMappingTableColumnNames objectAtIndex:columnIndex] backtickQuotedString], [fieldMappingTableTypes objectAtIndex:columnIndex]];
+ if(columnIndex < numberOfColumns-1) [createString appendString:@", \n"];
+ }
+ [createString appendString:@")"];
+ [mySQLConnection queryString:createString];
+
+ if ([mySQLConnection queryErrored]) {
+ NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"Error adding new table", @"error adding new table message")
+ defaultButton:NSLocalizedString(@"OK", @"OK button")
+ alternateButton:nil
+ otherButton:nil
+ informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to add the new table '%@' by\n\n%@.\n\nMySQL said: %@", @"error adding new table informative message"), [newTableNameTextField stringValue], createString, [mySQLConnection getLastErrorMessage]]];
+
+ [alert setAlertStyle:NSCriticalAlertStyle];
+ [alert beginSheetModalForWindow:[self window] modalDelegate:self didEndSelector:nil contextInfo:nil];
+ return;
+ }
+
+ }
+
+
[advancedReplaceView setHidden:YES];
[advancedUpdateView setHidden:YES];
[advancedInsertView setHidden:YES];
@@ -1026,13 +1069,22 @@
BOOL enableImportButton = YES;
if(newTableMode) {
- [importButton setTitle:@"Not Yet"];
- [importButton setEnabled:NO];
- return;
if(![tablesListInstance isTableNameValid:[newTableNameTextField stringValue] forType:SPTableTypeTable ignoringSelectedTable:NO]) {
[importButton setEnabled:NO];
return;
}
+ for(NSString* fieldName in fieldMappingTableColumnNames) {
+ if(![fieldName length]) {
+ [importButton setEnabled:NO];
+ return;
+ }
+ }
+ for(NSString* fieldType in fieldMappingTableTypes) {
+ if(![fieldType length]) {
+ [importButton setEnabled:NO];
+ return;
+ }
+ }
}
if([[self selectedImportMethod] isEqualToString:@"UPDATE"]) {
@@ -1316,7 +1368,7 @@
[self validateImportButton];
}
// Refresh table
- [aTableView performSelector:@selector(reloadData) withObject:nil afterDelay:0.01];
+ // [aTableView performSelector:@selector(reloadData) withObject:nil afterDelay:0.01];
}
else if(aTableView == globalValuesTableView) {
if ([[aTableColumn identifier] isEqualToString:@"global_value"])
@@ -1337,17 +1389,131 @@
}
+
+/*
+ * Trap the enter, escape, tab and arrow keys, overriding default behaviour and continuing/ending editing,
+ * only within the current row of the tableView only in newTableMode.
+ */
+- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)command
+{
+
+ if(!newTableMode) return NO;
+
+ NSUInteger row, column;
+
+ row = [fieldMapperTableView editedRow];
+ column = [fieldMapperTableView editedColumn];
+
+ // Trap tab key
+ // -- for handling of blob fields and to check if it's editable look at [[self delegate] control:textShouldBeginEditing:]
+ if ( [textView methodForSelector:command] == [textView methodForSelector:@selector(insertTab:)] )
+ {
+ [[control window] makeFirstResponder:control];
+
+ // Save the current line if it's the last field in the table
+ if ( [fieldMapperTableView numberOfColumns] - 1 == column) {
+ [fieldMapperTableView makeFirstResponder];
+ } else {
+ // Select the next field for editing
+ [fieldMapperTableView editColumn:column+1 row:row withEvent:nil select:YES];
+ }
+
+ return YES;
+ }
+
+ // Trap shift-tab key
+ else if ( [textView methodForSelector:command] == [textView methodForSelector:@selector(insertBacktab:)] )
+ {
+ [[control window] makeFirstResponder:control];
+
+ // Save the current line if it's the last field in the table
+ if ( column < 1 ) {
+ [fieldMapperTableView makeFirstResponder];
+ } else {
+ // Select the previous field for editing
+ [fieldMapperTableView editColumn:column-1 row:row withEvent:nil select:YES];
+ }
+
+ return YES;
+ }
+
+ // Trap enter key
+ else if ( [textView methodForSelector:command] == [textView methodForSelector:@selector(insertNewline:)] )
+ {
+
+ // If newTableNameTextField is active enter key closes the sheet
+ if(control == newTableNameTextField) {
+ NSButton *b = [[[NSButton alloc] init] autorelease];
+ [b setTag:1];
+ [self closeSheet:b];
+ return YES;
+ }
+
+ [[self window] endEditingFor:nil];
+ [[control window] makeFirstResponder:control];
+ return YES;
+
+ }
+
+ // Trap down arrow key
+ else if ( [textView methodForSelector:command] == [textView methodForSelector:@selector(moveDown:)] )
+ {
+
+ NSUInteger newRow = row+1;
+ if (newRow>=[self numberOfRowsInTableView:fieldMapperTableView]) return YES; //check if we're already at the end of the list
+
+ [[control window] makeFirstResponder:control];
+
+ [fieldMapperTableView selectRowIndexes:[NSIndexSet indexSetWithIndex:newRow] byExtendingSelection:NO];
+ [fieldMapperTableView editColumn:column row:newRow withEvent:nil select:YES];
+ return YES;
+ }
+
+ // Trap up arrow key
+ else if ( [textView methodForSelector:command] == [textView methodForSelector:@selector(moveUp:)] )
+ {
+
+ if (row==0) return YES; //already at the beginning of the list
+ NSUInteger newRow = row-1;
+
+ [[control window] makeFirstResponder:control];
+
+ [fieldMapperTableView selectRowIndexes:[NSIndexSet indexSetWithIndex:newRow] byExtendingSelection:NO];
+ [fieldMapperTableView editColumn:column row:newRow withEvent:nil select:YES];
+ return YES;
+ }
+
+
+ // Trap the escape key
+ else if ( [[control window] methodForSelector:command] == [[control window] methodForSelector:@selector(cancelOperation:)] )
+ {
+
+ // Abort editing
+ [control abortEditing];
+
+ // Preserve the focus
+ [fieldMapperTableView makeFirstResponder];
+
+ return TRUE;
+ }
+
+ return FALSE;
+
+}
+
#pragma mark -
#pragma mark NSTextField delegates
+
+/*
+ * Validate some user input in newTableMode
+ */
- (void)controlTextDidChange:(NSNotification *)notification
{
- id object = [notification object];
+ if(!newTableMode) return;
- if (object == newTableNameTextField) {
- [self validateImportButton];
- }
+ [self validateImportButton];
}
diff --git a/Source/SPTableView.m b/Source/SPTableView.m
index 8255f9c1..c19678db 100644
--- a/Source/SPTableView.m
+++ b/Source/SPTableView.m
@@ -87,9 +87,19 @@
- (void)keyDown:(NSEvent *)theEvent
{
+
// Check if ENTER or RETURN is hit and edit the column.
if([self numberOfSelectedRows] == 1 && ([theEvent keyCode] == 36 || [theEvent keyCode] == 76))
{
+
+ // ENTER or RETURN closes the SPFieldMapperController sheet by sending an object with the tag 1
+ if([[[[self delegate] class] description] isEqualToString:@"SPFieldMapperController"]) {
+ NSButton *b = [[[NSButton alloc] init] autorelease];
+ [b setTag:1];
+ [[self delegate] closeSheet:b];
+ return;
+ }
+
if (![[[[self delegate] class] description] isEqualToString:@"SPCustomQuery"] &&
![[[[self delegate] class] description] isEqualToString:@"SPQueryFavoriteManager"]){
diff --git a/Source/SPTablesList.m b/Source/SPTablesList.m
index e3a5cdd3..8075f244 100644
--- a/Source/SPTablesList.m
+++ b/Source/SPTablesList.m
@@ -1656,7 +1656,7 @@
[mySQLConnection queryString:query];
if ([mySQLConnection queryErrored]) {
- NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"Error while importing table", @"rror while importing table message")
+ NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"Error while importing table", @"error while importing table message")
defaultButton:NSLocalizedString(@"OK", @"OK button")
alternateButton:nil
otherButton:nil