diff options
-rw-r--r-- | Interfaces/English.lproj/DBView.xib | 6 | ||||
-rw-r--r-- | Source/SPCopyTable.m | 247 | ||||
-rw-r--r-- | Source/SPCustomQuery.h | 7 | ||||
-rw-r--r-- | Source/SPCustomQuery.m | 144 | ||||
-rw-r--r-- | Source/SPTableContent.m | 157 |
5 files changed, 358 insertions, 203 deletions
diff --git a/Interfaces/English.lproj/DBView.xib b/Interfaces/English.lproj/DBView.xib index 256df5df..2e29a3a4 100644 --- a/Interfaces/English.lproj/DBView.xib +++ b/Interfaces/English.lproj/DBView.xib @@ -24,7 +24,7 @@ <object class="NSMutableArray" key="IBDocument.EditedObjectIDs"> <bool key="EncodedWithXMLCoder">YES</bool> <integer value="6225"/> - <integer value="7223"/> + <integer value="7168"/> <integer value="7467"/> </object> <object class="NSArray" key="IBDocument.PluginDependencies"> @@ -3119,7 +3119,7 @@ </object> <object class="NSButton" id="67603994"> <reference key="NSNextResponder" ref="556476514"/> - <int key="NSvFlags">-2147483356</int> + <int key="NSvFlags">292</int> <string key="NSFrame">{{62, -1}, {32, 25}}</string> <reference key="NSSuperview" ref="556476514"/> <bool key="NSEnabled">YES</bool> @@ -23136,7 +23136,7 @@ IGRvIHlvdSB3YW50IHRvIGFkZCBmb3IgdGhpcyBmaWVsZD8</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>{{-142, 249}, {943, 549}}</string> + <string>{{0, 249}, {943, 549}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <boolean value="YES"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> diff --git a/Source/SPCopyTable.m b/Source/SPCopyTable.m index d37a0b73..4dcf6d9c 100644 --- a/Source/SPCopyTable.m +++ b/Source/SPCopyTable.m @@ -44,16 +44,16 @@ NSInteger MENU_EDIT_COPY_AS_SQL = 2003; - (void)copy:(id)sender { NSString *tmp = nil; - + if([sender tag] == MENU_EDIT_COPY_AS_SQL) { tmp = [self selectedRowsAsSqlInserts]; if ( nil != tmp ) { NSPasteboard *pb = [NSPasteboard generalPasteboard]; - + [pb declareTypes:[NSArray arrayWithObjects: NSStringPboardType, nil] owner:nil]; - + [pb setString:tmp forType:NSStringPboardType]; } } else { @@ -61,17 +61,183 @@ NSInteger MENU_EDIT_COPY_AS_SQL = 2003; if ( nil != tmp ) { NSPasteboard *pb = [NSPasteboard generalPasteboard]; - - [pb declareTypes:[NSArray arrayWithObjects: NSTabularTextPboardType, + + [pb declareTypes:[NSArray arrayWithObjects: NSTabularTextPboardType, NSStringPboardType, nil] owner:nil]; - + [pb setString:tmp forType:NSStringPboardType]; [pb setString:tmp forType:NSTabularTextPboardType]; } } } +/* + * 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, i; + + row = [self editedRow]; + column = [self editedColumn]; + BOOL isCellEditing = NO; + + // cell editing for views in SPTableContent or in SPCustomQuery + if([[self delegate] isKindOfClass:[SPCustomQuery class]] || ([[self delegate] isKindOfClass:[SPTableContent class]] && [[self delegate] valueForKeyPath:@"tablesListInstance"] && [[[self delegate] valueForKeyPath:@"tablesListInstance"] tableType] == SPTableTypeView)) + isCellEditing = YES; + + // Trap tab key + // -- for handling of blob fields look at [self control:textShouldBeginEditing:] + if ( [textView methodForSelector:command] == [textView methodForSelector:@selector(insertTab:)] ) + { + [[control window] makeFirstResponder:control]; + + if(isCellEditing) { + // Look for the next editable field + if ( column != ( [self numberOfColumns] - 1 ) ) { + i = 1; + while ([[self delegate] fieldEditStatusForRow:row andColumn:[NSArrayObjectAtIndex([self tableColumns], column+i) identifier]] != 1) { + i++; + + // If there are no columns after the latest blob or text column, save the current line. + if ( (column+i) >= [self numberOfColumns] ) + return YES; + + } + + [self editColumn:column+i row:row withEvent:nil select:YES]; + + } + + } else { + + // Save the current line if it's the last field in the table + if ( column == ( [self numberOfColumns] - 1 ) ) { + if([[self delegate] respondsToSelector:@selector(addRowToDB)]) + [[self delegate] addRowToDB]; + } 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]; + + if(isCellEditing) { + // Look for the next editable field backwards + if ( column > 0 ) { + i = 1; + while ([[self delegate] fieldEditStatusForRow:row andColumn:[NSArrayObjectAtIndex([self tableColumns], column-i) identifier]] != 1) { + i++; + + // If there are no columns before the latestone, return. + if ( column == i ) { + [[self onMainThread] makeFirstResponder]; + return TRUE; + } + } + + [self editColumn:column-i row:row withEvent:nil select:YES]; + + } + } else { + + // 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 onMainThread] makeFirstResponder]; + } 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 delegate] isKindOfClass:[SPTableContent class]] && [[self delegate] valueForKeyPath:@"tableDataInstance"]) { + NSString *fieldType = [[[[self delegate] valueForKeyPath:@"tableDataInstance"] columnWithName:[[NSArrayObjectAtIndex([self tableColumns], column) headerCell] stringValue]] objectForKey:@"typegrouping"]; + if([fieldType isEqualToString:@"enum"]) + return YES; + } + [[control window] makeFirstResponder:control]; + if([[self delegate] isKindOfClass:[SPTableContent class]] && !isCellEditing && [[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 delegate] isKindOfClass:[SPTableContent class]] && [[self delegate] valueForKeyPath:@"tableDataInstance"]) { + NSString *fieldType = [[[[self delegate] valueForKeyPath:@"tableDataInstance"] columnWithName:[[NSArrayObjectAtIndex([self tableColumns], column) headerCell] stringValue]] objectForKey:@"typegrouping"]; + if([fieldType isEqualToString:@"enum"]) + 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]] && !isCellEditing && [[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 (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 delegate] isKindOfClass:[SPTableContent class]] && [[self delegate] valueForKeyPath:@"tableDataInstance"]) { + NSString *fieldType = [[[[self delegate] valueForKeyPath:@"tableDataInstance"] columnWithName:[[NSArrayObjectAtIndex([self tableColumns], column) headerCell] stringValue]] objectForKey:@"typegrouping"]; + if([fieldType isEqualToString:@"enum"]) + return NO; + } + + if (row==0) return TRUE; //already at the beginning of the list + NSUInteger newRow = row-1; + + [[control window] makeFirstResponder:control]; + if([[self delegate] isKindOfClass:[SPTableContent class]] && !isCellEditing && [[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 (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; +} + + //allow for drag-n-drop out of the application as a copy - (NSUInteger)draggingSourceOperationMaskForLocal:(BOOL)isLocal { @@ -82,7 +248,7 @@ NSInteger MENU_EDIT_COPY_AS_SQL = 2003; * Only have the copy menu item enabled when row(s) are selected in * supported tables. */ -- (BOOL)validateMenuItem:(NSMenuItem*)anItem +- (BOOL)validateMenuItem:(NSMenuItem*)anItem { NSInteger menuItemTag = [anItem tag]; @@ -114,11 +280,11 @@ NSInteger MENU_EDIT_COPY_AS_SQL = 2003; - (NSString *)selectedRowsAsTabStringWithHeaders:(BOOL)withHeaders { if ([self numberOfSelectedRows] == 0) return nil; - + NSIndexSet *selectedRows = [self selectedRowIndexes]; NSArray *columns = [self tableColumns]; - NSUInteger numColumns = [columns count]; + NSUInteger numColumns = [columns count]; NSMutableString *result = [NSMutableString stringWithCapacity:2000]; // Add the table headers if requested to do so @@ -144,7 +310,7 @@ NSInteger MENU_EDIT_COPY_AS_SQL = 2003; NSString * nullString = [prefs objectForKey:SPNullValue]; NSStringEncoding connectionEncoding = [mySQLConnection encoding]; while ( rowIndex != NSNotFound ) - { + { for ( c = 0; c < numColumns; c++) { cellData = SPDataStorageObjectAtRowAndColumn(tableStorage, rowIndex, columnMappings[c]); @@ -189,7 +355,7 @@ NSInteger MENU_EDIT_COPY_AS_SQL = 2003; return result; } -/* +/* * Return selected rows as SQL INSERT INTO `foo` VALUES (baz) string. * If no selected table name is given `<table>` will be used instead. */ @@ -205,7 +371,7 @@ NSInteger MENU_EDIT_COPY_AS_SQL = 2003; NSMutableString *value = [NSMutableString stringWithCapacity:10]; id cellData = nil; - + NSUInteger rowCounter = 0; NSUInteger penultimateRowIndex = [selectedRows count]; NSUInteger c; @@ -226,11 +392,11 @@ NSInteger MENU_EDIT_COPY_AS_SQL = 2003; columnMappings[c] = [[[columns objectAtIndex:c] identifier] unsignedIntValue]; NSString *t = [[columnDefinitions objectAtIndex:columnMappings[c]] objectForKey:@"typegrouping"]; - + // Numeric data if ([t isEqualToString:@"bit"] || [t isEqualToString:@"integer"] || [t isEqualToString:@"float"]) columnTypes[c] = 0; - + // Blob data or long text data else if ([t isEqualToString:@"blobdata"] || [t isEqualToString:@"textdata"]) columnTypes[c] = 2; @@ -241,7 +407,7 @@ NSInteger MENU_EDIT_COPY_AS_SQL = 2003; } // Begin the SQL string - [result appendFormat:@"INSERT INTO %@ (%@)\nVALUES\n", + [result appendFormat:@"INSERT INTO %@ (%@)\nVALUES\n", [(selectedTable == nil)?@"<table>":selectedTable backtickQuotedString], [tbHeader componentsJoinedAndBacktickQuoted]]; NSUInteger rowIndex = [selectedRows firstIndex]; @@ -282,7 +448,7 @@ NSInteger MENU_EDIT_COPY_AS_SQL = 2003; continue; } else if (cellData) { - + // Check column type and insert the data accordingly switch(columnTypes[c]) { @@ -345,7 +511,7 @@ NSInteger MENU_EDIT_COPY_AS_SQL = 2003; rowIndex = [selectedRows indexGreaterThanIndex:rowIndex]; } - + // Remove the trailing ",\n" from the query string if ( [result length] > 3 ) [result deleteCharactersInRange:NSMakeRange([result length]-2, 2)]; @@ -354,7 +520,7 @@ NSInteger MENU_EDIT_COPY_AS_SQL = 2003; free(columnMappings); free(columnTypes); - + return result; } @@ -366,11 +532,11 @@ NSInteger MENU_EDIT_COPY_AS_SQL = 2003; NSArray *columns = [self tableColumns]; NSUInteger numColumns = [columns count]; NSIndexSet *selectedRows = [self selectedRowIndexes]; - + NSMutableString *result = [NSMutableString stringWithCapacity:2000]; NSUInteger c; id cellData = nil; - + // Create an array of table column mappings for fast iteration NSUInteger *columnMappings = malloc(numColumns * sizeof(NSUInteger)); for ( c = 0; c < numColumns; c++) { @@ -383,10 +549,10 @@ NSInteger MENU_EDIT_COPY_AS_SQL = 2003; Class nsDataClass = [NSData class]; NSStringEncoding connectionEncoding = [mySQLConnection encoding]; while ( rowIndex != NSNotFound ) - { + { for ( c = 0; c < numColumns; c++) { cellData = SPDataStorageObjectAtRowAndColumn(tableStorage, rowIndex, columnMappings[c]); - + // Copy the shown representation of the cell - custom NULL display strings, (not loaded), // and the string representation of any blobs or binary texts. if (cellData) { @@ -411,7 +577,7 @@ NSInteger MENU_EDIT_COPY_AS_SQL = 2003; if ([result length]) { [result deleteCharactersInRange:NSMakeRange([result length]-1, 1)]; } - + [result appendString:@"\n"]; // Retrieve the next selected row index @@ -437,7 +603,7 @@ NSInteger MENU_EDIT_COPY_AS_SQL = 2003; mySQLConnection = aMySqlConnection; tableInstance = anInstance; tableStorage = theTableStorage; - + if (columnDefinitions) [columnDefinitions release]; columnDefinitions = [[NSArray alloc] initWithArray:columnDefs]; } @@ -582,32 +748,25 @@ NSInteger MENU_EDIT_COPY_AS_SQL = 2003; - (void)keyDown:(NSEvent *)theEvent { + // RETURN or ENTER invoke editing mode for selected row // by calling tableView:shouldEditTableColumn: to validate - if([[[[self delegate] class] description] isEqualToString:@"SPTableContent"]) { + if([self numberOfSelectedRows] == 1 && ([theEvent keyCode] == 36 || [theEvent keyCode] == 76)) { + + NSUInteger i = 0; - id tableContentView = [[self delegate] valueForKeyPath:@"tableContentView"]; - if([tableContentView numberOfSelectedRows] == 1 && ([theEvent keyCode] == 36 || [theEvent keyCode] == 76)) { - if([[self delegate] tableView:tableContentView shouldEditTableColumn:[[tableContentView tableColumns] objectAtIndex:0] row:[tableContentView selectedRow]]) { + for(id item in [self tableColumns]) { + // Run in fieldEditorMode? + if(![[self delegate] tableView:self shouldEditTableColumn:item row:[self selectedRow]]) + ; + else { + // if not in fieldEditorMode select the first item [self editColumn:0 row:[self selectedRow] withEvent:nil select:YES]; - return; - } - } - } - if([[[[self delegate] class] description] isEqualToString:@"SPCustomQuery"]) { - id tableContentView = [[self delegate] valueForKeyPath:@"customQueryView"]; - if([tableContentView numberOfSelectedRows] == 1 && ([theEvent keyCode] == 36 || [theEvent keyCode] == 76)) { - - // TODO: this works until the user presses OK in the Field Editor Sheet!! - // in the future we should store the new row data temporarily and then - // after editing the last column update the db field by field (ask HansJB) - NSInteger colNum = [[tableContentView tableColumns] count]; - NSInteger i; - for(i=0; i<colNum; i++) { - [[self delegate] tableView:tableContentView shouldEditTableColumn:[[tableContentView tableColumns] objectAtIndex:i] row:[tableContentView selectedRow]]; + break; } - return; } + + return; } [super keyDown:theEvent]; diff --git a/Source/SPCustomQuery.h b/Source/SPCustomQuery.h index e2333c2d..e9c1df6b 100644 --- a/Source/SPCustomQuery.h +++ b/Source/SPCustomQuery.h @@ -49,7 +49,7 @@ @class SPCopyTable, SPQueryFavoriteManager, SPDataStorage, BWSplitView; -@interface SPCustomQuery : NSObject +@interface SPCustomQuery : NSObject { IBOutlet id tableDocumentInstance; IBOutlet id tablesListInstance; @@ -74,7 +74,7 @@ IBOutlet NSMenuItem *saveHistoryMenuItem; IBOutlet NSMenuItem *copyHistoryMenuItem; IBOutlet NSPopUpButton *encodingPopUp; - + IBOutlet SPTextView *textView; IBOutlet SPCopyTable *customQueryView; IBOutlet NSScrollView *customQueryScrollView; @@ -107,7 +107,7 @@ IBOutlet NSSearchFieldCell *helpSearchFieldCell; IBOutlet NSSegmentedControl *helpNavigator; IBOutlet NSSegmentedControl *helpTargetSelector; - + IBOutlet NSButton *queryInfoButton; IBOutlet BWSplitView *queryInfoPaneSplitView; @@ -236,6 +236,7 @@ - (void)commentOutCurrentQueryTakingSelection:(BOOL)takeSelection; - (NSString *)usedQuery; - (NSString *)argumentForRow:(NSUInteger)rowIndex ofTable:(NSString *)tableForColumn andDatabase:(NSString *)database; +- (NSInteger)fieldEditStatusForRow:(NSInteger)rowIndex andColumn:(NSInteger)columnIndex; - (NSUInteger)numberOfQueries; - (NSString *)buildHistoryString; diff --git a/Source/SPCustomQuery.m b/Source/SPCustomQuery.m index 37cdc6e8..4edaa40a 100644 --- a/Source/SPCustomQuery.m +++ b/Source/SPCustomQuery.m @@ -1586,6 +1586,64 @@ #pragma mark Field Editing /* + * Check if table cell is editable + * Returns the number of possible changes or + * -1 if no table name can be found or multiple table origins + */ +- (NSInteger)fieldEditStatusForRow:(NSInteger)rowIndex andColumn:(NSInteger)columnIndex +{ + NSDictionary *columnDefinition = nil; + + // Retrieve the column defintion + for(id c in cqColumnDefinition) { + if([[c objectForKey:@"datacolumnindex"] isEqualToNumber:columnIndex]) { + columnDefinition = [NSDictionary dictionaryWithDictionary:c]; + break; + } + } + + if(!columnDefinition) + return -2; + + // Resolve the original table name for current column if AS was used + NSString *tableForColumn = [columnDefinition objectForKey:@"org_table"]; + + // Get the database name which the field belongs to + NSString *dbForColumn = [columnDefinition objectForKey:@"db"]; + + // No table/database name found indicates that the field's column contains data from more than one table as for UNION + // or the field data are not bound to any table as in SELECT 1 or if column database is unset + if(!tableForColumn || ![tableForColumn length] || !dbForColumn || ![dbForColumn length]) + return -1; + + // if table and database name are given check if field can be identified unambiguously + NSString *fieldIDQueryStr = [self argumentForRow:rowIndex ofTable:tableForColumn andDatabase:[columnDefinition objectForKey:@"db"]]; + if(!fieldIDQueryStr) + return -1; + + [tableDocumentInstance startTaskWithDescription:NSLocalizedString(@"Checking field data for editing...", @"checking field data for editing task description")]; + + // Actual check whether field can be identified bijectively + MCPResult *tempResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@.%@ %@", + [[columnDefinition objectForKey:@"db"] backtickQuotedString], + [tableForColumn backtickQuotedString], + fieldIDQueryStr]]; + + [tableDocumentInstance endTask]; + + if ([mySQLConnection queryErrored]) + return -1; + + NSArray *tempRow = [tempResult fetchRowAsArray]; + + if(![tempRow count]) + return -1; + + return [[tempRow objectAtIndex:0] integerValue]; + +} + +/* * Collect all columns for a given 'tableForColumn' table and * return a WHERE clause for identifying the field in quesyion. */ @@ -2186,7 +2244,7 @@ [errorText setStringValue:NSLocalizedString(@"Field is not editable. Field has no or multiple table or database origin(s).",@"field is not editable due to no table/database")]; } - // if ([multipleLineEditingButton state] == NSOnState || isBlob) { + if ([multipleLineEditingButton state] == NSOnState || isBlob) { SPFieldEditorController *fieldEditor = [[SPFieldEditorController alloc] init]; @@ -2218,7 +2276,7 @@ return NO; - // } + } return isFieldEditable; } else { @@ -3388,20 +3446,73 @@ } } +/* + * If user selected a table cell which is a blob field and tried to edit it + * cancel the fieldEditor, display the field editor sheet instead for editing + * and re-enable the fieldEditor after editing. + */ +- (BOOL)control:(NSControl *)control textShouldBeginEditing:(NSText *)fieldEditor +{ + + NSString *fieldType; + NSUInteger row, column; + + row = [customQueryView editedRow]; + column = [customQueryView editedColumn]; + + NSDictionary *columnDefinition = nil; + + // Retrieve the column defintion + for(id c in cqColumnDefinition) { + if([[c objectForKey:@"datacolumnindex"] isEqualToNumber:[NSNumber numberWithInteger:column]]) { + columnDefinition = [NSDictionary dictionaryWithDictionary:c]; + break; + } + } + + if(!columnDefinition) return NO; + + BOOL isBlob = NO; + + // Check if current field is a blob + if([[columnDefinition objectForKey:@"typegrouping"] isEqualToString:@"textdata"] + || [[columnDefinition objectForKey:@"typegrouping"] isEqualToString:@"blobdata"]) + isBlob = YES; + else + isBlob = NO; + + // Check if current edited field is a blob + if (isBlob) + { + // Cancel editing + [control abortEditing]; + + // Call the field editor sheet + [self tableView:customQueryView shouldEditTableColumn:NSArrayObjectAtIndex([customQueryView tableColumns], column) row:row]; + + return NO; + + } + + return YES; + +} + /** * Abort editing of the Favorite and History search field editors if user presses ARROW UP or DOWN * to allow to navigate through the menu item list. */ -- (BOOL)control:(NSControl*)control textView:(NSTextView*)textView doCommandBySelector:(SEL)commandSelector +- (BOOL)control:(NSControl*)control textView:(NSTextView*)textView doCommandBySelector:(SEL)command { + if(control == queryHistorySearchField || control == queryFavoritesSearchField) { - if(commandSelector == @selector(moveDown:) || commandSelector == @selector(moveUp:)) { + if(command == @selector(moveDown:) || command == @selector(moveUp:)) { [queryHistorySearchField abortEditing]; [queryFavoritesSearchField abortEditing]; // Send moveDown/Up to the popup menu NSEvent *arrowEvent; - if(commandSelector == @selector(moveDown:)) + if(command == @selector(moveDown:)) arrowEvent = [NSEvent keyEventWithType:NSKeyDown location:NSMakePoint(0,0) modifierFlags:0 timestamp:0 windowNumber:[[tableDocumentInstance parentWindow] windowNumber] context:[NSGraphicsContext currentContext] characters:nil charactersIgnoringModifiers:nil isARepeat:NO keyCode:0x7D]; else arrowEvent = [NSEvent keyEventWithType:NSKeyDown location:NSMakePoint(0,0) modifierFlags:0 timestamp:0 windowNumber:[[tableDocumentInstance parentWindow] windowNumber] context:[NSGraphicsContext currentContext] characters:nil charactersIgnoringModifiers:nil isARepeat:NO keyCode:0x7E]; @@ -3410,6 +3521,29 @@ } } + + else { + + // Check firstly if SPCopyTable can handle command + if([customQueryView control:control textView:textView doCommandBySelector:(SEL)command]) + return YES; + + // Trap the escape key + if ( [[control window] methodForSelector:command] == [[control window] methodForSelector:@selector(cancelOperation:)] ) + { + + // Abort editing + [control abortEditing]; + + // Preserve the focus + [customQueryView makeFirstResponder]; + + return TRUE; + } + + + } + return NO; } // - (void)menu:(NSMenu *)menu willHighlightItem:(NSMenuItem *)item diff --git a/Source/SPTableContent.m b/Source/SPTableContent.m index 4017f42a..2a48d471 100644 --- a/Source/SPTableContent.m +++ b/Source/SPTableContent.m @@ -2681,6 +2681,7 @@ return [[tempRow objectAtIndex:0] integerValue]; } + /* * Close an open sheet. */ @@ -3764,155 +3765,16 @@ - (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)command { - NSString *fieldType; - NSUInteger row, column, i; - - row = [tableContentView editedRow]; - column = [tableContentView editedColumn]; - - // Trap tab key - // -- for handling of blob fields look at [self control:textShouldBeginEditing:] - if ( [textView methodForSelector:command] == [textView methodForSelector:@selector(insertTab:)] ) - { - [[control window] makeFirstResponder:control]; - - if([tablesListInstance tableType] == SPTableTypeView) { - // Look for the next editable field - if ( column != ( [tableContentView numberOfColumns] - 1 ) ) { - i = 1; - while ([self fieldEditStatusForRow:row andColumn:[NSArrayObjectAtIndex([tableContentView tableColumns], column+i) identifier]] != 1) { - i++; - - // If there are no columns after the latest blob or text column, save the current line. - if ( (column+i) >= [tableContentView numberOfColumns] ) { - return TRUE; - } - } - - [tableContentView editColumn:column+i row:row withEvent:nil select:YES]; - - } - } else { - - // Save the current line if it's the last field in the table - if ( column == ( [tableContentView numberOfColumns] - 1 ) ) { - [self addRowToDB]; - return YES; - } else { - // Select the next field for editing - [tableContentView editColumn:column+1 row:row withEvent:nil select:YES]; - return YES; - } - - } + // Check firstly if SPCopyTable can handle command + if([tableContentView control:control textView:textView doCommandBySelector:(SEL)command]) return YES; - } - - // Trap shift-tab key - if ( [textView methodForSelector:command] == [textView methodForSelector:@selector(insertBacktab:)] ) - { - [[control window] makeFirstResponder:control]; - - if([tablesListInstance tableType] == SPTableTypeView) { - // Look for the next editable field backwards - if ( column > 0 ) { - i = 1; - while ([self fieldEditStatusForRow:row andColumn:[NSArrayObjectAtIndex([tableContentView tableColumns], column-i) identifier]] != 1) { - i++; - - // If there are no columns before the latestone, return. - if ( column == i ) { - return TRUE; - } - } - - [tableContentView editColumn:column-i row:row withEvent:nil select:YES]; - - } - } else { - - // Save the current line if it's the last field in the table - if ( column < 1 ) { - [self addRowToDB]; - return YES; - } else { - // Select the previous field for editing - [tableContentView editColumn:column-1 row:row withEvent:nil select:YES]; - return 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 - NSString *fieldType = [[tableDataInstance columnWithName:[[NSArrayObjectAtIndex([tableContentView tableColumns], column) headerCell] stringValue]] objectForKey:@"typegrouping"]; - if([fieldType isEqualToString:@"enum"]) - return YES; - - [[control window] makeFirstResponder:control]; - if([tablesListInstance tableType] != SPTableTypeView) - [self addRowToDB]; - return TRUE; - - } - - // 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 - NSString *fieldType = [[tableDataInstance columnWithName:[[NSArrayObjectAtIndex([tableContentView tableColumns], column) headerCell] stringValue]] objectForKey:@"typegrouping"]; - if([fieldType isEqualToString:@"enum"]) - return NO; - - NSUInteger newRow = row+1; - if (newRow>=tableRowsCount) return TRUE; //check if we're already at the end of the list - - [[control window] makeFirstResponder:control]; - if([tablesListInstance tableType] != SPTableTypeView) - [self addRowToDB]; - - if (newRow>=tableRowsCount) return TRUE; //check again. addRowToDB could reload the table and change the number of rows - if (column>=[tableValues columnCount]) return TRUE; //the column count could change too - - [tableContentView selectRowIndexes:[NSIndexSet indexSetWithIndex:newRow] byExtendingSelection:NO]; - [tableContentView editColumn:column row:newRow withEvent:nil select:YES]; - return TRUE; - } - - // 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 - NSString *fieldType = [[tableDataInstance columnWithName:[[NSArrayObjectAtIndex([tableContentView tableColumns], column) headerCell] stringValue]] objectForKey:@"typegrouping"]; - if([fieldType isEqualToString:@"enum"]) - return NO; - - if (row==0) return TRUE; //already at the beginning of the list - NSUInteger newRow = row-1; - - [[control window] makeFirstResponder:control]; - if([tablesListInstance tableType] != SPTableTypeView) - [self addRowToDB]; - - if (newRow>=tableRowsCount) return TRUE; // addRowToDB could reload the table and change the number of rows - if (column>=[tableValues columnCount]) return TRUE; //the column count could change too - - [tableContentView selectRowIndexes:[NSIndexSet indexSetWithIndex:newRow] byExtendingSelection:NO]; - [tableContentView editColumn:column row:newRow withEvent:nil select:YES]; - return TRUE; - } // Trap the escape key - else if ( [[control window] methodForSelector:command] == [[control window] methodForSelector:@selector(_cancelKey:)] || - [textView methodForSelector:command] == [textView methodForSelector:@selector(complete:)] ) + if ( [[control window] methodForSelector:command] == [[control window] methodForSelector:@selector(cancelOperation:)] ) { + NSUInteger row = [tableContentView editedRow]; + // Abort editing [control abortEditing]; if ( isEditingRow && !isEditingNewRow ) { @@ -3933,10 +3795,9 @@ return TRUE; } - else - { - return FALSE; - } + + return FALSE; + } /** |