#include "CalendarView.h" #include "GNUstep.h" @implementation CalendarView #define isLeapYear(year) (((year % 4) == 0 && ((year % 100) != 0)) || (year % 400) == 0) static short numberOfDaysInMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - (void) awakeFromNib { [self setDate: [NSCalendarDate calendarDate]]; } - (NSCalendarDate *) date { return date; } - (void) setDate: (NSCalendarDate *) newDate { int i, currentDay, currentMonth, currentYear; int daysInMonth, startDayOfWeek, day; NSCalendarDate *firstDayOfMonth, *displayDate;; NSButtonCell *tempCell; ASSIGN(date, newDate); [label setStringValue: [date descriptionWithCalendarFormat: @"%b %Y"]]; currentMonth = [date monthOfYear]; currentYear = [date yearOfCommonEra]; firstDayOfMonth = [NSCalendarDate dateWithYear: currentYear month: currentMonth day: 1 hour: 0 minute: 0 second: 0 timeZone: [NSTimeZone localTimeZone]]; daysInMonth = numberOfDaysInMonth[currentMonth - 1]; if ((currentMonth == 2) && (isLeapYear(currentYear))) daysInMonth++; startDayOfWeek = [firstDayOfMonth dayOfWeek]; day = 1; for (i = 0; i < 42; i++) { tempCell = [dayMatrix cellWithTag: i]; [tempCell setBordered: NO]; if (i < startDayOfWeek || i >= (daysInMonth + startDayOfWeek)) { [tempCell setEnabled: NO]; [tempCell setTitle: @""]; } else { displayDate = [firstDayOfMonth dateByAddingYears: 0 months: 0 days: day-1 hours: 0 minutes: 0 seconds: 0]; [tempCell setEnabled: YES]; [tempCell setTitle: [NSString stringWithFormat: @"%d", day++]]; if ([delegate respondsToSelector: @selector(calendarView:willDisplayCell:ofDate:)]) { [delegate calendarView: self willDisplayCell: tempCell ofDate: displayDate]; } } } currentDay = [date dayOfMonth]; [dayMatrix selectCellWithTag: startDayOfWeek + currentDay - 1]; // Send notification [[NSNotificationCenter defaultCenter] postNotificationName: CalendarViewSelectionDidChangeNotification object: self]; } - (id) initWithFrame: (NSRect) rect { int i, j, count=0; NSImage *rightArrow, *leftArrow; NSButtonCell *dayCell, *tempCell; NSArray *weekArray; NSRect frame; NSSize boxMargin, contentSize; [super initWithFrame: rect]; calendarBox = [[NSBox alloc] initWithFrame: NSMakeRect(0, 0, rect.size.width, rect.size.height)]; [calendarBox setBorderType: NSGrooveBorder]; [calendarBox setTitlePosition: NSNoTitle]; [calendarBox setAutoresizingMask: (NSViewWidthSizable | NSViewHeightSizable)]; boxMargin = [calendarBox contentViewMargins]; contentSize = [[calendarBox contentView] bounds].size; frame = NSMakeRect(18, contentSize.height-20, contentSize.width-36, 20); label = [[NSTextField alloc] initWithFrame: frame]; [label setStringValue: @"This Year"]; [label setBezeled: NO]; [label setBackgroundColor: [NSColor windowBackgroundColor]]; [label setEditable: NO]; [label setSelectable: NO]; [label setAlignment: NSCenterTextAlignment]; [label setAutoresizingMask: (NSViewWidthSizable | NSViewMinYMargin)]; leftArrow = [NSImage imageNamed: @"common_ArrowLeft.tif"]; rightArrow = [NSImage imageNamed: @"common_ArrowRight.tif"]; frame = NSMakeRect(0, contentSize.height-18, 20, 20); lastMonthButton = [[NSButton alloc] initWithFrame: frame]; [lastMonthButton setImage: leftArrow]; [lastMonthButton setImagePosition: NSImageOnly]; [lastMonthButton setBordered: NO]; [lastMonthButton setAutoresizingMask: (NSViewMaxXMargin | NSViewMinYMargin)]; frame = NSMakeRect(contentSize.width-20, contentSize.height-18, 20, 20); nextMonthButton = [[NSButton alloc] initWithFrame: frame]; [nextMonthButton setImage: rightArrow]; [nextMonthButton setImagePosition: NSImageOnly]; [nextMonthButton setBordered: NO]; [nextMonthButton setAutoresizingMask: (NSViewMinXMargin | NSViewMinYMargin)]; [lastMonthButton setTarget: self]; [lastMonthButton setAction: @selector(updateDate:)]; [nextMonthButton setTarget: self]; [nextMonthButton setAction: @selector(updateDate:)]; [calendarBox addSubview: label]; [calendarBox addSubview: lastMonthButton]; [calendarBox addSubview: nextMonthButton]; RELEASE(label); RELEASE(lastMonthButton); RELEASE(nextMonthButton); weekArray = [NSArray arrayWithObjects: @"S", @"M", @"T", @"W", @"T", @"F", @"S", nil]; dayCell = [[NSButtonCell alloc] initTextCell: @""]; [dayCell setBordered: NO]; [dayCell setShowsStateBy: NSOnOffButton]; [dayCell setAlignment: NSCenterTextAlignment]; [dayCell setFont: [NSFont userFontOfSize: 10]]; frame = NSMakeRect(0, 0, contentSize.width, contentSize.height-20); dayMatrix = [[NSMatrix alloc] initWithFrame: frame mode: NSRadioModeMatrix prototype: dayCell numberOfRows: 7 numberOfColumns: 7]; [dayMatrix setAutoresizingMask: (NSViewWidthSizable | NSViewHeightSizable)]; [dayMatrix setIntercellSpacing: NSMakeSize(0,0)]; [dayMatrix setAutosizesCells: YES]; for (j = 0; j < 7; j++) { tempCell = [dayMatrix cellAtRow: 0 column: j]; [tempCell setTitle: [weekArray objectAtIndex: j]]; [tempCell setAlignment: NSCenterTextAlignment]; [tempCell setEnabled: NO]; } RELEASE(dayCell); count = 0; for (i = 1; i < 7; i++) for (j = 0; j < 7; j++) { [[dayMatrix cellAtRow: i column: j] setTag: count++]; } [dayMatrix setTarget: self]; [dayMatrix setAction: @selector(updateDate:)]; [calendarBox addSubview: dayMatrix]; RELEASE(dayMatrix); [self addSubview: calendarBox]; RELEASE(calendarBox); return self; } - (void) updateDate: (id) sender { int j=0, k=0; NSCalendarDate *newDate; if (sender == lastMonthButton) { j = -1; } else if (sender == nextMonthButton) { j = 1; } else if (sender == dayMatrix) { k = [[[sender selectedCell] title] intValue] - [date dayOfMonth]; } newDate = [date dateByAddingYears: 0 months: j days: k hours: 0 minutes: 0 seconds: 0]; [self setDate: newDate]; } - (void) dealloc { [[NSNotificationCenter defaultCenter] removeObserver: delegate]; RELEASE(date); RELEASE(delegate); [super dealloc]; } - (void) setDelegate: (id) d { ASSIGN(delegate, d); [[NSNotificationCenter defaultCenter] addObserver: delegate selector: @selector(calendarViewSelectionDidChange:) name: CalendarViewSelectionDidChangeNotification object: self]; } - (id) delegate { return delegate; } @end