From 85290111df9004529db698745acc98a21a8d1996 Mon Sep 17 00:00:00 2001 From: Bibiko Date: Thu, 26 Aug 2010 18:53:33 +0000 Subject: =?UTF-8?q?=E2=80=A2=20removed=20onMainThread=20for=20[Content/Cus?= =?UTF-8?q?tomTable=20makeFirstResponder]=20to=20avoid=20the=20trampoline?= =?UTF-8?q?=20exceptions=20=E2=80=A2=20unified=20error=20message=20while?= =?UTF-8?q?=20cell=20editing=20=E2=80=A2=20in=20Custom=20Query=20table=20c?= =?UTF-8?q?ell=20editing=20errors=20are=20displayed=20as=20tooltips=20and?= =?UTF-8?q?=20added=20these=20message=20if=20edit=20event=20comes=20from?= =?UTF-8?q?=20the=20keyboard=20=E2=80=A2=20fixed:=20check=20edit=20status?= =?UTF-8?q?=20in=20Content=20Tables=20only=20for=20views=20to=20avoid=20un?= =?UTF-8?q?necessary=20queries=20=E2=80=A2=20used=20[SPCustomQuery=20field?= =?UTF-8?q?EditStatusForRow:andColumn:]=20consequently=20to=20simplify=20c?= =?UTF-8?q?ode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Source/SPCopyTable.m | 4 +- Source/SPCustomQuery.h | 5 ++ Source/SPCustomQuery.m | 137 +++++++++++++++++++++++++++++------------------- Source/SPTableContent.h | 4 ++ Source/SPTableContent.m | 25 +++++---- 5 files changed, 111 insertions(+), 64 deletions(-) diff --git a/Source/SPCopyTable.m b/Source/SPCopyTable.m index db8ce49d..962557f1 100644 --- a/Source/SPCopyTable.m +++ b/Source/SPCopyTable.m @@ -120,7 +120,7 @@ NSInteger MENU_EDIT_COPY_AS_SQL = 2003; if ( [self numberOfColumns] - 1 == column) { if([[self delegate] respondsToSelector:@selector(addRowToDB)]) [[self delegate] addRowToDB]; - [[self onMainThread] makeFirstResponder]; + [self makeFirstResponder]; } else { // Select the next field for editing [self editColumn:column+1 row:row withEvent:nil select:YES]; @@ -138,7 +138,7 @@ NSInteger MENU_EDIT_COPY_AS_SQL = 2003; if ( column < 1 ) { if([[self delegate] respondsToSelector:@selector(addRowToDB)]) [[self delegate] addRowToDB]; - [[self onMainThread] makeFirstResponder]; + [self makeFirstResponder]; } else { // Select the previous field for editing [self editColumn:column-1 row:row withEvent:nil select:YES]; diff --git a/Source/SPCustomQuery.h b/Source/SPCustomQuery.h index e9c1df6b..30e64ef5 100644 --- a/Source/SPCustomQuery.h +++ b/Source/SPCustomQuery.h @@ -160,6 +160,11 @@ NSTimer *queryLoadTimer; NSUInteger queryLoadInterfaceUpdateInterval, queryLoadTimerTicksSinceLastUpdate, queryLoadLastRowCount; NSInteger runAllContinueStopSheetReturnCode; + + NSString *kCellEditorErrorNoMatch; + NSString *kCellEditorErrorNoMultiTabDb; + NSString *kCellEditorErrorTooManyMatches; + } // IBAction methods diff --git a/Source/SPCustomQuery.m b/Source/SPCustomQuery.m index adb806ad..f8729074 100644 --- a/Source/SPCustomQuery.m +++ b/Source/SPCustomQuery.m @@ -1808,9 +1808,6 @@ { if (aTableView == customQueryView) { - // Field editing - if (fieldIDQueryString == nil) return; - NSDictionary *columnDefinition; // Retrieve the column defintion @@ -1837,9 +1834,8 @@ fieldIDQueryString = [self argumentForRow:rowIndex ofTable:tableForColumn andDatabase:[columnDefinition objectForKey:@"db"]]; // Check if the IDstring identifies the current field bijectively - NSInteger numberOfPossibleUpdateRows = [[[[mySQLConnection queryString:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@.%@ %@", [[columnDefinition objectForKey:@"db"] backtickQuotedString], [tableForColumn backtickQuotedString], fieldIDQueryString]] fetchRowAsArray] objectAtIndex:0] integerValue]; + NSInteger numberOfPossibleUpdateRows = [self fieldEditStatusForRow:rowIndex andColumn:[aTableColumn identifier]]; if(numberOfPossibleUpdateRows == 1) { - // [[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryWillBePerformed" object:tableDocumentInstance]; NSString *newObject = nil; if ( [anObject isKindOfClass:[NSCalendarDate class]] ) { @@ -1865,10 +1861,8 @@ [mySQLConnection queryString: [NSString stringWithFormat:@"UPDATE %@.%@ SET %@.%@.%@ = %@ %@ LIMIT 1", - [[columnDefinition objectForKey:@"db"] backtickQuotedString], [tableForColumn backtickQuotedString], - [[columnDefinition objectForKey:@"db"] backtickQuotedString], [tableForColumn backtickQuotedString], [columnName backtickQuotedString], newObject, fieldIDQueryString]]; - - // [[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance]; + [[columnDefinition objectForKey:@"db"] backtickQuotedString], [[columnDefinition objectForKey:@"org_table"] backtickQuotedString], + [[columnDefinition objectForKey:@"db"] backtickQuotedString], [[columnDefinition objectForKey:@"org_table"] backtickQuotedString], [columnName backtickQuotedString], newObject, fieldIDQueryString]]; // Check for errors while UPDATE if ([mySQLConnection queryErrored]) { @@ -1878,7 +1872,6 @@ return; } - // This shouldn't happen – for safety reasons if ( ![mySQLConnection affectedRows] ) { if ( [prefs boolForKey:SPShowNoAffectedRowsError] ) { @@ -1894,17 +1887,15 @@ if ([prefs boolForKey:SPReloadAfterEditingRow]) { reloadingExistingResult = YES; [self storeCurrentResultViewForRestoration]; - [self performQueries:[NSArray arrayWithObject:lastExecutedQuery] withCallback:NULL]; - } else { // otherwise, just update the data in the data storage SPDataStorageReplaceObjectAtRowAndColumn(resultData, rowIndex, [[aTableColumn identifier] intValue], anObject); } } else { SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [tableDocumentInstance parentWindow], self, nil, nil, - [NSString stringWithFormat:NSLocalizedString(@"Updating field content failed. Couldn't identify field origin unambiguously (%ld match%@). It's very likely that while editing this field the table `%@` was changed by an other user.", @"message of panel when error while updating field to db after enabling it"), - (long)numberOfPossibleUpdateRows, (numberOfPossibleUpdateRows>1)?@"es":@"", tableForColumn]); + [NSString stringWithFormat:NSLocalizedString(@"Updating field content failed. Couldn't identify field origin unambiguously (%ld match%@). It's very likely that while editing this field of table `%@` was changed.", @"message of panel when error while updating field to db after enabling it"), + (long)numberOfPossibleUpdateRows, (numberOfPossibleUpdateRows>1)?@"es":@"", [columnDefinition objectForKey:@"org_table"]]); } @@ -2189,12 +2180,9 @@ // Check if the field can identified bijectively if ( aTableView == customQueryView ) { - NSDictionary *columnDefinition; - BOOL noTableName = NO; - BOOL isFieldEditable; - BOOL isBlob; - NSInteger numberOfPossibleUpdateRows = -1; + BOOL isFieldEditable = NO; + BOOL isBlob = NO; // Retrieve the column defintion for(id c in cqColumnDefinition) { @@ -2211,39 +2199,52 @@ else isBlob = NO; - // 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 length]) - noTableName = YES; - - if(!noTableName) { - // if table and database name are given check if field can be identified unambiguously - fieldIDQueryString = [self argumentForRow:rowIndex ofTable:tableForColumn andDatabase:[columnDefinition objectForKey:@"db"]]; - - // Actual check whether field can be identified bijectively - numberOfPossibleUpdateRows = [[[[mySQLConnection queryString:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@.%@ %@", [[columnDefinition objectForKey:@"db"] backtickQuotedString], [tableForColumn backtickQuotedString], fieldIDQueryString]] fetchRowAsArray] objectAtIndex:0] integerValue]; + // Check if the clicked table field is editable + NSInteger numberOfPossibleUpdateRows = [self fieldEditStatusForRow:rowIndex andColumn:[aTableColumn identifier]]; + isFieldEditable = (numberOfPossibleUpdateRows == 1) ? YES : NO; + NSPoint pos = [NSEvent mouseLocation]; + pos.y -= 20; + switch(numberOfPossibleUpdateRows) { + case -1: + isFieldEditable = NO; + fieldIDQueryString = nil; + [SPTooltip showWithObject:kCellEditorErrorNoMultiTabDb + atLocation:pos + ofType:@"text"]; + isFieldEditable = NO; + // Allow to display blobs even it's not editable + if(!isBlob && [multipleLineEditingButton state] == NSOffState) + return NO; + break; - isFieldEditable = (numberOfPossibleUpdateRows == 1) ? YES : NO; + case 0: + [SPTooltip showWithObject:[NSString stringWithFormat:kCellEditorErrorNoMatch, [columnDefinition objectForKey:@"org_table"]] + atLocation:pos + ofType:@"text"]; + isFieldEditable = NO; + // Allow to display blobs even it's not editable + if(!isBlob && [multipleLineEditingButton state] == NSOffState) + return NO; + break; - if(!isFieldEditable) - if(numberOfPossibleUpdateRows == 0) - [errorText setStringValue:[NSString stringWithFormat:NSLocalizedString(@"Field is not editable. No matching record found. Try to add the primary key field or more fields in your SELECT statement for table '%@' to identify field origin unambiguously.", @"Custom Query result editing error - could not identify original row"), tableForColumn]]; - else - [errorText setStringValue:[NSString stringWithFormat:NSLocalizedString(@"Field is not editable. Couldn't identify field origin unambiguously (%ld match%@).", @"Custom Query result editing error - could not match row being edited uniquely"), (long)numberOfPossibleUpdateRows, (numberOfPossibleUpdateRows>1)?NSLocalizedString(@"es", @"Plural suffix for row count, eg 4 match*es*"):@""]]; + case 1: + isFieldEditable = YES; + if(!isBlob && [multipleLineEditingButton state] == NSOffState) + return YES; + break; - } else { - // no table/databse name are given + default: + [SPTooltip showWithObject:[NSString stringWithFormat:kCellEditorErrorTooManyMatches, (long)numberOfPossibleUpdateRows, (numberOfPossibleUpdateRows>1)?NSLocalizedString(@"es", @"Plural suffix for row count, eg 4 match*es*"):@""] + atLocation:pos + ofType:@"text"]; isFieldEditable = NO; - fieldIDQueryString = nil; - [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")]; + // Allow to display blobs even it's not editable + if(!isBlob && [multipleLineEditingButton state] == NSOffState) + return NO; + } + if ([multipleLineEditingButton state] == NSOnState || isBlob) { SPFieldEditorController *fieldEditor = [[SPFieldEditorController alloc] init]; @@ -3414,6 +3415,10 @@ prefs = [NSUserDefaults standardUserDefaults]; + kCellEditorErrorNoMatch = NSLocalizedString(@"Field is not editable. No matching record found. Reload data, check encoding, or try to add a primary key field or more fields in your SELECT statement for table '%@' to identify field origin unambiguously.", @"Custom Query result editing error - could not identify original row"); + kCellEditorErrorNoMultiTabDb = NSLocalizedString(@"Field is not editable. Field has no or multiple table or database origin(s).",@"field is not editable due to no table/database"); + kCellEditorErrorTooManyMatches = NSLocalizedString(@"Field is not editable. Couldn't identify field origin unambiguously (%ld match%@).", @"Custom Query result editing error - could not match row being edited uniquely"); + } return self; @@ -3460,17 +3465,11 @@ { NSUInteger row, column; + NSDictionary *columnDefinition = nil; row = [customQueryView editedRow]; column = [customQueryView editedColumn]; - if([self fieldEditStatusForRow:row andColumn:[NSArrayObjectAtIndex([customQueryView tableColumns], column) identifier]] != 1) - return NO; - - NSString *fieldType; - - NSDictionary *columnDefinition = nil; - // Retrieve the column defintion for(id c in cqColumnDefinition) { if([[c objectForKey:@"datacolumnindex"] isEqualToNumber:[NSNumber numberWithInteger:column]]) { @@ -3481,6 +3480,35 @@ if(!columnDefinition) return NO; + NSInteger numberOfPossibleUpdateRows = [self fieldEditStatusForRow:row andColumn:[NSArrayObjectAtIndex([customQueryView tableColumns], column) identifier]]; + NSPoint pos = [[tableDocumentInstance parentWindow] convertBaseToScreen:[customQueryView convertPoint:[customQueryView frameOfCellAtColumn:column row:row].origin toView:nil]]; + pos.y -= 20; + switch(numberOfPossibleUpdateRows) { + case -1: + [SPTooltip showWithObject:kCellEditorErrorNoMultiTabDb + atLocation:pos + ofType:@"text"]; + return NO; + break; + case 0: + [SPTooltip showWithObject:[NSString stringWithFormat:kCellEditorErrorNoMatch, [columnDefinition objectForKey:@"org_table"]] + atLocation:pos + ofType:@"text"]; + return NO; + break; + + case 1: + break; + + default: + [SPTooltip showWithObject:[NSString stringWithFormat:kCellEditorErrorTooManyMatches, (long)numberOfPossibleUpdateRows, (numberOfPossibleUpdateRows>1)?NSLocalizedString(@"es", @"Plural suffix for row count, eg 4 match*es*"):@""] + atLocation:pos + ofType:@"text"]; + return NO; + } + + NSString *fieldType; + BOOL isBlob = NO; // Check if current field is a blob @@ -3506,6 +3534,9 @@ } + // Set editing color to black for NULL values while editing + [fieldEditor setTextColor:[NSColor blackColor]]; + return YES; } diff --git a/Source/SPTableContent.h b/Source/SPTableContent.h index b1748c2d..506c01d0 100644 --- a/Source/SPTableContent.h +++ b/Source/SPTableContent.h @@ -107,6 +107,10 @@ NSString *fieldIDQueryString; BOOL isFirstChangeInView; + NSString *kCellEditorErrorNoMatch; + NSString *kCellEditorErrorNoMultiTabDb; + NSString *kCellEditorErrorTooManyMatches; + } // Table loading methods and information diff --git a/Source/SPTableContent.m b/Source/SPTableContent.m index 14150607..71dd35f9 100644 --- a/Source/SPTableContent.m +++ b/Source/SPTableContent.m @@ -125,6 +125,9 @@ [numberOfDefaultFilters setObject:[NSNumber numberWithInteger:[[contentFilters objectForKey:@"string"] count]] forKey:@"string"]; } + kCellEditorErrorNoMatch = NSLocalizedString(@"Field is not editable. No matching record found.\nReload table, check the encoding, or try to add\na primary key field or more fields\nin the view declaration of '%@' to identify\nfield origin unambiguously.", @"Table Content result editing error - could not identify original row"); + kCellEditorErrorNoMultiTabDb = NSLocalizedString(@"Field is not editable. Field has no or multiple table or database origin(s).",@"field is not editable due to no table/database"); + kCellEditorErrorTooManyMatches = NSLocalizedString(@"Field is not editable. Couldn't identify field origin unambiguously (%ld match%@).", @"Table Content result editing error - could not match row being edited uniquely"); } @@ -3465,7 +3468,7 @@ pos.y -= 20; switch(numberOfPossibleUpdateRows) { case -1: - [SPTooltip showWithObject:NSLocalizedString(@"Field is not editable. Field has no or multiple table or database origin(s).",@"field is not editable due to no table/database") + [SPTooltip showWithObject:kCellEditorErrorNoMultiTabDb atLocation:pos ofType:@"text"]; isFieldEditable = NO; @@ -3475,7 +3478,7 @@ break; case 0: - [SPTooltip showWithObject:[NSString stringWithFormat:NSLocalizedString(@"Field is not editable. No matching record found.\nReload table or try to add a primary key field or more fields\nin the view declaration of '%@' to identify\nfield origin unambiguously.", @"Table Content result editing error - could not identify original row"), selectedTable] + [SPTooltip showWithObject:[NSString stringWithFormat:kCellEditorErrorNoMatch, selectedTable] atLocation:pos ofType:@"text"]; @@ -3492,7 +3495,7 @@ break; default: - [SPTooltip showWithObject:[NSString stringWithFormat:NSLocalizedString(@"Field is not editable. Couldn't identify field origin unambiguously (%ld match%@).", @"Table Content result editing error - could not match row being edited uniquely"), (long)numberOfPossibleUpdateRows, (numberOfPossibleUpdateRows>1)?NSLocalizedString(@"es", @"Plural suffix for row count, eg 4 match*es*"):@""] + [SPTooltip showWithObject:[NSString stringWithFormat:kCellEditorErrorTooManyMatches, (long)numberOfPossibleUpdateRows, (numberOfPossibleUpdateRows>1)?NSLocalizedString(@"es", @"Plural suffix for row count, eg 4 match*es*"):@""] atLocation:pos ofType:@"text"]; @@ -3552,7 +3555,7 @@ if (editData) [editData release]; - [[tableContentView onMainThread] makeFirstResponder]; + [tableContentView makeFirstResponder]; return NO; } @@ -3720,18 +3723,22 @@ row = [tableContentView editedRow]; column = [tableContentView editedColumn]; - NSInteger numberOfPossibleUpdateRows = [self fieldEditStatusForRow:row andColumn:[NSArrayObjectAtIndex([tableContentView tableColumns], column) identifier]]; - if([tableContentView isCellEditingMode] && numberOfPossibleUpdateRows != 1) { + + // If cell editing mode and editing request comes + // from the keyboard show an error tooltip + // or bypass if numberOfPossibleUpdateRows == 1 + if([tableContentView isCellEditingMode]) { + NSInteger numberOfPossibleUpdateRows = [self fieldEditStatusForRow:row andColumn:[NSArrayObjectAtIndex([tableContentView tableColumns], column) identifier]]; NSPoint pos = [[tableDocumentInstance parentWindow] convertBaseToScreen:[tableContentView convertPoint:[tableContentView frameOfCellAtColumn:column row:row].origin toView:nil]]; pos.y -= 20; switch(numberOfPossibleUpdateRows) { case -1: - [SPTooltip showWithObject:NSLocalizedString(@"Field is not editable. Field has no or multiple table or database origin(s).",@"field is not editable due to no table/database") + [SPTooltip showWithObject:kCellEditorErrorNoMultiTabDb atLocation:pos ofType:@"text"]; break; case 0: - [SPTooltip showWithObject:[NSString stringWithFormat:NSLocalizedString(@"Field is not editable. No matching record found.\nReload table or try to add a primary key field or more fields\nin the view declaration of '%@' to identify\nfield origin unambiguously.", @"Table Content result editing error - could not identify original row"), selectedTable] + [SPTooltip showWithObject:[NSString stringWithFormat:kCellEditorErrorNoMatch, selectedTable] atLocation:pos ofType:@"text"]; break; @@ -3740,7 +3747,7 @@ break; default: - [SPTooltip showWithObject:[NSString stringWithFormat:NSLocalizedString(@"Field is not editable. Couldn't identify field origin unambiguously (%ld match%@).", @"Table Content result editing error - could not match row being edited uniquely"), (long)numberOfPossibleUpdateRows, (numberOfPossibleUpdateRows>1)?NSLocalizedString(@"es", @"Plural suffix for row count, eg 4 match*es*"):@""] + [SPTooltip showWithObject:[NSString stringWithFormat:kCellEditorErrorTooManyMatches, (long)numberOfPossibleUpdateRows, (numberOfPossibleUpdateRows>1)?NSLocalizedString(@"es", @"Plural suffix for row count, eg 4 match*es*"):@""] atLocation:pos ofType:@"text"]; } -- cgit v1.2.3