diff options
author | stuconnolly <stuart02@gmail.com> | 2010-12-08 19:03:47 +0000 |
---|---|---|
committer | stuconnolly <stuart02@gmail.com> | 2010-12-08 19:03:47 +0000 |
commit | 61e398816badc49b301a6ae70c3697d581258cfb (patch) | |
tree | cca1e18f88c42556b4a5e48c1e685cb2b6574b78 /Source/SPCopyTable.m | |
parent | 3fccc9c751cded1360aa22796ed3c6d700fd04c1 (diff) | |
parent | 5b88ac6a6d0c02b1b51f295cf79e84b61c1f1bd5 (diff) | |
download | sequelpro-61e398816badc49b301a6ae70c3697d581258cfb.tar.gz sequelpro-61e398816badc49b301a6ae70c3697d581258cfb.tar.bz2 sequelpro-61e398816badc49b301a6ae70c3697d581258cfb.zip |
Bring outline view branch up to date with trunk (r2976:2988).
Diffstat (limited to 'Source/SPCopyTable.m')
-rw-r--r-- | Source/SPCopyTable.m | 432 |
1 files changed, 259 insertions, 173 deletions
diff --git a/Source/SPCopyTable.m b/Source/SPCopyTable.m index 493c3fb4..58339976 100644 --- a/Source/SPCopyTable.m +++ b/Source/SPCopyTable.m @@ -922,6 +922,178 @@ NSInteger kBlobAsImageFile = 4; } +/** + * Only have the copy menu item enabled when row(s) are selected in + * supported tables. + */ +- (BOOL) validateMenuItem:(NSMenuItem*)anItem +{ + NSInteger menuItemTag = [anItem tag]; + + // Don't validate anything other than the copy commands + if (menuItemTag != MENU_EDIT_COPY && menuItemTag != MENU_EDIT_COPY_WITH_COLUMN && menuItemTag != MENU_EDIT_COPY_AS_SQL) { + return YES; + } + + // Don't enable menus for relations or triggers - no action to take yet + if ([[self delegate] isKindOfClass:[SPTableRelations class]] || [[self delegate] isKindOfClass:[SPTableTriggers class]]) { + return NO; + } + + // Enable the Copy [with column names] commands if a row is selected + if (menuItemTag == MENU_EDIT_COPY || menuItemTag == MENU_EDIT_COPY_WITH_COLUMN) { + return ([self numberOfSelectedRows] > 0); + } + + // Enable the Copy as SQL commands if rows are selected and column definitions are available + if (menuItemTag == MENU_EDIT_COPY_AS_SQL) { + return (columnDefinitions != nil && [self numberOfSelectedRows] > 0); + } + + return NO; +} + +/** + * Trap the enter, escape, tab and arrow keys, overriding default behaviour and continuing/ending editing, + * only within the current row. + */ +- (BOOL) control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)command +{ + + NSUInteger row, column; + + row = [self editedRow]; + column = [self 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 ( [self numberOfColumns] - 1 == column ) { + if([[self delegate] respondsToSelector:@selector(addRowToDB)]) + [[self delegate] addRowToDB]; + [[self window] makeFirstResponder:self]; + } else { + // Select the next field for editing + [self 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 ) { + if([[self delegate] respondsToSelector:@selector(addRowToDB)]) + [[self delegate] addRowToDB]; + [[self window] makeFirstResponder:self]; + } else { + // Select the previous field for editing + [self editColumn:column-1 row:row withEvent:nil select:YES]; + } + + return YES; + } + + // Trap enter key + else if ( [textView methodForSelector:command] == [textView methodForSelector:@selector(insertNewline:)] ) + { + // If enum field is edited RETURN selects the new value instead of saving the entire row + if([self isCellComplex]) + return YES; + + [[control window] makeFirstResponder:control]; + if([[self delegate] isKindOfClass:[SPTableContent class]] && ![self isCellEditingMode] && [[self delegate] respondsToSelector:@selector(addRowToDB)]) + [[self delegate] addRowToDB]; + return YES; + + } + + // Trap down arrow key + else if ( [textView methodForSelector:command] == [textView methodForSelector:@selector(moveDown:)] ) + { + + // If enum field is edited ARROW key navigates through the popup list + if([self isCellComplex]) + return NO; + + NSUInteger newRow = row+1; + if (newRow>=[[self delegate] numberOfRowsInTableView:self]) return YES; //check if we're already at the end of the list + + [[control window] makeFirstResponder:control]; + if([[self delegate] isKindOfClass:[SPTableContent class]] && ![self isCellEditingMode] && [[self delegate] respondsToSelector:@selector(addRowToDB)]) + [[self delegate] addRowToDB]; + + if (newRow>=[[self delegate] numberOfRowsInTableView:self]) return YES; //check again. addRowToDB could reload the table and change the number of rows + if (tableStorage && column>=[tableStorage columnCount]) return YES; //the column count could change too + + [self selectRowIndexes:[NSIndexSet indexSetWithIndex:newRow] byExtendingSelection:NO]; + [self editColumn:column row:newRow withEvent:nil select:YES]; + return YES; + } + + // Trap up arrow key + else if ( [textView methodForSelector:command] == [textView methodForSelector:@selector(moveUp:)] ) + { + + // If enum field is edited ARROW key navigates through the popup list + if([self isCellComplex]) + return NO; + + if (row==0) return YES; //already at the beginning of the list + NSUInteger newRow = row-1; + + [[control window] makeFirstResponder:control]; + if([[self delegate] isKindOfClass:[SPTableContent class]] && ![self isCellEditingMode] && [[self delegate] respondsToSelector:@selector(addRowToDB)]) + [[self delegate] addRowToDB]; + + if (newRow>=[[self delegate] numberOfRowsInTableView:self]) return YES; // addRowToDB could reload the table and change the number of rows + if (tableStorage && column>=[tableStorage columnCount]) return YES; //the column count could change too + + [self selectRowIndexes:[NSIndexSet indexSetWithIndex:newRow] byExtendingSelection:NO]; + [self editColumn:column row:newRow withEvent:nil select:YES]; + return YES; + } + + return NO; +} + +- (void) keyDown:(NSEvent *)theEvent +{ + + // RETURN or ENTER invoke editing mode for selected row + // by calling tableView:shouldEditTableColumn: to validate + + if([self numberOfSelectedRows] == 1 && ([theEvent keyCode] == 36 || [theEvent keyCode] == 76)) { + [self editColumn:0 row:[self selectedRow] withEvent:nil select:YES]; + return; + } + + // Check if ESCAPE is hit and use it to cancel row editing if supported + if ([theEvent keyCode] == 53 && [[self delegate] respondsToSelector:@selector(cancelRowEditing)]) + { + if ([[self delegate] cancelRowEditing]) return; + } + + else if ([theEvent keyCode] == 48 && ([[self delegate] isKindOfClass:[SPCustomQuery class]] + || [[self delegate] isKindOfClass:[SPTableContent class]])) { + [self editColumn:0 row:[self selectedRow] withEvent:nil select:YES]; + return; + } + + [super keyDown:theEvent]; +} + +#pragma mark - +#pragma mark Bundle Command Support + - (IBAction)executeBundleItemForDataTable:(id)sender { NSInteger idx = [sender tag] - 1000000; @@ -964,6 +1136,7 @@ NSInteger kBlobAsImageFile = 4; NSError *err = nil; NSString *uuid = [NSString stringWithNewUUID]; NSString *bundleInputFilePath = [NSString stringWithFormat:@"%@_%@", SPBundleTaskInputFilePath, uuid]; + NSString *bundleInputTableMetaDataFilePath = [NSString stringWithFormat:@"%@_%@", SPBundleTaskTableMetaDataFilePath, uuid]; [[NSFileManager defaultManager] removeItemAtPath:bundleInputFilePath error:nil]; @@ -973,12 +1146,15 @@ NSInteger kBlobAsImageFile = 4; inputFallBackAction = [[cmdData objectForKey:SPBundleFileInputSourceFallBackKey] lowercaseString]; NSMutableDictionary *env = [NSMutableDictionary dictionary]; - [env setObject:[infoPath stringByDeletingLastPathComponent] forKey:@"SP_BUNDLE_PATH"]; - [env setObject:bundleInputFilePath forKey:@"SP_BUNDLE_INPUT_FILE"]; + [env setObject:[infoPath stringByDeletingLastPathComponent] forKey:SPBundleShellVariableBundlePath]; + [env setObject:bundleInputFilePath forKey:SPBundleShellVariableInputFilePath]; if([[self delegate] respondsToSelector:@selector(usedQuery)] && [[self delegate] usedQuery]) [env setObject:[[self delegate] usedQuery] forKey:@"SP_USED_QUERY_FOR_TABLE"]; + [env setObject:bundleInputTableMetaDataFilePath forKey:SPBundleShellVariableInputTableMetaData]; + [env setObject:SPBundleScopeDataTable forKey:SPBundleShellVariableScope]; + if([self numberOfSelectedRows]) { NSMutableArray *sel = [NSMutableArray array]; NSIndexSet *selectedRows = [self selectedRowIndexes]; @@ -1006,7 +1182,7 @@ NSInteger kBlobAsImageFile = 4; if(blobHandling != kBlobExclude) { NSString *bundleBlobFilePath = [NSString stringWithFormat:@"%@_%@", SPBundleTaskCopyBlobFileDirectory, uuid]; - [env setObject:bundleBlobFilePath forKey:@"SP_BUNDLE_BLOB_FILES_DIRECTORY"]; + [env setObject:bundleBlobFilePath forKey:SPBundleShellVariableBlobFileDirectory]; [self setCopyBlobFileDirectory:bundleBlobFilePath]; } else { [self setCopyBlobFileDirectory:@""]; @@ -1045,21 +1221,100 @@ NSInteger kBlobAsImageFile = 4; return; } + NSMutableString *tableMetaData = [NSMutableString string]; + if([[self delegate] isKindOfClass:[SPCustomQuery class]]) { + NSArray *defs = [[self delegate] dataColumnDefinitions]; + for(NSDictionary* col in defs) { + [tableMetaData appendFormat:@"%@\t", [col objectForKey:@"type"]]; + [tableMetaData appendFormat:@"%@\t", [col objectForKey:@"typegrouping"]]; + [tableMetaData appendFormat:@"%@\t", ([col objectForKey:@"char_length"]) ? : @""]; + [tableMetaData appendFormat:@"%@\t", [col objectForKey:@"UNSIGNED_FLAG"]]; + [tableMetaData appendFormat:@"%@\t", [col objectForKey:@"AUTO_INCREMENT_FLAG"]]; + [tableMetaData appendFormat:@"%@\t", [col objectForKey:@"PRI_KEY_FLAG"]]; + [tableMetaData appendString:@"\n"]; + } + } + else if([[self delegate] isKindOfClass:[SPTableContent class]]) { + NSArray *defs = [[self delegate] dataColumnDefinitions]; + for(NSDictionary* col in defs) { + [tableMetaData appendFormat:@"%@\t", [col objectForKey:@"type"]]; + [tableMetaData appendFormat:@"%@\t", [col objectForKey:@"typegrouping"]]; + [tableMetaData appendFormat:@"%@\t", ([col objectForKey:@"length"]) ? : @""]; + [tableMetaData appendFormat:@"%@\t", [col objectForKey:@"unsigned"]]; + [tableMetaData appendFormat:@"%@\t", [col objectForKey:@"autoincrement"]]; + [tableMetaData appendFormat:@"%@\t", ([col objectForKey:@"isprimarykey"]) ? : @"0"]; + [tableMetaData appendFormat:@"%@\n", [col objectForKey:@"comment"]]; + } + } + + inputFileError = nil; + [tableMetaData writeToFile:bundleInputTableMetaDataFilePath + atomically:YES + encoding:NSUTF8StringEncoding + error:&inputFileError]; + + if(inputFileError != nil) { + NSString *errorMessage = [inputFileError localizedDescription]; + SPBeginAlertSheet(NSLocalizedString(@"Bundle Error", @"bundle error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [self window], self, nil, nil, + [NSString stringWithFormat:@"%@ “%@”:\n%@", NSLocalizedString(@"Error for", @"error for message"), [cmdData objectForKey:@"name"], errorMessage]); + if (cmdData) [cmdData release]; + return; + } + + NSString *output = [cmd runBashCommandWithEnvironment:env atCurrentDirectoryPath:nil callerInstance:[[NSApp delegate] frontDocument] contextInfo:[NSDictionary dictionaryWithObjectsAndKeys: ([cmdData objectForKey:SPBundleFileNameKey])?:@"-", @"name", NSLocalizedString(@"Data Table", @"data table menu item label"), @"scope", + uuid, SPBundleFileInternalexecutionUUID, nil] error:&err]; [[NSFileManager defaultManager] removeItemAtPath:bundleInputFilePath error:nil]; + NSString *action = [[cmdData objectForKey:SPBundleFileOutputActionKey] lowercaseString]; + + // Redirect due exit code + if(err != nil) { + if([err code] == SPBundleRedirectActionNone) { + action = SPBundleOutputActionNone; + err = nil; + } + else if([err code] == SPBundleRedirectActionReplaceSection) { + action = SPBundleOutputActionReplaceSelection; + err = nil; + } + else if([err code] == SPBundleRedirectActionReplaceContent) { + action = SPBundleOutputActionReplaceContent; + err = nil; + } + else if([err code] == SPBundleRedirectActionInsertAsText) { + action = SPBundleOutputActionInsertAsText; + err = nil; + } + else if([err code] == SPBundleRedirectActionInsertAsSnippet) { + action = SPBundleOutputActionInsertAsSnippet; + err = nil; + } + else if([err code] == SPBundleRedirectActionShowAsHTML) { + action = SPBundleOutputActionShowAsHTML; + err = nil; + } + else if([err code] == SPBundleRedirectActionShowAsTextTooltip) { + action = SPBundleOutputActionShowAsTextTooltip; + err = nil; + } + else if([err code] == SPBundleRedirectActionShowAsHTMLTooltip) { + action = SPBundleOutputActionShowAsHTMLTooltip; + err = nil; + } + } + if(err == nil && output) { if([cmdData objectForKey:SPBundleFileOutputActionKey] && [[cmdData objectForKey:SPBundleFileOutputActionKey] length] && ![[cmdData objectForKey:SPBundleFileOutputActionKey] isEqualToString:SPBundleOutputActionNone]) { - NSString *action = [[cmdData objectForKey:SPBundleFileOutputActionKey] lowercaseString]; NSPoint pos = [NSEvent mouseLocation]; pos.y -= 16; @@ -1104,175 +1359,6 @@ NSInteger kBlobAsImageFile = 4; } -/** - * Only have the copy menu item enabled when row(s) are selected in - * supported tables. - */ -- (BOOL) validateMenuItem:(NSMenuItem*)anItem -{ - NSInteger menuItemTag = [anItem tag]; - - // Don't validate anything other than the copy commands - if (menuItemTag != MENU_EDIT_COPY && menuItemTag != MENU_EDIT_COPY_WITH_COLUMN && menuItemTag != MENU_EDIT_COPY_AS_SQL) { - return YES; - } - - // Don't enable menus for relations or triggers - no action to take yet - if ([[self delegate] isKindOfClass:[SPTableRelations class]] || [[self delegate] isKindOfClass:[SPTableTriggers class]]) { - return NO; - } - - // Enable the Copy [with column names] commands if a row is selected - if (menuItemTag == MENU_EDIT_COPY || menuItemTag == MENU_EDIT_COPY_WITH_COLUMN) { - return ([self numberOfSelectedRows] > 0); - } - - // Enable the Copy as SQL commands if rows are selected and column definitions are available - if (menuItemTag == MENU_EDIT_COPY_AS_SQL) { - return (columnDefinitions != nil && [self numberOfSelectedRows] > 0); - } - - return NO; -} - -/** - * Trap the enter, escape, tab and arrow keys, overriding default behaviour and continuing/ending editing, - * only within the current row. - */ -- (BOOL) control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)command -{ - - NSUInteger row, column; - - row = [self editedRow]; - column = [self 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 ( [self numberOfColumns] - 1 == column ) { - if([[self delegate] respondsToSelector:@selector(addRowToDB)]) - [[self delegate] addRowToDB]; - [[self window] makeFirstResponder:self]; - } else { - // Select the next field for editing - [self 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 ) { - if([[self delegate] respondsToSelector:@selector(addRowToDB)]) - [[self delegate] addRowToDB]; - [[self window] makeFirstResponder:self]; - } else { - // Select the previous field for editing - [self editColumn:column-1 row:row withEvent:nil select:YES]; - } - - return YES; - } - - // Trap enter key - else if ( [textView methodForSelector:command] == [textView methodForSelector:@selector(insertNewline:)] ) - { - // If enum field is edited RETURN selects the new value instead of saving the entire row - if([self isCellComplex]) - return YES; - - [[control window] makeFirstResponder:control]; - if([[self delegate] isKindOfClass:[SPTableContent class]] && ![self isCellEditingMode] && [[self delegate] respondsToSelector:@selector(addRowToDB)]) - [[self delegate] addRowToDB]; - return YES; - - } - - // Trap down arrow key - else if ( [textView methodForSelector:command] == [textView methodForSelector:@selector(moveDown:)] ) - { - - // If enum field is edited ARROW key navigates through the popup list - if([self isCellComplex]) - return NO; - - NSUInteger newRow = row+1; - if (newRow>=[[self delegate] numberOfRowsInTableView:self]) return YES; //check if we're already at the end of the list - - [[control window] makeFirstResponder:control]; - if([[self delegate] isKindOfClass:[SPTableContent class]] && ![self isCellEditingMode] && [[self delegate] respondsToSelector:@selector(addRowToDB)]) - [[self delegate] addRowToDB]; - - if (newRow>=[[self delegate] numberOfRowsInTableView:self]) return YES; //check again. addRowToDB could reload the table and change the number of rows - if (tableStorage && column>=[tableStorage columnCount]) return YES; //the column count could change too - - [self selectRowIndexes:[NSIndexSet indexSetWithIndex:newRow] byExtendingSelection:NO]; - [self editColumn:column row:newRow withEvent:nil select:YES]; - return YES; - } - - // Trap up arrow key - else if ( [textView methodForSelector:command] == [textView methodForSelector:@selector(moveUp:)] ) - { - - // If enum field is edited ARROW key navigates through the popup list - if([self isCellComplex]) - return NO; - - if (row==0) return YES; //already at the beginning of the list - NSUInteger newRow = row-1; - - [[control window] makeFirstResponder:control]; - if([[self delegate] isKindOfClass:[SPTableContent class]] && ![self isCellEditingMode] && [[self delegate] respondsToSelector:@selector(addRowToDB)]) - [[self delegate] addRowToDB]; - - if (newRow>=[[self delegate] numberOfRowsInTableView:self]) return YES; // addRowToDB could reload the table and change the number of rows - if (tableStorage && column>=[tableStorage columnCount]) return YES; //the column count could change too - - [self selectRowIndexes:[NSIndexSet indexSetWithIndex:newRow] byExtendingSelection:NO]; - [self editColumn:column row:newRow withEvent:nil select:YES]; - return YES; - } - - return NO; -} - -- (void) keyDown:(NSEvent *)theEvent -{ - - // RETURN or ENTER invoke editing mode for selected row - // by calling tableView:shouldEditTableColumn: to validate - - if([self numberOfSelectedRows] == 1 && ([theEvent keyCode] == 36 || [theEvent keyCode] == 76)) { - [self editColumn:0 row:[self selectedRow] withEvent:nil select:YES]; - return; - } - - // Check if ESCAPE is hit and use it to cancel row editing if supported - if ([theEvent keyCode] == 53 && [[self delegate] respondsToSelector:@selector(cancelRowEditing)]) - { - if ([[self delegate] cancelRowEditing]) return; - } - - else if ([theEvent keyCode] == 48 && ([[self delegate] isKindOfClass:[SPCustomQuery class]] - || [[self delegate] isKindOfClass:[SPTableContent class]])) { - [self editColumn:0 row:[self selectedRow] withEvent:nil select:YES]; - return; - } - - [super keyDown:theEvent]; -} - #pragma mark - - (void) awakeFromNib |