1from Cocoa import * 2 3gNumDaysInMonth = ( 0, 31, 28, 31, 30, 21, 30, 31, 31, 30, 31, 30, 31 ) 4 5def isLeap(year): 6 return (((year % 4) == 0 and ((year % 100) != 0)) or (year % 400) == 0) 7 8class CalendarMatrix (NSMatrix): 9 lastMonthButton = objc.IBOutlet() 10 monthName = objc.IBOutlet() 11 nextMonthButton = objc.IBOutlet() 12 13 __slots__ = ('_selectedDay', '_startOffset') 14 15 def initWithFrame_(self, frameRect): 16 self._selectedDay = None 17 self._startOffset = 0 18 19 cell = NSButtonCell.alloc().initTextCell_("") 20 now = NSCalendarDate.date() 21 22 cell.setShowsStateBy_(NSOnOffButton) 23 self.initWithFrame_mode_prototype_numberOfRows_numberOfColumns_( 24 frameRect, NSRadioModeMatrix, cell, 5, 7) 25 26 count = 0 27 for i in range(6): 28 for j in range(7): 29 val = self.cellAtRow_column_(i, j) 30 if val: 31 val.setTag_(count) 32 count += 1 33 34 self._selectedDay = NSCalendarDate.dateWithYear_month_day_hour_minute_second_timeZone_( 35 now.yearOfCommonEra(), 36 now.monthOfYear(), 37 now.dayOfMonth(), 38 0, 39 0, 40 0, 41 NSTimeZone.localTimeZone()) 42 return self 43 44 45 @objc.IBAction 46 def choseDay_(self, sender): 47 prevSelDate = self.selectedDay() 48 selDay = self.selectedCell().tag() - self._startOffset + 1 49 50 selDate = NSCalendarDate.dateWithYear_month_day_hour_minute_second_timeZone_( 51 prevSelDate.yearOfCommonEra(), 52 prevSelDate.monthOfYear(), 53 selDay, 54 0, 55 0, 56 0, 57 NSTimeZone.localTimeZone()) 58 self.setSelectedDay_(selDate) 59 self.highlightTodayIfVisible() 60 61 if self.delegate().respondsToSelector_('calendarMatrix:didChangeToDate:'): 62 self.delegate().calendarMatrix_didChangeToDate_( 63 self, selDate) 64 65 66 @objc.IBAction 67 def monthChanged_(self, sender): 68 thisDate = self.selectedDay() 69 currentYear = thisDate.yearOfCommonEra() 70 currentMonth = thisDate.monthOfYear() 71 72 if sender is self.nextMonthButton: 73 if currentMonth == 12: 74 currentMonth = 1 75 currentYear += 1 76 else: 77 currentMonth += 1 78 else: 79 if currentMonth == 1: 80 currentMonth = 12 81 currentYear -= 1 82 else: 83 currentMonth -= 1 84 85 self.setSelectedDay_(NSCalendarDate.dateWithYear_month_day_hour_minute_second_timeZone_(currentYear, currentMonth, 1, 0, 0, 0, NSTimeZone.localTimeZone())) 86 self.refreshCalendar() 87 self.choseDay_(self) 88 89 def setSelectedDay_(self, newDay): 90 self._selectedDay = newDay 91 92 def selectedDay(self): 93 return self._selectedDay 94 95 def refreshCalendar(self): 96 97 selDate = self.selectedDay() 98 currentMonth = selDate.monthOfYear() 99 currentYear = selDate.yearOfCommonEra() 100 101 firstOfMonth = NSCalendarDate.dateWithYear_month_day_hour_minute_second_timeZone_( 102 currentYear, 103 currentMonth, 104 1, 105 0, 106 0, 107 0, 108 NSTimeZone.localTimeZone()) 109 self.monthName.setStringValue_( 110 firstOfMonth.descriptionWithCalendarFormat_("%B %Y")) 111 daysInMonth = gNumDaysInMonth[currentMonth] 112 113 if (currentMonth == 2) and isLeap(currentYear): 114 daysInMonth += 1 115 116 self._startOffset = firstOfMonth.dayOfWeek() 117 118 dayLabel = 1 119 120 for i in range(42): 121 cell = self.cellWithTag_(i) 122 if cell is None: 123 continue 124 125 if i < self._startOffset or i >= (daysInMonth + self._startOffset): 126 # blank out unused cells in the matrix 127 cell.setBordered_(False) 128 cell.setEnabled_(False) 129 cell.setTitle_("") 130 cell.setCellAttribute_to_(NSCellHighlighted, False) 131 else: 132 # Fill in valid days in the matrix 133 cell.setBordered_(True) 134 cell.setEnabled_(True) 135 cell.setFont_(NSFont.systemFontOfSize_(12)) 136 cell.setTitle_(str(dayLabel)) 137 dayLabel += 1 138 cell.setCellAttribute_to_(NSCellHighlighted, False) 139 140 self.selectCellWithTag_(selDate.dayOfMonth() + self._startOffset - 1) 141 self.highlightTodayIfVisible() 142 143 144 def highlightTodayIfVisible(self): 145 now = NSCalendarDate.date() 146 selDate = self.selectedDay() 147 148 if (selDate.yearOfCommonEra() == now.yearOfCommonEra() 149 and selDate.monthOfYear() == now.monthOfYear() 150 and selDate.dayOfMonth() == now.dayOfMonth()): 151 aCell = self.cellWithTag_( 152 now.dayOfMonth() + self._startOffset - 1) 153 aCell.setHighlightsBy_(NSMomentaryChangeButton) 154 aCell.setCellAttribute_to_(NSCellHighlighted, True) 155 156 def awakeFromNib(self): 157 self.setTarget_(self) 158 self.setAction_('choseDay:') 159 self.setAutosizesCells_(True) 160 self.refreshCalendar() 161 self.choseDay_(self) 162