1 #---------------------------------------------------------------------------- 
   3 # Purpose:      Calendar display control 
   5 # Author:       Lorne White (email: lorne.white@telusplanet.net) 
  10 # Licence:      wxWindows license 
  11 #---------------------------------------------------------------------------- 
  12 # 12/01/2003 - Jeff Grimmett (grimmtooth@softhome.net) 
  14 # o Updated for wx namespace 
  15 # o Tested with updated demo 
  16 # o Added new event type EVT_CALENDAR. The reason for this is that the original 
  17 #   library used a hardcoded ID of 2100 for generating events. This makes it 
  18 #   very difficult to fathom when trying to decode the code since there's no 
  19 #   published API. Creating the new event binder might seem like overkill -  
  20 #   after all, you might ask, why not just use a new event ID and be done with 
  21 #   it? However, a consistent interface is very useful at times; also it makes 
  22 #   it clear that we're not just hunting for mouse clicks -- we're hunting 
  23 #   wabbit^H^H^H^H (sorry bout that) for calender-driven mouse clicks. So 
  24 #   that's my sad story. Shoot me if you must :-) 
  25 # o There's still one deprecation warning buried in here somewhere, but I  
  26 #   haven't been able to find it yet. It only occurs when displaying a  
  27 #   print preview, and only the first time. It *could* be an error in the 
  30 #   Here's the traceback: 
  32 #   C:\Python\lib\site-packages\wx\core.py:949: DeprecationWarning:  
  33 #       integer argument expected, got float 
  34 #   newobj = _core.new_Rect(*args, **kwargs) 
  36 # 12/17/2003 - Jeff Grimmett (grimmtooth@softhome.net) 
  38 # o A few style-guide nips and tucks 
  39 # o Renamed wxCalendar to Calendar 
  40 # o Couple of bugfixes 
  47 CalDays 
= [6, 0, 1, 2, 3, 4, 5] 
  48 AbrWeekday 
= {6:"Sun", 0:"Mon", 1:"Tue", 2:"Wed", 3:"Thu", 4:"Fri", 5:"Sat"}
 
  51 BusCalDays 
= [0, 1, 2, 3, 4, 5, 6] 
  53 # Calendar click event - added 12/1/03 by jmg (see above) 
  54 wxEVT_COMMAND_PYCALENDAR_DAY_CLICKED 
= wx
.NewEventType() 
  55 EVT_CALENDAR 
= wx
.PyEventBinder(wxEVT_COMMAND_PYCALENDAR_DAY_CLICKED
, 1) 
  62             monthlist
.append(name
) 
  65 # calendar drawing routing 
  68     def __init__(self
, parent
): 
  72             self
.scale 
= parent
.scale
 
  79         self
.num_auto 
= True    # auto scale of the cal number day size 
  80         self
.num_size 
= 12      # default size of calendar if no auto size 
  81         self
.max_num_size 
= 12  # maximum size for calendar number 
  83         self
.num_align_horz 
= wx
.ALIGN_CENTRE    
# alignment of numbers 
  84         self
.num_align_vert 
= wx
.ALIGN_CENTRE
 
  85         self
.num_indent_horz 
= 0     # points indent from position, used to offset if not centered 
  86         self
.num_indent_vert 
= 0 
  88         self
.week_auto 
= True       # auto scale of week font text 
  90         self
.max_week_size 
= 12 
  92         self
.grid_color 
= 'BLACK'       # grid and selection colors 
  93         self
.back_color 
= 'WHITE' 
  94         self
.sel_color 
= 'RED' 
  96         self
.high_color 
= 'LIGHT BLUE' 
  97         self
.border_color 
= 'BLACK' 
  98         self
.week_color 
= 'LIGHT GREY' 
 100         self
.week_font_color 
= 'BLACK'      # font colors 
 101         self
.day_font_color 
= 'BLACK' 
 104         self
.bold 
= wx
.NORMAL
 
 106         self
.hide_title 
= False 
 107         self
.hide_grid 
= False 
 108         self
.outer_border 
= True 
 110         self
.title_offset 
= 0 
 111         self
.cal_week_scale 
= 0.7 
 112         self
.show_weekend 
= False 
 113         self
.cal_type 
= "NORMAL" 
 115     def SetWeekColor(self
, font_color
, week_color
):     # set font and background color for week title 
 116         self
.week_font_color 
= font_color
 
 117         self
.week_color 
= week_color
 
 119     def SetSize(self
, size
): 
 120         self
.set_sizew 
= size
[0] 
 121         self
.set_sizeh 
= size
[1] 
 123     def InitValues(self
):       # default dimensions of various elements of the calendar 
 126         self
.set_cy_st 
= 0      # start position 
 129         self
.set_y_mrg 
= 15      # start of vertical draw default 
 133     def SetPos(self
, xpos
, ypos
): 
 134         self
.set_cx_st 
= xpos
 
 135         self
.set_cy_st 
= ypos
 
 137     def SetMarg(self
, xmarg
, ymarg
): 
 138         self
.set_x_st 
= xmarg
 
 139         self
.set_y_st 
= ymarg
 
 140         self
.set_y_end 
= ymarg
 
 142     def InitScale(self
):        # scale position values 
 143         self
.sizew 
= int(self
.set_sizew 
* self
.pwidth
) 
 144         self
.sizeh 
= int(self
.set_sizeh 
* self
.pheight
) 
 146         self
.cx_st 
= int(self
.set_cx_st 
* self
.pwidth
)       # draw start position 
 147         self
.cy_st 
= int(self
.set_cy_st 
* self
.pheight
) 
 149         self
.x_mrg 
= int(self
.set_x_mrg 
* self
.pwidth
)         # calendar draw margins 
 150         self
.y_mrg 
= int(self
.set_y_mrg 
* self
.pheight
) 
 151         self
.y_end 
= int(self
.set_y_end 
* self
.pheight
) 
 153     def DrawCal(self
, DC
, sel_lst
=[]): 
 159         if self
.hide_title 
is False: 
 167         if self
.show_weekend 
is True:       # highlight weekend dates 
 170         self
.AddSelect(sel_lst
)     # overrides the weekend highlight 
 172         self
.DrawSel()      # highlighted days 
 176     def AddSelect(self
, list, cfont
=None, cbackgrd 
= None): 
 178             cfont 
= self
.sel_color      
# font digit color 
 181             cbackgrd 
= self
.high_color     
# select background color 
 184             self
.cal_sel
[val
] = (cfont
, cbackgrd
) 
 186     # draw border around the outside of the main display rectangle 
 187     def DrawBorder(self
):    
 188         brush 
= wx
.Brush(wx
.NamedColour(self
.back_color
), wx
.SOLID
) 
 189         self
.DC
.SetBrush(brush
) 
 190         self
.DC
.SetPen(wx
.Pen(wx
.NamedColour(self
.border_color
), 1)) 
 192         if self
.outer_border 
is True: 
 193             # full display window area 
 194             rect 
= wx
.Rect(self
.cx_st
, self
.cy_st
, self
.sizew
, self
.sizeh
)   
 195             self
.DC
.DrawRectangleRect(rect
) 
 197     def DrawNumVal(self
): 
 200     # calculate the calendar days and offset position 
 202     def SetCal(self
, year
, month
): 
 203         self
.InitValues()       # reset initial values 
 209         t 
= Date(year
, month
, day
) 
 210         dow 
= self
.dow 
= t
.day_of_week     
# start day in month 
 211         dim 
= self
.dim 
= t
.days_in_month   
# number of days in month 
 213         if self
.cal_type 
== "NORMAL": 
 218         self
.st_pos 
= start_pos
 
 221         for i 
in range(start_pos
): 
 226             self
.cal
.append(str(i
)) 
 231     def SetWeekEnd(self
, font_color
='BLACK', backgrd 
= 'LIGHT GREY'): 
 232         date 
= 6 - int(self
.dow
)     # start day of first saturday 
 234         while date 
<= self
.dim
: 
 235             self
.cal_sel
[date
] = (font_color
, backgrd
)  # Saturday 
 239                 self
.cal_sel
[date
] = (font_color
, backgrd
)      # Sunday 
 244     # get the display rectange list of the day grid 
 247         for y 
in self
.gridy
[1:-1]: 
 248             for x 
in self
.gridx
[:-1]: 
 249                 assert type(y
) == int 
 250                 assert type(x
) == int 
 251                 rect 
= wx
.Rect(x
, y
, self
.dl_w
, self
.dl_h
)  # create rect region 
 263     # month and year title 
 265         month 
= Month
[self
.month
] 
 268         if self
.sizeh 
< _MIDSIZE
: 
 271         f 
= wx
.Font(sizef
, self
.font
, wx
.NORMAL
, self
.bold
) 
 274         tw
,th 
= self
.DC
.GetTextExtent(month
) 
 275         adjust 
= self
.cx_st 
+ (self
.sizew
-tw
)/2 
 276         self
.DC
.DrawText(month
, (adjust
, self
.cy_st 
+ th
)) 
 278         year 
= str(self
.year
) 
 279         tw
,th 
= self
.DC
.GetTextExtent(year
) 
 280         adjust 
=  self
.sizew 
- tw 
- self
.x_mrg
 
 282         self
.title_offset 
= th 
* 2 
 284         f 
= wx
.Font(sizef
, self
.font
, wx
.NORMAL
, self
.bold
) 
 286         self
.DC
.DrawText(year
, (self
.cx_st 
+ adjust
, self
.cy_st 
+ th
)) 
 288     def DrawWeek(self
):     # draw the week days 
 289         width 
= self
.gridx
[1]-self
.gridx
[0] 
 290         height 
= self
.gridy
[1] - self
.gridy
[0] 
 291         rect_w 
= self
.gridx
[7]-self
.gridx
[0] 
 293         f 
= wx
.Font(10, self
.font
, wx
.NORMAL
, self
.bold
)      # initial font setting 
 295         if self
.week_auto 
== True: 
 296             test_size 
= self
.max_week_size      
# max size 
 299                 f
.SetPointSize(test_size
) 
 301                 tw
,th 
= self
.DC
.GetTextExtent(test_day
) 
 303                 if tw 
< width 
and th 
< height
: 
 306                 test_size 
= test_size 
- 1 
 308             f
.SetPointSize(self
.week_size
)   # set fixed size 
 311         self
.DC
.SetTextForeground(wx
.NamedColour(self
.week_font_color
)) 
 316         brush 
= wx
.Brush(wx
.NamedColour(self
.week_color
), wx
.SOLID
) 
 317         self
.DC
.SetBrush(brush
) 
 318         self
.DC
.DrawRectangle((self
.gridx
[0], self
.gridy
[0]), (rect_w
+1, height
)) 
 320         if self
.cal_type 
== "NORMAL": 
 323             cal_days 
= BusCalDays
 
 326             day 
= AbrWeekday
[val
] 
 331             dw
,dh 
= self
.DC
.GetTextExtent(day
) 
 333             diffy 
= (height
-dh
)/2 
 335             x 
= self
.gridx
[cnt_x
] 
 336             y 
= self
.gridy
[cnt_y
] 
 337             self
.DC
.DrawRectangle((self
.gridx
[cnt_x
], self
.gridy
[0]), (width
+1, height
)) 
 338             self
.DC
.DrawText(day
, (x
+diffx
, y
+diffy
)) 
 341     # draw the day numbers 
 343         f 
= wx
.Font(10, self
.font
, wx
.NORMAL
, self
.bold
)      # initial font setting 
 345         if self
.num_auto 
== True: 
 346             test_size 
= self
.max_num_size      
# max size 
 350                 f
.SetPointSize(test_size
) 
 352                 tw
,th 
= self
.DC
.GetTextExtent(test_day
) 
 354                 if tw 
< self
.dl_w 
and th 
< self
.dl_h
: 
 357                 test_size 
= test_size 
- 1 
 359             f
.SetPointSize(self
.num_size
)   # set fixed size 
 365             x 
= self
.gridx
[cnt_x
] 
 366             y 
= self
.gridy
[cnt_y
] 
 370                 num_color 
= self
.cal_sel
[num_val
][0] 
 372                 num_color 
= self
.day_font_color
 
 374             self
.DC
.SetTextForeground(wx
.NamedColour(num_color
)) 
 377             tw
,th 
= self
.DC
.GetTextExtent(val
) 
 379             if self
.num_align_horz 
== wx
.ALIGN_CENTRE
: 
 380                 adj_h 
= (self
.dl_w 
- tw
)/2 
 381             elif self
.num_align_horz 
== wx
.ALIGN_RIGHT
: 
 382                 adj_h 
= self
.dl_w 
- tw
 
 384                 adj_h 
= 0   # left alignment 
 386             adj_h 
= adj_h 
+ self
.num_indent_horz
 
 388             if self
.num_align_vert 
== wx
.ALIGN_CENTRE
: 
 389                 adj_v 
= (self
.dl_h 
- th
)/2 
 390             elif self
.num_align_horz 
== wx
.ALIGN_RIGHT
: 
 391                 adj_v 
= self
.dl_h 
- th
 
 393                 adj_v 
= 0   # left alignment 
 395             adj_v 
= adj_v 
+ self
.num_indent_vert
 
 397             self
.DC
.DrawText(val
, (x
+adj_h
, y
+adj_v
)) 
 405     # calculate the dimensions in the center of the drawing area 
 408         bdh 
= self
.y_mrg 
+ self
.y_end 
+ self
.title_offset
 
 410         self
.dl_w 
= int((self
.sizew
-bdw
)/7) 
 411         self
.dl_h 
= int((self
.sizeh
-bdh
)/7) 
 413         # week title adjustment 
 414         self
.dl_th 
= int(self
.dl_h
*self
.cal_week_scale
) 
 415         self
.cwidth 
= self
.dl_w 
* 7 
 416         self
.cheight 
= self
.dl_h 
* 6 + self
.dl_th
 
 418     # highlighted selected days 
 420         for key 
in self
.cal_sel
.keys(): 
 421             sel_color 
= self
.cal_sel
[key
][1] 
 422             brush 
= wx
.Brush(wx
.NamedColour(sel_color
), wx
.SOLID
) 
 423             self
.DC
.SetBrush(brush
) 
 425             if self
.hide_grid 
is False: 
 426                 self
.DC
.SetPen(wx
.Pen(wx
.NamedColour(self
.grid_color
), 0)) 
 428                 self
.DC
.SetPen(wx
.Pen(wx
.NamedColour(self
.back_color
), 0)) 
 430             nkey 
= key 
+ self
.st_pos 
-1 
 432             self
.DC
.DrawRectangle((rect
.x
, rect
.y
), (rect
.width
+1, rect
.height
+1)) 
 434     # calculate and draw the grid lines 
 436         self
.DC
.SetPen(wx
.Pen(wx
.NamedColour(self
.grid_color
), 0)) 
 441         self
.x_st 
= self
.cx_st 
+ self
.x_mrg
 
 442         # start postion of draw 
 443         self
.y_st 
= self
.cy_st 
+ self
.y_mrg 
+ self
.title_offset
 
 447         y2 
= y1 
+ self
.cheight
 
 450             if self
.hide_grid 
is False: 
 451                 self
.DC
.DrawLine((x1
, y1
), (x1
, y2
)) 
 452             self
.gridx
.append(x1
) 
 457         x2 
= x1 
+ self
.cwidth
 
 460             if self
.hide_grid 
is False: 
 461                 self
.DC
.DrawLine((x1
, y1
), (x2
, y1
)) 
 463             self
.gridy
.append(y1
) 
 471 class PrtCalDraw(CalDraw
): 
 472     def InitValues(self
): 
 475         # start draw border location 
 479         # draw offset position 
 484     # calculate the dimensions in the center of the drawing area 
 485     def SetPSize(self
, pwidth
, pheight
):     
 486         self
.pwidth 
= int(pwidth
)/self
.scale
 
 487         self
.pheight 
= int(pheight
)/self
.scale
 
 489     def SetPreview(self
, preview
): 
 490         self
.preview 
= preview
 
 492 class Calendar(wx
.Window
): 
 493     def __init__(self
, parent
, id, pos
=wx
.DefaultPosition
, size
=wx
.DefaultSize
): 
 494         wx
.Window
.__init
__(self
, parent
, id, pos
, size
) 
 496         # set the calendar control attributes 
 498         self
.grid_color 
= 'BLACK' 
 499         self
.back_color 
= 'WHITE' 
 500         self
.hide_grid 
= False 
 501         self
.sel_color 
= 'RED' 
 502         self
.hide_title 
= False 
 503         self
.show_weekend 
= False 
 504         self
.cal_type 
= "NORMAL" 
 507         self
.week_color 
= 'LIGHT GREY' 
 508         self
.week_font_color 
= 'BLACK'       
 510         self
.select_list 
= [] 
 512         self
.SetBackgroundColour(self
.back_color
) 
 513         self
.Bind(wx
.EVT_LEFT_DOWN
, self
.OnLeftEvent
) 
 514         self
.Bind(wx
.EVT_LEFT_DCLICK
, self
.OnLeftDEvent
) 
 515         self
.Bind(wx
.EVT_RIGHT_DOWN
, self
.OnRightEvent
) 
 516         self
.Bind(wx
.EVT_RIGHT_DCLICK
, self
.OnRightDEvent
) 
 518         self
.sel_key 
= None      #  last used by 
 519         self
.sel_lst 
= []        # highlighted selected days 
 521         # default calendar for current month 
 527         self
.Bind(wx
.EVT_PAINT
, self
.OnPaint
) 
 528         self
.Bind(wx
.EVT_SIZE
, self
.OnSize
) 
 530     # control some of the main calendar attributes 
 533         self
.hide_title 
= True 
 536         self
.hide_grid 
= True 
 538     # determine the calendar rectangle click area and draw a selection 
 540     def ProcessClick(self
, event
): 
 541         self
.x
, self
.y 
= event
.GetX(), event
.GetY() 
 542         key 
= self
.GetDayHit(self
.x
, self
.y
) 
 545     # tab mouse click events and process 
 547     def OnLeftEvent(self
, event
): 
 549         self
.shiftkey 
= event
.ShiftDown() 
 550         self
.ctrlkey 
= event
.ControlDown() 
 551         self
.ProcessClick(event
) 
 553     def OnLeftDEvent(self
, event
): 
 555         self
.ProcessClick(event
) 
 557     def OnRightEvent(self
, event
): 
 559         self
.ProcessClick(event
) 
 561     def OnRightDEvent(self
, event
): 
 562         self
.click 
= 'DRIGHT' 
 563         self
.ProcessClick(event
) 
 565     def SetSize(self
, set_size
): 
 568     def SetSelDay(self
, sel
): 
 569         # list of highlighted days 
 572     # get the current date 
 575         self
.month 
= dt
.month
 
 579     # set the current day 
 580     def SetCurrentDay(self
): 
 582         self
.set_day 
= self
.day
 
 584     # get the date, day, month, year set in calendar 
 587         return self
.day
, self
.month
, self
.year
 
 598     # set the day, month, and year 
 600     def SetDayValue(self
, day
): 
 603     def SetMonth(self
, month
): 
 604         if month 
>= 1 and month 
<= 12: 
 610     def SetYear(self
, year
): 
 613     # increment year and month 
 616         self
.year 
= self
.year 
+ 1 
 620         self
.year 
= self
.year 
- 1 
 624         self
.month 
= self
.month 
+ 1 
 627             self
.year 
= self
.year 
+ 1 
 631         self
.month 
= self
.month 
- 1 
 634             self
.year 
= self
.year 
- 1 
 637     # test to see if the selection has a date and create event 
 639     def TestDay(self
, key
): 
 641             self
.day 
= int(self
.cal
[key
]) 
 647             # Changed 12/1/03 by jmg (see above) to support 2.5 event binding 
 648             evt 
= wx
.PyCommandEvent(wxEVT_COMMAND_PYCALENDAR_DAY_CLICKED
, self
.GetId()) 
 649             evt
.click
, evt
.day
, evt
.month
, evt
.year 
= self
.click
, self
.day
, self
.month
, self
.year
 
 650             evt
.shiftkey 
= self
.shiftkey
 
 651             evt
.ctrlkey 
= self
.ctrlkey
 
 652             self
.GetEventHandler().ProcessEvent(evt
) 
 654             self
.set_day 
= self
.day
 
 657     # find the clicked area rectangle 
 659     def GetDayHit(self
, mx
, my
): 
 660         for key 
in self
.rg
.keys(): 
 662             ms_rect 
= wx
.Rect(mx
, my
, 1, 1) 
 663             if wx
.IntersectRect(ms_rect
, val
) is not None: 
 664                 result 
= self
.TestDay(key
) 
 671     def SetWeekColor(self
, font_color
, week_color
):      
 672         # set font and background color for week title 
 673         self
.week_font_color 
= font_color
 
 674         self
.week_color 
= week_color
 
 676     def AddSelect(self
, list, font_color
, back_color
): 
 677         list_val 
= [list, font_color
, back_color
] 
 678         self
.select_list
.append(list_val
) 
 680     def ShowWeekEnd(self
): 
 682         self
.show_weekend 
= True 
 684     def SetBusType(self
): 
 685         self
.cal_type 
= "BUS" 
 687     def OnSize(self
, evt
): 
 691     def OnPaint(self
, event
): 
 692         DC 
= wx
.PaintDC(self
) 
 695     def DoDrawing(self
, DC
): 
 696         DC 
= wx
.PaintDC(self
) 
 699         self
.cal 
= cal 
= CalDraw(self
) 
 701         cal
.grid_color 
= self
.grid_color
 
 702         cal
.back_color 
= self
.back_color
 
 703         cal
.hide_grid 
= self
.hide_grid
 
 704         cal
.grid_color 
= self
.grid_color
 
 705         cal
.hide_title 
= self
.hide_title
 
 706         cal
.show_weekend 
= self
.show_weekend
 
 707         cal
.cal_type 
= self
.cal_type
 
 709         if self
.size 
is None: 
 710             size 
= self
.GetClientSize() 
 716         cal
.week_font_color 
= self
.week_font_color
 
 717         cal
.week_color 
= self
.week_color
 
 720         cal
.SetCal(self
.year
, self
.month
) 
 722         for val 
in self
.select_list
: 
 723             cal
.AddSelect(val
[0], val
[1], val
[2]) 
 725         cal
.DrawCal(DC
, self
.sel_lst
) 
 727         self
.rg 
= cal
.GetRect() 
 728         self
.cal 
= cal
.GetCal() 
 729         self
.st_pos 
= cal
.GetOffset() 
 730         self
.ymax 
= DC
.MaxY() 
 732         if self
.set_day 
!= None: 
 733             self
.SetDay(self
.set_day
) 
 737     # draw the selection rectangle 
 738     def DrawRect(self
, key
, color 
= 'BLACK', width 
= 0): 
 742         DC 
= wx
.ClientDC(self
) 
 745         brush 
= wx
.Brush(wx
.Colour(0, 0xFF, 0x80), wx
.TRANSPARENT
) 
 747         DC
.SetPen(wx
.Pen(wx
.NamedColour(color
), width
)) 
 750         DC
.DrawRectangle((rect
.x
, rect
.y
), (rect
.width
+1, rect
.height
+1)) 
 754     # set the day selection 
 756     def SetDay(self
, day
): 
 757         day 
= day 
+ self
.st_pos 
- 1 
 760     def SelectDay(self
, key
): 
 762         # clear large selection 
 763         self
.DrawRect(self
.sel_key
, self
.back_color
, sel_size
) 
 765         if self
.hide_grid 
is False: 
 766             self
.DrawRect(self
.sel_key
, self
.grid_color
) 
 768         self
.DrawRect(key
, self
.sel_color
, sel_size
) 
 771         self
.select_day 
= None 
 776 class CalenDlg(wx
.Dialog
): 
 777     def __init__(self
, parent
, month
=None, day 
= None, year
=None): 
 778         wx
.Dialog
.__init
__(self
, parent
, -1, "Event Calendar", wx
.DefaultPosition
, (280, 360)) 
 780         # set the calendar and attributes 
 781         self
.calend 
= Calendar(self
, -1, (20, 60), (240, 200)) 
 784             self
.calend
.SetCurrentDay() 
 785             start_month 
= self
.calend
.GetMonth() 
 786             start_year 
= self
.calend
.GetYear() 
 788             self
.calend
.month 
= start_month 
= month
 
 789             self
.calend
.year 
= start_year 
= year
 
 790             self
.calend
.SetDayValue(day
) 
 792         self
.calend
.HideTitle() 
 795         # get month list from DateTime 
 796         monthlist 
= GetMonthList() 
 799         self
.date 
= wx
.ComboBox(self
, -1, Month
[start_month
], (20, 20), (90, -1),  
 800                                 monthlist
, wx
.CB_DROPDOWN
) 
 801         self
.Bind(wx
.EVT_COMBOBOX
, self
.EvtComboBox
, self
.date
) 
 803         # alternate spin button to control the month 
 804         h 
= self
.date
.GetSize().height
 
 805         self
.m_spin 
= wx
.SpinButton(self
, -1, (130, 20), (h
*2, h
), wx
.SP_VERTICAL
) 
 806         self
.m_spin
.SetRange(1, 12) 
 807         self
.m_spin
.SetValue(start_month
) 
 808         self
.Bind(wx
.EVT_SPIN
, self
.OnMonthSpin
, self
.m_spin
) 
 810         # spin button to control the year 
 811         self
.dtext 
= wx
.TextCtrl(self
, -1, str(start_year
), (160, 20), (60, -1)) 
 812         h 
= self
.dtext
.GetSize().height
 
 814         self
.y_spin 
= wx
.SpinButton(self
, -1, (220, 20), (h
*2, h
), wx
.SP_VERTICAL
) 
 815         self
.y_spin
.SetRange(1980, 2010) 
 816         self
.y_spin
.SetValue(start_year
) 
 818         self
.Bind(wx
.EVT_SPIN
, self
.OnYrSpin
, self
.y_spin
) 
 819         self
.Bind(EVT_CALENDAR
, self
.MouseClick
, self
.calend
) 
 825         btn 
= wx
.Button(self
, -1, ' Ok ', (x_pos
, y_pos
), but_size
) 
 826         self
.Bind(wx
.EVT_BUTTON
, self
.OnOk
, btn
) 
 828         btn 
= wx
.Button(self
, -1, ' Close ', (x_pos 
+ 120, y_pos
), but_size
) 
 829         self
.Bind(wx
.EVT_BUTTON
, self
.OnCancel
, btn
) 
 831     def OnOk(self
, event
): 
 832         self
.EndModal(wx
.ID_OK
) 
 834     def OnCancel(self
, event
): 
 835         self
.EndModal(wx
.ID_CANCEL
) 
 837     # log the mouse clicks 
 838     def MouseClick(self
, evt
): 
 839         self
.month 
= evt
.month
 
 840         # result click type and date 
 841         self
.result 
= [evt
.click
, str(evt
.day
), Month
[evt
.month
], str(evt
.year
)]   
 843         if evt
.click 
== 'DLEFT': 
 844             self
.EndModal(wx
.ID_OK
) 
 846     # month and year spin selection routines 
 847     def OnMonthSpin(self
, event
): 
 848         month 
= event
.GetPosition() 
 849         self
.date
.SetValue(Month
[month
]) 
 850         self
.calend
.SetMonth(month
) 
 851         self
.calend
.Refresh() 
 853     def OnYrSpin(self
, event
): 
 854         year 
= event
.GetPosition() 
 855         self
.dtext
.SetValue(str(year
)) 
 856         self
.calend
.SetYear(year
) 
 857         self
.calend
.Refresh() 
 859     def EvtComboBox(self
, event
): 
 860         name 
= event
.GetString() 
 861         monthval 
= self
.date
.FindString(name
) 
 862         self
.m_spin
.SetValue(monthval
+1) 
 864         self
.calend
.SetMonth(monthval
+1) 
 867     # set the calendar for highlighted days 
 869     def ResetDisplay(self
): 
 870         month 
= self
.calend
.GetMonth() 
 871         self
.calend
.Refresh()