aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBibiko <bibiko@eva.mpg.de>2010-08-24 14:26:00 +0000
committerBibiko <bibiko@eva.mpg.de>2010-08-24 14:26:00 +0000
commitd90aac6dfab328485bad6ec450388d90684a0ee6 (patch)
treed09c5bbe1cb309018a3298e805eb79aec3e1c053
parent015321ca8747bbd2ee6f8a153e779835f75f9efe (diff)
downloadsequelpro-d90aac6dfab328485bad6ec450388d90684a0ee6.tar.gz
sequelpro-d90aac6dfab328485bad6ec450388d90684a0ee6.tar.bz2
sequelpro-d90aac6dfab328485bad6ec450388d90684a0ee6.zip
• outsourced control:textView:doCommandBySelector: stuff to SPCopyTable since we need that for Content and Custom Query table; only class specific stuff like ESC trapping will handled in the actual class
• enabled in cell editing for Custom Query tables - also added spreadsheet button to Custom Query status bar • fixed ESC trapping: F5 can be used for completion • simplified [SPCopyTable keyDown:] for trapping ENTER/RETURN key • some code cosmetics
-rw-r--r--Interfaces/English.lproj/DBView.xib6
-rw-r--r--Source/SPCopyTable.m247
-rw-r--r--Source/SPCustomQuery.h7
-rw-r--r--Source/SPCustomQuery.m144
-rw-r--r--Source/SPTableContent.m157
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;
+
}
/**