// // $Id$ // // SPDataCellFormatter.m // sequel-pro // // Created by Rowan Beentje on 11/02/2009. // Copyright 2009 Arboreal. All rights reserved. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // More info at #import "SPDataCellFormatter.h" #import "SPTooltip.h" @implementation SPDataCellFormatter @synthesize textLimit; @synthesize fieldType; - (NSString *)stringForObjectValue:(id)anObject { // Truncate the string for speed purposes if it's very long - improves table scrolling speed. if ([anObject isKindOfClass:[NSString class]] && [(NSString *)anObject length] > 150) { return ([NSString stringWithFormat:@"%@...", [anObject substringToIndex:147]]); } return anObject; } // Always provide the full string when editing - (NSString *)editingStringForObjectValue:(id)anObject { return anObject; } - (BOOL) getObjectValue:(id*) object forString:(NSString*) string errorDescription:(NSString**) error { *object = string; return YES; } /** * When producing an attributed string, take the opportunity to convert to a single * line for display, displaying placeholders for CR and LF characters. */ - (NSAttributedString *)attributedStringForObjectValue:(id)anObject withDefaultAttributes:(NSDictionary *)attributes { // Start with a base string which has been shortened for fast display NSString *baseString = [self stringForObjectValue:anObject]; // Look for any linebreaks within the string NSRange linebreakRange = [baseString rangeOfCharacterFromSet:[NSCharacterSet newlineCharacterSet] options:NSLiteralSearch]; // If there's no linebreaks, return a non-mutable string if (linebreakRange.location == NSNotFound) { return [[[NSAttributedString alloc] initWithString:baseString attributes:attributes] autorelease]; } NSMutableAttributedString *mutableString; NSUInteger i, j, stringLength = [baseString length]; unichar c; // Otherwise, prepare a mutable attributed string to alter, and walk along the string. mutableString = [[[NSMutableAttributedString alloc] initWithString:baseString attributes:attributes] autorelease]; for (i = linebreakRange.location, j = i; i < stringLength; i++, j++) { c = [baseString characterAtIndex:i]; switch (c) { case '\n': [mutableString replaceCharactersInRange:NSMakeRange(j, 1) withString:@"¶"]; [mutableString addAttribute:NSForegroundColorAttributeName value:[NSColor lightGrayColor] range:NSMakeRange(j, 1)]; break; case '\r': case 0x0085: case 0x000b: case 0x000c: [mutableString replaceCharactersInRange:NSMakeRange(j, 1) withString:@"⁋"]; [mutableString addAttribute:NSForegroundColorAttributeName value:[NSColor lightGrayColor] range:NSMakeRange(j, 1)]; if (c == '\r' && i + 1 < stringLength && [baseString characterAtIndex:i+1] == '\n') { [mutableString deleteCharactersInRange:NSMakeRange(j+1, 1)]; i++; } break; } } return mutableString; } - (BOOL)isPartialStringValid:(NSString *)partialString newEditingString:(NSString **)newString errorDescription:(NSString **)error { // No limit set or partialString is NULL value string allow editing if (textLimit == 0 || [partialString isEqualToString:[[NSUserDefaults standardUserDefaults] objectForKey:SPNullValue]]) return YES; // A single character over the length of the string - likely typed. Prevent the change. if ((NSInteger)[partialString length] == textLimit + 1) { [SPTooltip showWithObject:[NSString stringWithFormat:NSLocalizedString(@"Maximum text length is set to %ld.", @"Maximum text length is set to %ld."), (long)textLimit]]; return NO; } // If the string is considerably longer than the limit, likely pasted. Accept but truncate. if ((NSInteger)[partialString length] > textLimit) { [SPTooltip showWithObject:[NSString stringWithFormat:NSLocalizedString(@"Maximum text length is set to %ld. Inserted text was truncated.", @"Maximum text length is set to %ld. Inserted text was truncated."), (long)textLimit]]; *newString = [NSString stringWithString:[partialString substringToIndex:textLimit]]; return NO; } // Check for BIT fields whether 1 or 0 are typed if(fieldType && [fieldType length] && [[fieldType uppercaseString] isEqualToString:@"BIT"]) { if([partialString rangeOfCharacterFromSet:[[NSCharacterSet characterSetWithCharactersInString:@"01"] invertedSet]].location != NSNotFound) { [SPTooltip showWithObject:NSLocalizedString(@"For BIT fields only “1” or “0” are allowed.", @"For BIT fields only “1” or “0” are allowed.")]; return NO; } return YES; } return YES; } - (void)dealloc { if (fieldType) [fieldType release], fieldType = nil; [super dealloc]; } @end