// // TableColumnDateFormatter.m // // Created by John Chang on 2007-06-07. // This code is Creative Commons Public Domain. You may use it for any purpose whatsoever. // http://creativecommons.org/licenses/publicdomain/ // #import "TableColumnDateFormatter.h" @implementation TableColumnDateFormatter - (void) _setupDateFormatArrays { /* 3/21/01 3/21/01, 12:34 PM Mar 21, 2001, 12:34 PM March 21, 2001, 12:34 PM */ _dateFormats = [[NSMutableArray alloc] init]; [_dateFormatter setDateStyle:NSDateFormatterShortStyle]; [(NSMutableArray *)_dateFormats addObject:[_dateFormatter dateFormat]]; NSDateFormatterStyle dateStyle; for (dateStyle = NSDateFormatterShortStyle; dateStyle <= NSDateFormatterLongStyle; dateStyle++) { [_dateFormatter setDateStyle:dateStyle]; NSString * format = [NSString stringWithFormat:@"%@, %@", [_dateFormatter dateFormat], [_timeFormatter dateFormat]]; [(NSMutableArray *)_dateFormats addObject:format]; } /* Yesterday Yesterday, 12:34 PM */ _relativeDateFormats = [[NSMutableArray alloc] init]; [(NSMutableArray *)_relativeDateFormats addObject:@"'%@'"]; NSString * format = [NSString stringWithFormat:@"'%%@', %@", [_timeFormatter dateFormat]]; [(NSMutableArray *)_relativeDateFormats addObject:format]; } - (id)init { if ((self = [super init])) { _dateFormatter = [[NSDateFormatter alloc] init]; [_dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4]; [_dateFormatter setTimeStyle:NSDateFormatterNoStyle]; _timeFormatter = [[NSDateFormatter alloc] init]; [_timeFormatter setFormatterBehavior:NSDateFormatterBehavior10_4]; [_timeFormatter setDateStyle:NSDateFormatterNoStyle]; [_timeFormatter setTimeStyle:NSDateFormatterShortStyle]; [self _setupDateFormatArrays]; } return self; } - (void) dealloc { [_dateFormatter release]; [_timeFormatter release]; [_dateFormats release]; [_relativeDateFormats release]; [_tableColumn release]; [super dealloc]; } - (void) setTableColumn:(NSTableColumn *)tableColumn { [[tableColumn dataCell] setFormatter:nil]; [_tableColumn release]; _tableColumn = [tableColumn retain]; [[tableColumn dataCell] setFormatter:self]; [[tableColumn dataCell] setLineBreakMode:NSLineBreakByTruncatingMiddle]; } - (NSString *)stringForObjectValue:(id)anObject { if (![anObject isKindOfClass:[NSDate class]]) return nil; return [_dateFormatter stringForObjectValue:anObject]; } - (NSString *) _relativeDateStringForDate:(NSDate *)date { NSCalendarDate * nowCalendarDate = [NSCalendarDate calendarDate]; NSCalendarDate * todayCalendarDate = [NSCalendarDate dateWithYear:[nowCalendarDate yearOfCommonEra] month:[nowCalendarDate monthOfYear] day:[nowCalendarDate dayOfMonth] hour:0 minute:0 second:0 timeZone:nil]; if ([date compare:todayCalendarDate] >= NSOrderedSame) { // "Today" NSArray * designations = [[NSUserDefaults standardUserDefaults] objectForKey:NSThisDayDesignations]; if (designations && [designations count] > 0) return [[designations objectAtIndex:0] capitalizedString]; } NSDate * yesterdayCalendarDate = [todayCalendarDate addTimeInterval:-60*60*24]; if ([date compare:yesterdayCalendarDate] >= NSOrderedSame) { // "Yesterday" NSArray * designations = [[NSUserDefaults standardUserDefaults] objectForKey:NSPriorDayDesignations]; if (designations && [designations count] > 0) return [[designations objectAtIndex:0] capitalizedString]; } return nil; } - (NSString *) _stringByFittingDate:(NSDate *)date maxWidth:(float)maxWidth attributes:(NSDictionary *)attributes { NSString * relativeDateString = [self _relativeDateStringForDate:date]; NSArray * dateFormatArray = (relativeDateString ? _relativeDateFormats : _dateFormats); // Try growing the date and time until it doesn't fit anymore int i, count = [dateFormatArray count]; for (i=0; i maxWidth) { if (i > 0) { NSString * dateFormat = [dateFormatArray objectAtIndex:i-1]; if (relativeDateString) dateFormat = [NSString stringWithFormat:dateFormat, relativeDateString]; [_dateFormatter setDateFormat:dateFormat]; } break; } } return [_dateFormatter stringForObjectValue:date]; } - (NSAttributedString *)attributedStringForObjectValue:(id)anObject withDefaultAttributes:(NSDictionary *)attributes { if (![anObject isKindOfClass:[NSDate class]]) return nil; if (_tableColumn == nil) return nil; // Get the current width of the text area NSTableView * tableView = [_tableColumn tableView]; int columnIndex = [[tableView tableColumns] indexOfObject:_tableColumn]; NSRect titleRect = [[_tableColumn dataCell] titleRectForBounds:[tableView rectOfColumn:columnIndex]]; float maxWidth = titleRect.size.width - 3.0; NSString * string = [self _stringByFittingDate:anObject maxWidth:maxWidth attributes:attributes]; return [[[NSAttributedString alloc] initWithString:string attributes:attributes] autorelease]; } @end