1from Cocoa import * 2 3# date/time element popup selections: 4kNSHourMinuteDatePickerElementFlag = 0 5kNSHourMinuteSecondDatePickerElementFlag = 1 6kNSTimeZoneDatePickerElementFlag = 2 7 8kNSYearMonthDatePickerElementFlag = 0 9kNSYearMonthDayDatePickerElementFlag = 1 10kNSEraDatePickerElementFlag = 2 11 12kSingleDateMode = 0 13kRangeDateMode = 1 14 15 16 17class MyWindowController (NSWindowController): 18 datePickerControl = objc.ivar() 19 shrinkGrowFactor = objc.ivar.int() 20 21 outerBox = objc.IBOutlet() 22 datePickerPlaceHolder = objc.IBOutlet() 23 24 dateResult1 = objc.IBOutlet() 25 dateResult2 = objc.IBOutlet() 26 dateResult3 = objc.IBOutlet() 27 dateResult4 = objc.IBOutlet() 28 dateResult5 = objc.IBOutlet() 29 30 # appearance 31 pickerStylePopup = objc.IBOutlet() 32 drawsBackgroundCheck = objc.IBOutlet() 33 bezeledCheck = objc.IBOutlet() 34 borderedCheck = objc.IBOutlet() 35 backColorWell = objc.IBOutlet() 36 textColorWell = objc.IBOutlet() 37 fontSizePopup = objc.IBOutlet() 38 39 # date and time 40 dateElementChecks = objc.IBOutlet() 41 timeElementChecks = objc.IBOutlet() 42 overrideDateCheck = objc.IBOutlet() 43 overrideDate = objc.IBOutlet() 44 45 # date range 46 datePickerModeRadios = objc.IBOutlet() 47 secondsRangeEdit = objc.IBOutlet() 48 secondsRangeEditLabel = objc.IBOutlet() 49 50 minDatePicker = objc.IBOutlet() 51 maxDatePicker = objc.IBOutlet() 52 setMinDateButton = objc.IBOutlet() 53 setMaxDateButton = objc.IBOutlet() 54 clearMinDateButton = objc.IBOutlet() 55 clearMaxDateButton = objc.IBOutlet() 56 57 def awakeFromNib(self): 58 # based our date formatter on CFDateFormatter: allows more configurability and better localization 59 NSDateFormatter.setDefaultFormatterBehavior_(NSDateFormatterBehavior10_4) 60 61 self.setupDatePickerControl_(NSClockAndCalendarDatePickerStyle) 62 63 # setup the initial NSDatePickerElementFlags since we are using picker style: 64 # NSClockAndCalendarDatePickerStyle 65 flags = ( 66 NSYearMonthDatePickerElementFlag 67 | NSYearMonthDayDatePickerElementFlag 68 | NSEraDatePickerElementFlag 69 | NSHourMinuteDatePickerElementFlag 70 | NSHourMinuteSecondDatePickerElementFlag 71 | NSTimeZoneDatePickerElementFlag 72 ) 73 self.datePickerControl.setDatePickerElements_(flags) 74 75 self.datePickerModeRadios.cellWithTag_(1).setEnabled_(False) # not currently implemened in 10.4.x and earlier 76 77 self.minDatePicker.setDateValue_(NSDate.date()) 78 self.maxDatePicker.setDateValue_(NSDate.distantFuture()) 79 80 self.updateControls() # force update of all UI elements and the picker itself 81 82 def applicationShouldTerminateAfterLastWindowClosed_(self, sender): 83 return True 84 85 def setupDatePickerControl_(self, pickerStyle): 86 # we need to re-create the picker control (due to a resize bug when switching between styles) 87 if self.datePickerControl is not None: # hide and release the previous date picker, if any 88 self.datePickerControl.setHidden_(True) 89 self.datePickerControl.setNeedsDisplay_(True) 90 self.datePickerControl = None 91 92 frame = self.datePickerPlaceHolder.frame() 93 self.shrinkGrowFactor = frame.size.height - 30 94 95 # create the date picker control if not created already 96 if self.datePickerControl is None: 97 self.datePickerControl = NSDatePicker.alloc().initWithFrame_(frame) 98 99 self.datePickerControl.setFrameOrigin_(NSMakePoint(1,0)) # nudge the control placement a little 100 101 self.datePickerControl.setDatePickerStyle_(pickerStyle) # set our desired picker style 102 103 self.datePickerPlaceHolder.addSubview_(self.datePickerControl) # embed into our placeholder 104 self.datePickerControl.setDrawsBackground_(True) 105 self.datePickerControl.setBezeled_(True) 106 self.datePickerControl.setBordered_(False) 107 self.datePickerControl.setEnabled_(True) 108 109 self.datePickerControl.setTextColor_(self.textColorWell.color()) 110 self.datePickerControl.setBackgroundColor_(self.backColorWell.color()) 111 112 # always set the date/time to TODAY 113 # note that our delete override might block this... 114 self.datePickerControl.setDateValue_(NSDate.date()) 115 116 self.datePickerControl.setNeedsDisplay_(True) 117 self.updateControls() # force update of all UI elements and the picker itself 118 119 # synch the picker style popup with the new style change 120 self.pickerStylePopup.selectItemWithTag_(pickerStyle) 121 122 # we want to be the cell's delegate to catch date validation 123 self.datePickerControl.setDelegate_(self) 124 # or we can set us as the delegate to its cell like so: 125 # self.datePickerControl.cell().setDelegate_(self) 126 127 # we want to respond to date/time changes 128 self.datePickerControl.setAction_('datePickerAction:') 129 130 131 def updateDateResult(self): 132 theDate = self.datePickerControl.dateValue() 133 if theDate is not None: 134 formatter = NSDateFormatter.alloc().init() 135 136 # some examples: 137 # formatter.setDateStyle_(NSDateFormatterNoStyle) # <no date displayed> 138 # formatter.setDateStyle_(NSDateFormatterMediumStyle) # Jan 24, 1984 139 # formatter.setDateStyle_(NSDateFormatterShortStyle) # 1/24/84 140 # formatter.setDateStyle_(NSDateFormatterLongStyle) # January 24, 1984 141 # formatter.setDateStyle_(NSDateFormatterFullStyle) # Tuesday, January 24, 1984 142 # 143 # formatter.setTimeStyle_(NSDateFormatterNoStyle) # <no time displayed> 144 # formatter.setTimeStyle_(NSDateFormatterShortStyle) # 2:44 PM 145 # formatter.setTimeStyle_(NSDateFormatterMediumStyle) # 2:44:55 PM 146 # formatter.setTimeStyle_(NSDateFormatterLongStyle) # 2:44:55 PM PDT 147 # formatter.setTimeStyle_(NSDateFormatterFullStyle) # 2:44:55 PM PDT 148 # 149 150 formatter.setDateStyle_(NSDateFormatterShortStyle) 151 formatter.setTimeStyle_(NSDateFormatterNoStyle) 152 formattedDateString = formatter.stringFromDate_(theDate) 153 self.dateResult1.setStringValue_(formattedDateString) 154 155 formatter.setDateStyle_(NSDateFormatterShortStyle) 156 formatter.setTimeStyle_(NSDateFormatterShortStyle) 157 formattedDateString = formatter.stringFromDate_(theDate) 158 self.dateResult2.setStringValue_(formattedDateString) 159 160 formatter.setDateStyle_(NSDateFormatterMediumStyle) 161 formatter.setTimeStyle_(NSDateFormatterShortStyle) 162 formattedDateString = formatter.stringFromDate_(theDate) 163 self.dateResult3.setStringValue_(formattedDateString) 164 165 formatter.setDateStyle_(NSDateFormatterLongStyle) 166 formatter.setTimeStyle_(NSDateFormatterShortStyle) 167 formattedDateString = formatter.stringFromDate_(theDate) 168 self.dateResult4.setStringValue_(formattedDateString) 169 170 formatter.setDateStyle_(NSDateFormatterFullStyle) 171 formatter.setTimeStyle_(NSDateFormatterFullStyle) 172 formattedDateString = formatter.stringFromDate_(theDate) 173 self.dateResult5.setStringValue_(formattedDateString) 174 175 def updateControls(self): 176 self.datePickerControl.setNeedsDisplay_(True) # force it to update 177 178 self.updateDatePickerMode() 179 self.updateDateTimeElementFlags() 180 self.updateDateResult() 181 182 @objc.IBAction 183 def setPickerStyle_(self, sender): 184 tag = sender.selectedCell().tag() 185 186 windowFrame = self.window().frame() 187 boxFrame = self.outerBox.frame() 188 189 self.datePickerControl.setHidden_(True) 190 191 if tag == NSClockAndCalendarDatePickerStyle: 192 # for this picker style, we need to grow the window to make room 193 194 windowFrame.size.height += self.shrinkGrowFactor; 195 windowFrame.origin.y -= self.shrinkGrowFactor; 196 197 boxFrame.size.height += self.shrinkGrowFactor; 198 self.outerBox.setFrame_(boxFrame) 199 200 self.window().setFrame_display_animate_(windowFrame, True, True) 201 202 # set our desired picker style 203 self.datePickerControl.setDatePickerStyle_(NSClockAndCalendarDatePickerStyle) 204 205 # shows these last 206 self.dateResult1.setHidden_(False) 207 self.dateResult2.setHidden_(False) 208 self.dateResult3.setHidden_(False) 209 self.dateResult4.setHidden_(False) 210 211 else: 212 currentPickerStyle = self.datePickerControl.datePickerStyle() 213 214 # shrink the window only if the current style is "clock and calendar" 215 if currentPickerStyle == NSClockAndCalendarDatePickerStyle: 216 # hide these first 217 self.dateResult1.setHidden_(True) 218 self.dateResult2.setHidden_(True) 219 self.dateResult3.setHidden_(True) 220 self.dateResult4.setHidden_(True) 221 222 windowFrame.size.height -= self.shrinkGrowFactor 223 windowFrame.origin.y += self.shrinkGrowFactor 224 225 boxFrame.size.height -= self.shrinkGrowFactor 226 self.outerBox.setFrame_(boxFrame) 227 228 self.window().setFrame_display_animate_(windowFrame, True, True) 229 230 self.setupDatePickerControl_(tag) # set our desired picker style 231 232 self.datePickerControl.setHidden_(False) 233 234 self.updateControls() # force update of all UI elements and the picker itself 235 236 @objc.IBAction 237 def setFontSize_(self, sender): 238 tag = sender.selectedCell().tag() 239 if tag == NSMiniControlSize: 240 self.datePickerControl.cell().setControlSize_(NSMiniControlSize) 241 self.datePickerControl.cell().setFont_(NSFont.systemFontOfSize_(9.0)) 242 243 elif tag == NSSmallControlSize: 244 self.datePickerControl.cell().setControlSize_(NSSmallControlSize) 245 self.datePickerControl.cell().setFont_(NSFont.systemFontOfSize_(11.0)) 246 247 elif tag == NSRegularControlSize: 248 self.datePickerControl.cell().setControlSize_(NSRegularControlSize) 249 self.datePickerControl.cell().setFont_(NSFont.systemFontOfSize_(13.0)) 250 251 @objc.IBAction 252 def datePickerAction_(self, sender): 253 self.updateDateResult() 254 255 @objc.IBAction 256 def dateOverrideAction_(self, sender): 257 checked = sender.selectedCell().state() 258 if checked: 259 self.datePickerControl.setDelegate_(self) 260 261 else: 262 self.datePickerControl.setDelegate_(None) 263 264 self.datePickerControl.setDateValue_(NSDate.date()) # force the delete "datePickerCell" to be called 265 266 def datePickerCell_validateProposedDateValue_timeInterval_(self, aDatePickerCell, proposedDateValue, proposedTimeInterval): 267 controller = aDatePickerCell.delegate() 268 269 if controller is self and aDatePickerCell is self.datePickerControl.cell(): 270 # override the date and time? 271 if self.overrideDateCheck.cell().state(): 272 # override the date using the user specified date 273 return (self.overrideDate.dateValue(), proposedTimeInterval) 274 275 return (proposedDateValue, proposedTimeInterval) 276 277 @objc.IBAction 278 def setDrawsBackground_(self, sender): 279 self.datePickerControl.setDrawsBackground_(sender.state()) 280 281 @objc.IBAction 282 def setBackgroundColor_(self, sender): 283 newColor = sender.color() 284 self.datePickerControl.setBackgroundColor_(newColor) 285 286 @objc.IBAction 287 def setTextColor_(self, sender): 288 newColor = sender.color() 289 self.datePickerControl.setTextColor_(newColor) 290 291 @objc.IBAction 292 def setBezeled_(self, sender): 293 self.datePickerControl.setBezeled_(sender.state()) 294 295 @objc.IBAction 296 def setBordered_(self, sender): 297 self.datePickerControl.setBordered_(sender.state()) 298 299 300 @objc.IBAction 301 def setDateElementFlags_(self, sender): 302 tag = sender.selectedCell().tag() 303 flags = self.datePickerControl.datePickerElements() 304 305 checked = sender.selectedCell().state() 306 307 if tag == kNSYearMonthDatePickerElementFlag: 308 if checked: 309 flags |= NSYearMonthDatePickerElementFlag 310 else: 311 flags ^= NSYearMonthDatePickerElementFlag 312 313 elif tag == kNSYearMonthDayDatePickerElementFlag: 314 if checked: 315 flags |= NSYearMonthDayDatePickerElementFlag 316 else: 317 flags ^= NSYearMonthDayDatePickerElementFlag 318 319 elif tag == kNSEraDatePickerElementFlag: 320 if checked: 321 flags |= NSEraDatePickerElementFlag 322 else: 323 flags ^= NSEraDatePickerElementFlag 324 325 self.datePickerControl.setDatePickerElements_(flags) 326 327 self.updateControls() # force update of all UI elements and the picker itself 328 329 @objc.IBAction 330 def setTimeElementFlags_(self, sender): 331 tag = sender.selectedCell().tag() 332 flags = self.datePickerControl.datePickerElements() 333 334 checked = sender.selectedCell().state() 335 336 if tag == kNSHourMinuteDatePickerElementFlag: 337 if checked: 338 flags |= NSHourMinuteDatePickerElementFlag 339 else: 340 flags ^= NSHourMinuteDatePickerElementFlag 341 342 elif tag == kNSHourMinuteSecondDatePickerElementFlag: 343 if checked: 344 flags |= NSHourMinuteSecondDatePickerElementFlag 345 else: 346 flags ^= NSHourMinuteSecondDatePickerElementFlag 347 348 elif tag == kNSTimeZoneDatePickerElementFlag: 349 if checked: 350 flags |= NSTimeZoneDatePickerElementFlag 351 else: 352 flags ^= NSTimeZoneDatePickerElementFlag 353 354 self.datePickerControl.setDatePickerElements_(flags) 355 356 self.updateControls() # force update of all UI elements and the picker itself 357 358 def updateDateTimeElementFlags(self): 359 elementFlags = self.datePickerControl.datePickerElements() 360 361 # time elements 362 if (elementFlags & NSHourMinuteDatePickerElementFlag) != 0: 363 self.timeElementChecks.selectCellWithTag_(0) 364 if (elementFlags & NSHourMinuteSecondDatePickerElementFlag) != 0: 365 self.timeElementChecks.selectCellWithTag_(1) 366 if (elementFlags & NSTimeZoneDatePickerElementFlag) != 0: 367 self.timeElementChecks.selectCellWithTag_(2) 368 369 # date elements 370 if (elementFlags & NSYearMonthDatePickerElementFlag) != 0: 371 self.dateElementChecks.selectCellWithTag_(0) 372 if (elementFlags & NSYearMonthDayDatePickerElementFlag) != 0: 373 self.dateElementChecks.selectCellWithTag_(1) 374 if (elementFlags & NSEraDatePickerElementFlag) != 0: 375 self.dateElementChecks.selectCellWithTag_(2) 376 377 378 @objc.IBAction 379 def setMinDate_(self, sender): 380 self.datePickerControl.setMinDate_(self.minDatePicker.dateValue()) 381 self.setMinDateButton.setEnabled_(False) 382 self.clearMinDateButton.setEnabled_(True) 383 384 385 @objc.IBAction 386 def setMaxDate_(self, sender): 387 self.datePickerControl.setMaxDate_(self.maxDatePicker.dateValue()) 388 self.setMaxDateButton.setEnabled_(False) 389 self.clearMaxDateButton.setEnabled_(True) 390 391 @objc.IBAction 392 def clearMinDate_(self, sender): 393 self.datePickerControl.setMinDate_(NSDate.distantPast()) 394 self.clearMinDateButton.setEnabled_(False) 395 self.setMinDateButton.setEnabled_(True) 396 397 398 @objc.IBAction 399 def clearMaxDate_(self, sender): 400 self.datePickerControl.setMaxDate_(NSDate.distantFuture()) 401 self.clearMaxDateButton.setEnabled_(False) 402 self.setMaxDateButton.setEnabled_(True) 403 404 @objc.IBAction 405 def setDatePickerMode_(self, sender): 406 tag = sender.selectedCell().tag() 407 408 if tag == kSingleDateMode: 409 self.datePickerControl.setDatePickerMode_(NSSingleDateMode) 410 411 elif tag == kRangeDateMode: 412 self.datePickerControl.setDatePickerMode_(NSRangeDateMode) 413 414 self.updateControls() # force update of all UI elements and the picker itself 415 416 417 def updateDatePickerMode(self): 418 mode = self.datePickerControl.datePickerMode() 419 if mode == NSSingleDateMode: 420 self.datePickerModeRadios.selectCellWithTag_(0) 421 422 # interval value not applicable: 423 self.secondsRangeEdit.setEnabled_(False) 424 self.secondsRangeEditLabel.setTextColor_(NSColor.lightGrayColor()) 425 426 self.datePickerControl.setTimeInterval_(0) 427 428 elif mode == NSRangeDateMode: 429 self.datePickerModeRadios.selectCellWithTag_(1) 430 431 # interval value applies: 432 self.secondsRangeEdit.setEnabled_(True) 433 self.secondsRangeEditLabel.setTextColor_(NSColor.blackColor()) 434 435 # set the date range by start date (here we use the current date in the date picker 436 # control), and time interval (in seconds) 437 secsStr = self.secondsRangeEdit.stringValue() 438 numSeconds = int(secsStr) 439 self.datePickerControl.setTimeInterval_(numSeconds) 440 441 def controlTextDidEndEditing_(self, notification): 442 self.updateDatePickerMode() # force update of the date picker control 443