1#!/usr/bin/env python 2 3#---------------------------------------------------------------------------- 4# Name: Calendar.py 5# Purpose: Calendar control display testing on panel for wxPython demo 6# 7# Author: Lorne White (email: lwhite1@planet.eon.net) 8# 9# Version 0.9 10# Date: Feb 26, 2001 11# Licence: wxWindows license 12#---------------------------------------------------------------------------- 13# 11/15/2003 - Jeff Grimmett (grimmtooth@softhome.net) 14# 15# o Updated for wx namespace 16# 17# 11/26/2003 - Jeff Grimmett (grimmtooth@softhome.net) 18# 19# o Ugh. AFter updating to the Bind() method, things lock up 20# on various control clicks. Will have to debug. Only seems 21# to happen on windows with calendar controls, though. 22# 23# 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net) 24# 25# o Lockup issue clarification: it appears that the spinner is 26# the culprit. 27# 28 29import os 30 31import wx 32import wx.lib.calendar 33 34import images 35 36 37# highlighted days in month 38 39test_days ={ 0: [], 40 1: [3, 7, 9, 21], 41 2: [2, 10, 4, 9], 42 3: [4, 20, 29], 43 4: [1, 12, 22], 44 5: [2, 10, 15], 45 6: [4, 8, 17], 46 7: [6, 7, 8], 47 8: [5, 10, 20], 48 9: [1, 2, 5, 29], 49 10: [2, 4, 6, 22], 50 11: [6, 9, 12, 28, 29], 51 12: [8, 9, 10, 11, 20] } 52 53# test of full window calendar control functions 54 55def GetMonthList(): 56 57 monthlist = [] 58 59 for i in range(13): 60 name = wx.lib.calendar.Month[i] 61 62 if name != None: 63 monthlist.append(name) 64 65 return monthlist 66 67class TestPanel(wx.Panel): 68 def __init__(self, parent, log, frame): 69 wx.Panel.__init__(self, parent, -1) 70 71 self.log = log 72 self.frame = frame 73 74 self.calend = wx.lib.calendar.Calendar(self, -1, (100, 50), (200, 180)) 75 76# start_month = 2 # preselect the date for calendar 77# start_year = 2001 78 79 start_month = self.calend.GetMonth() # get the current month & year 80 start_year = self.calend.GetYear() 81 82 # month list from DateTime module 83 84 monthlist = GetMonthList() 85 86 self.date = wx.ComboBox(self, -1, "", 87 (100, 20), (90, -1), 88 monthlist, wx.CB_DROPDOWN) 89 90 self.date.SetSelection(start_month-1) 91 self.Bind(wx.EVT_COMBOBOX, self.EvtComboBox, self.date) 92 93 # set start month and year 94 95 self.calend.SetMonth(start_month) 96 self.calend.SetYear(start_year) 97 98 # set attributes of calendar 99 100 self.calend.hide_title = True 101 self.calend.HideGrid() 102 self.calend.SetWeekColor('WHITE', 'BLACK') 103 104 # display routine 105 106 self.ResetDisplay() 107 108 # mouse click event 109 self.Bind(wx.lib.calendar.EVT_CALENDAR, self.MouseClick, self.calend) 110 111 # scroll bar for month selection 112 self.scroll = wx.ScrollBar(self, -1, (100, 240), (200, 20), wx.SB_HORIZONTAL) 113 self.scroll.SetScrollbar(start_month-1, 1, 12, 1, True) 114 self.Bind(wx.EVT_COMMAND_SCROLL, self.Scroll, self.scroll) 115 116 # spin control for year selection 117 118 self.dtext = wx.TextCtrl(self, -1, str(start_year), (200, 20), (60, -1)) 119 h = self.dtext.GetSize().height 120 121 self.spin = wx.SpinButton(self, -1, (270, 20), (h*2, h)) 122 self.spin.SetRange(1980, 2010) 123 self.spin.SetValue(start_year) 124 self.Bind(wx.EVT_SPIN, self.OnSpin, self.spin) 125 126 # button for calendar dialog test 127 self.but1 = wx.Button(self, -1, "Test Calendar Dialog", (380, 80)) 128 self.Bind(wx.EVT_BUTTON, self.TestDlg, self.but1) 129 130 # button for calendar window test 131 self.but2 = wx.Button(self, -1, "Test Calendar Window", (380, 180)) 132 self.Bind(wx.EVT_BUTTON, self.TestFrame, self.but2) 133 134 self.but3 = wx.Button(self, -1, "Test Calendar Print", (380, 280)) 135 self.Bind(wx.EVT_BUTTON, self.OnPreview, self.but3) 136 137 # calendar dialog 138 139 def TestDlg(self, event): # test the date dialog 140 dlg = wx.lib.calendar.CalenDlg(self) 141 dlg.Centre() 142 143 if dlg.ShowModal() == wx.ID_OK: 144 result = dlg.result 145 day = result[1] 146 month = result[2] 147 year = result[3] 148 new_date = str(month) + '/'+ str(day) + '/'+ str(year) 149 self.log.WriteText('Date Selected: %s\n' % new_date) 150 else: 151 self.log.WriteText('No Date Selected') 152 153 # calendar window test 154 155 def TestFrame(self, event): 156 frame = CalendFrame(self, -1, "Test Calendar", self.log) 157 frame.Show(True) 158 return True 159 160 # calendar print preview 161 162 def OnPreview(self, event): 163 month = self.calend.GetMonth() 164 year = self.calend.GetYear() 165 166 prt = PrintCalend(self.frame, month, year) 167 prt.Preview() 168 169 # month and year control events 170 171 def OnSpin(self, event): 172 year = event.GetPosition() 173 self.dtext.SetValue(str(year)) 174 self.calend.SetYear(year) 175 self.calend.Refresh() 176 177 def EvtComboBox(self, event): 178 name = event.GetString() 179 self.log.WriteText('EvtComboBox: %s\n' % name) 180 monthval = self.date.FindString(name) 181 self.scroll.SetScrollbar(monthval, 1, 12, 1, True) 182 183 self.calend.SetMonth(monthval+1) 184 self.ResetDisplay() 185 186 def Scroll(self, event): 187 value = self.scroll.GetThumbPosition() 188 monthval = int(value)+1 189 self.calend.SetMonth(monthval) 190 self.ResetDisplay() 191 self.log.WriteText('Month: %s\n' % value) 192 193 name = wx.lib.calendar.Month[monthval] 194 self.date.SetValue(name) 195 196 # log mouse events 197 198 def MouseClick(self, evt): 199 text = '%s CLICK %02d/%02d/%d' % (evt.click, evt.day, evt.month, evt.year) # format date 200 self.log.WriteText('Date Selected: ' + text + '\n') 201 202 203 # set the highlighted days for the calendar 204 205 def ResetDisplay(self): 206 month = self.calend.GetMonth() 207 208 try: 209 set_days = test_days[month] 210 except: 211 set_days = [1, 5, 12] 212 213 self.calend.AddSelect([4, 11], 'BLUE', 'WHITE') 214 self.calend.SetSelDay(set_days) 215 self.calend.Refresh() 216 217 # increment and decrement toolbar controls 218 219 def OnIncYear(self, event): 220 self.calend.IncYear() 221 self.ResetDisplay() 222 223 def OnDecYear(self, event): 224 self.calend.DecYear() 225 self.ResetDisplay() 226 227 def OnIncMonth(self, event): 228 self.calend.IncMonth() 229 self.ResetDisplay() 230 231 def OnDecMonth(self, event): 232 self.calend.DecMonth() 233 self.ResetDisplay() 234 235 def OnCurrent(self, event): 236 self.calend.SetCurrentDay() 237 self.ResetDisplay() 238 239# test of full window calendar control functions 240 241class CalendFrame(wx.Frame): 242 def __init__(self, parent, id, title, log): 243 wx.Frame.__init__(self, parent, id, title, size=(400, 400), 244 style=wx.DEFAULT_FRAME_STYLE|wx.NO_FULL_REPAINT_ON_RESIZE) 245 246 self.Bind(wx.EVT_CLOSE, self.OnCloseWindow) 247 248 self.log = log 249 self.CreateStatusBar() 250 self.mainmenu = wx.MenuBar() 251 menu = wx.Menu() 252 253 menu = self.MakeFileMenu() 254 self.mainmenu.Append(menu, '&File') 255 256 self.MakeToolMenu() # toolbar 257 258 self.SetMenuBar(self.mainmenu) 259 self.calend = wx.lib.calendar.Calendar(self, -1) 260 self.calend.SetCurrentDay() 261 self.calend.grid_color = 'BLUE' 262 self.calend.SetBusType() 263# self.calend.ShowWeekEnd() 264 265 self.ResetDisplay() 266 267 self.Bind(wx.lib.calendar.EVT_CALENDAR, self.MouseClick, self.calend) 268 269 def MouseClick(self, evt): 270 text = '%s CLICK %02d/%02d/%d' % (evt.click, evt.day, evt.month, evt.year) # format date 271 self.log.WriteText('Date Selected: ' + text + '\n') 272 273 def OnCloseWindow(self, event): 274 self.Destroy() 275 276 def ResetDisplay(self): 277 month = self.calend.GetMonth() 278 279 try: 280 set_days = test_days[month] 281 except: 282 set_days = [1, 5, 12] 283 284 self.calend.AddSelect([2, 16], 'GREEN', 'WHITE') 285 286 self.calend.SetSelDay(set_days) 287 self.calend.Refresh() 288 289 def OnIncYear(self, event): 290 self.calend.IncYear() 291 self.ResetDisplay() 292 293 def OnDecYear(self, event): 294 self.calend.DecYear() 295 self.ResetDisplay() 296 297 def OnIncMonth(self, event): 298 self.calend.IncMonth() 299 self.ResetDisplay() 300 301 def OnDecMonth(self, event): 302 self.calend.DecMonth() 303 self.ResetDisplay() 304 305 def OnCurrent(self, event): 306 self.calend.SetCurrentDay() 307 self.ResetDisplay() 308 309 def MakeFileMenu(self): 310 menu = wx.Menu() 311 312 mID = wx.NewIdRef() 313 menu.Append(mID, 'Decrement', 'Next') 314 self.Bind(wx.EVT_MENU, self.OnDecMonth, id=mID) 315 316 mID = wx.NewIdRef() 317 menu.Append(mID, 'Increment', 'Dec') 318 self.Bind(wx.EVT_MENU, self.OnIncMonth, id=mID) 319 320 menu.AppendSeparator() 321 322 mID = wx.NewIdRef() 323 menu.Append(mID, 'E&xit', 'Exit') 324 self.Bind(wx.EVT_MENU, self.OnCloseWindow, id=mID) 325 326 return menu 327 328 def MakeToolMenu(self): 329 tb = self.CreateToolBar(wx.TB_HORIZONTAL|wx.NO_BORDER) 330 331 mID = wx.NewIdRef() 332 SetToolPath(self, tb, mID, images.DbDec.GetBitmap(), 'Dec Year') 333 self.Bind(wx.EVT_TOOL, self.OnDecYear, id=mID) 334 335 mID = wx.NewIdRef() 336 SetToolPath(self, tb, mID, images.Dec.GetBitmap(), 'Dec Month') 337 self.Bind(wx.EVT_TOOL, self.OnDecMonth, id=mID) 338 339 mID = wx.NewIdRef() 340 SetToolPath(self, tb, mID, images.Pt.GetBitmap(), 'Current Month') 341 self.Bind(wx.EVT_TOOL, self.OnCurrent, id=mID) 342 343 mID = wx.NewIdRef() 344 SetToolPath(self, tb, mID, images.Inc.GetBitmap(), 'Inc Month') 345 self.Bind(wx.EVT_TOOL, self.OnIncMonth, id=mID) 346 347 mID = wx.NewIdRef() 348 SetToolPath(self, tb, mID, images.DbInc.GetBitmap(), 'Inc Year') 349 self.Bind(wx.EVT_TOOL, self.OnIncYear, id=mID) 350 351 tb.Realize() 352 353#--------------------------------------------------------------------------- 354 355# example class for printing/previewing calendars 356 357class PrintCalend: 358 def __init__(self, parent, month, year): 359 self.frame = parent 360 self.month = month 361 self.year = year 362 363 self.SetParms() 364 self.SetCal() 365 self.printData = wx.PrintData() 366 367 def SetCal(self): 368 self.grid_color = 'BLUE' 369 self.back_color = 'WHITE' 370 self.sel_color = 'RED' 371 self.high_color = 'LIGHT BLUE' 372 self.font = wx.FONTFAMILY_SWISS 373 self.bold = wx.FONTWEIGHT_NORMAL 374 375 self.sel_key = None # last used by 376 self.sel_lst = [] # highlighted selected days 377 378 self.size = None 379 self.hide_title = False 380 self.hide_grid = False 381 self.set_day = None 382 383 def SetParms(self): 384 self.ymax = 1 385 self.xmax = 1 386 self.page = 1 387 self.total_pg = 1 388 389 self.preview = None 390 self.scale = 1.0 391 392 self.pagew = 8.5 393 self.pageh = 11.0 394 395 self.txt_marg = 0.1 396 self.lf_marg = 0 397 self.top_marg = 0 398 399 self.page = 0 400 401 def SetDates(self, month, year): 402 self.month = month 403 self.year = year 404 405 def SetStyleDef(self, desc): 406 self.style = desc 407 408 def SetCopies(self, copies): # number of copies of label 409 self.copies = copies 410 411 def SetStart(self, start): # start position of label 412 self.start = start 413 414 def Preview(self): 415 printout = SetPrintout(self) 416 printout2 = SetPrintout(self) 417 self.preview = wx.PrintPreview(printout, printout2, self.printData) 418 419 if not self.preview.IsOk(): 420 wx.MessageBox("There was a problem printing!", "Printing", wx.OK) 421 return 422 423 self.preview.SetZoom(60) # initial zoom value 424 425 frame = wx.PreviewFrame(self.preview, self.frame, "Print preview") 426 427 frame.Initialize() 428 frame.SetPosition(self.frame.GetPosition()) 429 frame.SetSize(self.frame.GetSize()) 430 frame.Show(True) 431 432 def Print(self): 433 pdd = wx.PrintDialogData() 434 pdd.SetPrintData(self.printData) 435 printer = wx.Printer(pdd) 436 printout = SetPrintout(self) 437 frame = wx.Frame(None, -1, "Test") 438 439 if not printer.Print(frame, printout): 440 wx.MessageBox("There was a problem printing.\nPerhaps your current printer is not set correctly?", "Printing", wx.OK) 441 else: 442 self.printData = printer.GetPrintDialogData().GetPrintData() 443 444 printout.Destroy() 445 446 def DoDrawing(self, DC): 447 size = DC.GetSize() 448 449 cal = wx.lib.calendar.PrtCalDraw(self) 450 451 if self.preview is None: 452 cal.SetPSize(size[0]/self.pagew, size[1]/self.pageh) 453 cal.SetPreview(False) 454 455 else: 456 if self.preview == 1: 457 cal.SetPSize(size[0]/self.pagew, size[1]/self.pageh) 458 else: 459 cal.SetPSize(self.pwidth, self.pheight) 460 461 cal.SetPreview(self.preview) 462 463 cal.hide_title = self.hide_title # set the calendar parameters 464 cal.hide_grid = self.hide_grid 465 466 cal.grid_color = self.grid_color 467 cal.high_color = self.high_color 468 cal.back_color = self.back_color 469 cal.outer_border = False 470 cal.font = self.font 471 cal.bold = self.bold 472 473 cal_size = (3.0, 3.0) 474 cal.SetSize(cal_size) 475 476 year, month = self.year, self.month 477 478 x = 0.5 479 for i in range(2): 480 y = 0.5 481 482 for j in range(3): 483 cal.SetCal(year, month) # current month 484 cal.SetPos(x, y) 485 486 try: 487 set_days = test_days[month] 488 except: 489 set_days = [1, 5, 12] 490 491 cal.AddSelect([2, 16], 'GREEN', 'WHITE') 492 493 cal.DrawCal(DC, set_days) 494 495 year, month = self.IncMonth(year, month) 496 y = y + 3.5 497 498 x = x + 4.0 # next column 499 500 self.ymax = DC.MaxY() 501 self.xmax = DC.MaxX() 502 503 def IncMonth(self, year, month): # next month 504 month = month + 1 505 506 if month > 12: 507 month = 1 508 year = year + 1 509 510 return year, month 511 512 def GetTotalPages(self): 513 self.pg_cnt = 1 514 return self.pg_cnt 515 516 def SetPage(self, page): 517 self.page = page 518 519 def SetPageSize(self, width, height): 520 self.pwidth, self.pheight = width, height 521 522 def SetTotalSize(self, width, height): 523 self.ptwidth, self.ptheight = width, height 524 525 def SetPreview(self, preview, scale): 526 self.preview = preview 527 self.scale = scale 528 529 def SetTotalSize(self, width, height): 530 self.ptwidth = width 531 self.ptheight = height 532 533def SetToolPath(self, tb, id, bmp, title): 534 tb.AddSimpleTool(id, bmp, title, title) 535 536class SetPrintout(wx.Printout): 537 def __init__(self, canvas): 538 wx.Printout.__init__(self) 539 self.canvas = canvas 540 self.end_pg = 1 541 542 def OnBeginDocument(self, start, end): 543 return super(SetPrintout, self).OnBeginDocument(start, end) 544 545 def OnEndDocument(self): 546 super(SetPrintout, self).OnEndDocument() 547 548 def HasPage(self, page): 549 if page <= self.end_pg: 550 return True 551 else: 552 return False 553 554 def GetPageInfo(self): 555 self.end_pg = self.canvas.GetTotalPages() 556 str_pg = 1 557 558 try: 559 end_pg = self.end_pg 560 except: 561 end_pg = 1 562 563 return (str_pg, end_pg, str_pg, end_pg) 564 565 def OnPreparePrinting(self): 566 super(SetPrintout, self).OnPreparePrinting() 567 568 def OnBeginPrinting(self): 569 dc = self.GetDC() 570 571 self.preview = self.IsPreview() 572 573 if (self.preview): 574 self.pixelsPerInch = self.GetPPIScreen() 575 else: 576 self.pixelsPerInch = self.GetPPIPrinter() 577 578 (w, h) = dc.GetSize() 579 scaleX = float(w) / 1000 580 scaleY = float(h) / 1000 581 self.printUserScale = min(scaleX, scaleY) 582 583 super(SetPrintout, self).OnBeginPrinting() 584 585 def GetSize(self): 586 self.psizew, self.psizeh = self.GetPPIPrinter() 587 return self.psizew, self.psizeh 588 589 def GetTotalSize(self): 590 self.ptsizew, self.ptsizeh = self.GetPageSizePixels() 591 return self.ptsizew, self.ptsizeh 592 593 def OnPrintPage(self, page): 594 dc = self.GetDC() 595 (w, h) = dc.GetSize() 596 scaleX = float(w) / 1000 597 scaleY = float(h) / 1000 598 self.printUserScale = min(scaleX, scaleY) 599 dc.SetUserScale(self.printUserScale, self.printUserScale) 600 601 self.preview = self.IsPreview() 602 603 self.canvas.SetPreview(self.preview, self.printUserScale) 604 self.canvas.SetPage(page) 605 606 self.ptsizew, self.ptsizeh = self.GetPageSizePixels() 607 self.canvas.SetTotalSize(self.ptsizew, self.ptsizeh) 608 609 self.psizew, self.psizeh = self.GetPPIPrinter() 610 self.canvas.SetPageSize(self.psizew, self.psizeh) 611 612 self.canvas.DoDrawing(dc) 613 return True 614 615class MyApp(wx.App): 616 def OnInit(self): 617 frame = CalendFrame(None, -1, "Test Calendar", log) 618 frame.Show(True) 619 self.SetTopWindow(frame) 620 return True 621 622#--------------------------------------------------------------------------- 623 624def MessageDlg(self, message, type = 'Message'): 625 dlg = wx.MessageDialog(self, message, type, wx.OK | wx.ICON_INFORMATION) 626 dlg.ShowModal() 627 dlg.Destroy() 628 629#--------------------------------------------------------------------------- 630 631def runTest(frame, nb, log): 632 win = TestPanel(nb, log, frame) 633 return win 634 635#--------------------------------------------------------------------------- 636 637 638overview = """\ 639This control provides a Calendar control class for displaying and selecting dates. 640In addition, the class is extended and can be used for printing/previewing. 641 642Additional features include weekend highlighting and business type Monday-Sunday 643format. 644 645See example for various methods used to set display month, year, and highlighted 646dates (different font and background colours). 647 648by Lorne White 649 650""" 651 652 653 654 655if __name__ == '__main__': 656 import sys,os 657 import run 658 run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:]) 659 660