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 
  42 # 06/02/2004 - Joerg "Adi" Sieker adi@sieker.info 
  44 # o Changed color handling, use dictionary instead of members. 
  45 #   This causes all color changes to be ignored if they manipluate the members directly. 
  46 #   SetWeekColor and other method color methods were adapted to use the new dictionary. 
  47 # o Added COLOR_* constants 
  48 # o Added SetColor method for Calendar class 
  49 # o Added 3D look of week header 
  50 # o Added colors for 3D look of header 
  51 # o Fixed width calculation. 
  52 #   Because of rounding difference the total width and height of the 
  53 #   calendar could be up to 6 pixels to small. The last column and row 
  54 #   are now wider/taller by the missing amount. 
  55 # o Added SetTextAlign method to wxCalendar. This exposes logic 
  56 #   which was already there. 
  57 # o Fixed CalDraw.SetMarg which set set_x_st and set_y_st which don't get used anywhere. 
  58 #   Instead set set_x_mrg and set_y_mrg 
  59 # o Changed default X and Y Margin to 0. 
  60 # o Added wxCalendar.SetMargin. 
  66 CalDays 
= [6, 0, 1, 2, 3, 4, 5] 
  67 AbrWeekday 
= {6:"Sun", 0:"Mon", 1:"Tue", 2:"Wed", 3:"Thu", 4:"Fri", 5:"Sat"}
 
  70 COLOR_GRID_LINES 
= "grid_lines" 
  71 COLOR_BACKGROUND 
= "background" 
  72 COLOR_SELECTION_FONT 
= "selection_font" 
  73 COLOR_SELECTION_BACKGROUND 
= "selection_background" 
  74 COLOR_BORDER 
= "border" 
  75 COLOR_HEADER_BACKGROUND 
= "header_background" 
  76 COLOR_HEADER_FONT 
= "header_font" 
  77 COLOR_WEEKEND_BACKGROUND 
= "weekend_background" 
  78 COLOR_WEEKEND_FONT 
= "weekend_font" 
  80 COLOR_3D_LIGHT 
= "3d_light" 
  81 COLOR_3D_DARK 
= "3d_dark" 
  82 COLOR_HIGHLIGHT_FONT 
= "highlight_font" 
  83 COLOR_HIGHLIGHT_BACKGROUND 
= "highlight_background" 
  85 BusCalDays 
= [0, 1, 2, 3, 4, 5, 6] 
  87 # Calendar click event - added 12/1/03 by jmg (see above) 
  88 wxEVT_COMMAND_PYCALENDAR_DAY_CLICKED 
= wx
.NewEventType() 
  89 EVT_CALENDAR 
= wx
.PyEventBinder(wxEVT_COMMAND_PYCALENDAR_DAY_CLICKED
, 1) 
  96             monthlist
.append(name
) 
  99 def MakeColor(in_color
): 
 101         color 
= wxNamedColour(in_color
) 
 108     colors
[COLOR_GRID_LINES
] = 'BLACK' 
 109     colors
[COLOR_BACKGROUND
] = 'WHITE' 
 110     colors
[COLOR_SELECTION_FONT
]  =  wx
.SystemSettings_GetColour(wx
.SYS_COLOUR_WINDOWTEXT
) 
 111     colors
[COLOR_SELECTION_BACKGROUND
] =wx
.Colour(255,255,225) 
 112     colors
[COLOR_BORDER
] = 'BLACK' 
 113     colors
[COLOR_HEADER_BACKGROUND
] = wx
.SystemSettings_GetColour(wx
.SYS_COLOUR_3DFACE
) 
 114     colors
[COLOR_HEADER_FONT
] = wx
.SystemSettings_GetColour(wx
.SYS_COLOUR_WINDOWTEXT
) 
 115     colors
[COLOR_WEEKEND_BACKGROUND
] = 'LIGHT GREY' 
 116     colors
[COLOR_WEEKEND_FONT
] = wx
.SystemSettings_GetColour(wx
.SYS_COLOUR_WINDOWTEXT
) 
 117     colors
[COLOR_FONT
] = wx
.SystemSettings_GetColour(wx
.SYS_COLOUR_WINDOWTEXT
) 
 118     colors
[COLOR_3D_LIGHT
] = wx
.SystemSettings_GetColour(wx
.SYS_COLOUR_BTNHIGHLIGHT
) 
 119     colors
[COLOR_3D_DARK
] = wx
.SystemSettings_GetColour(wx
.SYS_COLOUR_BTNSHADOW
) 
 120     colors
[COLOR_HIGHLIGHT_FONT
]  =  'PINK' 
 121     colors
[COLOR_HIGHLIGHT_BACKGROUND
] = 'RED' 
 123 # calendar drawing routing 
 126     def __init__(self
, parent
): 
 130             self
.scale 
= parent
.scale
 
 140         self
.num_auto 
= True    # auto scale of the cal number day size 
 141         self
.num_size 
= 12      # default size of calendar if no auto size 
 142         self
.max_num_size 
= 12  # maximum size for calendar number 
 144         self
.num_align_horz 
= wx
.ALIGN_CENTRE    
# alignment of numbers 
 145         self
.num_align_vert 
= wx
.ALIGN_CENTRE
 
 146         self
.num_indent_horz 
= 0     # points indent from position, used to offset if not centered 
 147         self
.num_indent_vert 
= 0 
 149         self
.week_auto 
= True       # auto scale of week font text 
 151         self
.max_week_size 
= 12 
 153         self
.colors 
= DefaultColors() 
 156         self
.bold 
= wx
.NORMAL
 
 158         self
.hide_title 
= False 
 159         self
.hide_grid 
= False 
 160         self
.outer_border 
= True 
 162         self
.title_offset 
= 0 
 163         self
.cal_week_scale 
= 0.7 
 164         self
.show_weekend 
= False 
 165         self
.cal_type 
= "NORMAL" 
 167     def SetWeekColor(self
, font_color
, week_color
): 
 168         # set font and background color for week title 
 169         self
.colors
[COLOR_HEADER_FONT
] = MakeColor(font_color
) 
 170         self
.colors
[COLOR_HEADER_BACKGROUND
] = MakeColor(week_color
) 
 171         self
.colors
[COLOR_3D_LIGHT
] = MakeColor(week_color
) 
 172         self
.colors
[COLOR_3D_DARK
] = MakeColor(week_color
) 
 174     def SetSize(self
, size
): 
 175         self
.set_sizew 
= size
[0] 
 176         self
.set_sizeh 
= size
[1] 
 178     def InitValues(self
):       # default dimensions of various elements of the calendar 
 181         self
.set_cy_st 
= 0      # start position 
 184         self
.set_y_mrg 
= 1      # start of vertical draw default 
 187     def SetPos(self
, xpos
, ypos
): 
 188         self
.set_cx_st 
= xpos
 
 189         self
.set_cy_st 
= ypos
 
 191     def SetMarg(self
, xmarg
, ymarg
): 
 192         self
.set_x_mrg 
= xmarg
 
 193         self
.set_y_mrg 
= ymarg
 
 194         self
.set_y_end 
= ymarg
 
 196     def InitScale(self
):        # scale position values 
 197         self
.sizew 
= int(self
.set_sizew 
* self
.pwidth
) 
 198         self
.sizeh 
= int(self
.set_sizeh 
* self
.pheight
) 
 200         self
.cx_st 
= int(self
.set_cx_st 
* self
.pwidth
)       # draw start position 
 201         self
.cy_st 
= int(self
.set_cy_st 
* self
.pheight
) 
 203         self
.x_mrg 
= int(self
.set_x_mrg 
* self
.pwidth
)         # calendar draw margins 
 204         self
.y_mrg 
= int(self
.set_y_mrg 
* self
.pheight
) 
 205         self
.y_end 
= int(self
.set_y_end 
* self
.pheight
) 
 207     def DrawCal(self
, DC
, sel_lst
=[]): 
 212         if self
.hide_title 
is False: 
 219         if self
.show_weekend 
is True:       # highlight weekend dates 
 222         self
.AddSelect(sel_lst
)     # overrides the weekend highlight 
 224         self
.DrawSel(DC
)      # highlighted days 
 228     def AddSelect(self
, list, cfont
=None, cbackgrd 
= None): 
 230             cfont 
= self
.colors
[COLOR_SELECTION_FONT
]      # font digit color 
 232             cbackgrd 
= self
.colors
[COLOR_SELECTION_BACKGROUND
]     # select background color 
 235             self
.cal_sel
[val
] = (cfont
, cbackgrd
) 
 237     # draw border around the outside of the main display rectangle 
 238     def DrawBorder(self
, DC
):    
 239         brush 
= wx
.Brush(MakeColor(self
.colors
[COLOR_BACKGROUND
]), wx
.SOLID
) 
 241         DC
.SetPen(wx
.Pen(MakeColor(self
.colors
[COLOR_BORDER
]), 1)) 
 242         if self
.outer_border 
is True: 
 243             # full display window area 
 244             rect 
= wx
.Rect(self
.cx_st
, self
.cy_st
, self
.sizew
, self
.sizeh
)   
 245             DC
.DrawRectangleRect(rect
) 
 247     def DrawNumVal(self
): 
 250     # calculate the calendar days and offset position 
 251     def SetCal(self
, year
, month
): 
 252         self
.InitValues()       # reset initial values 
 258         t 
= Date(year
, month
, day
) 
 259         dow 
= self
.dow 
= t
.day_of_week     
# start day in month 
 260         dim 
= self
.dim 
= t
.days_in_month   
# number of days in month 
 262         if self
.cal_type 
== "NORMAL": 
 267         self
.st_pos 
= start_pos
 
 270         for i 
in range(start_pos
): 
 271             self
.cal_days
.append('') 
 275             self
.cal_days
.append(str(i
)) 
 280     def SetWeekEnd(self
, font_color
=None, backgrd 
= None): 
 281         if font_color 
!= None: 
 282             self
.SetColor(COLOR_WEEKEND_FONT
, MakeColor(font_color
)) 
 284             self
.SetColor(COLOR_WEEKEND_BACKGROUND
, MakeColor(backgrd
)) 
 286         date 
= 6 - int(self
.dow
)     # start day of first saturday 
 288         while date 
<= self
.dim
: 
 289             self
.cal_sel
[date
] = (self
.GetColor(COLOR_WEEKEND_FONT
), self
.GetColor(COLOR_WEEKEND_BACKGROUND
))  # Saturday 
 293                 self
.cal_sel
[date
] = (self
.GetColor(COLOR_WEEKEND_FONT
), self
.GetColor(COLOR_WEEKEND_BACKGROUND
))      # Sunday 
 298     # get the display rectange list of the day grid 
 301         for y 
in self
.gridy
[1:-1]: 
 302             if y 
== self
.gridy
[-2]: 
 305             for x 
in self
.gridx
[:-1]: 
 306                 assert type(y
) == int 
 307                 assert type(x
) == int 
 312                 if x 
== self
.gridx
[-2]: 
 315                 rect 
= wx
.Rect(x
, y
, w
+1, h
+1)  # create rect region 
 328     # month and year title 
 329     def DrawMonth(self
, DC
): 
 330         month 
= Month
[self
.month
] 
 333         if self
.sizeh 
< _MIDSIZE
: 
 336         f 
= wx
.Font(sizef
, self
.font
, wx
.NORMAL
, self
.bold
) 
 339         tw
,th 
= DC
.GetTextExtent(month
) 
 340         adjust 
= self
.cx_st 
+ (self
.sizew
-tw
)/2 
 341         DC
.DrawText(month
, (adjust
, self
.cy_st 
+ th
)) 
 343         year 
= str(self
.year
) 
 344         tw
,th 
= DC
.GetTextExtent(year
) 
 345         adjust 
=  self
.sizew 
- tw 
- self
.x_mrg
 
 347         self
.title_offset 
= th 
* 2 
 349         f 
= wx
.Font(sizef
, self
.font
, wx
.NORMAL
, self
.bold
) 
 351         DC
.DrawText(year
, (self
.cx_st 
+ adjust
, self
.cy_st 
+ th
)) 
 353     def DrawWeek(self
, DC
):     # draw the week days 
 354         # increase by 1 to include all gridlines 
 355         width  
= self
.gridx
[1] - self
.gridx
[0] + 1 
 356         height 
= self
.gridy
[1] - self
.gridy
[0] + 1 
 357         rect_w 
= self
.gridx
[-1] - self
.gridx
[0] 
 359         f 
= wx
.Font(10, self
.font
, wx
.NORMAL
, self
.bold
)      # initial font setting 
 361         if self
.week_auto 
== True: 
 362             test_size 
= self
.max_week_size      
# max size 
 365                 f
.SetPointSize(test_size
) 
 367                 tw
,th 
= DC
.GetTextExtent(test_day
) 
 369                 if tw 
< width 
and th 
< height
: 
 372                 test_size 
= test_size 
- 1 
 374             f
.SetPointSize(self
.week_size
)   # set fixed size 
 377         DC
.SetTextForeground(MakeColor(self
.colors
[COLOR_HEADER_FONT
])) 
 382         brush 
= wx
.Brush(MakeColor(self
.colors
[COLOR_HEADER_BACKGROUND
]), wx
.SOLID
) 
 385         if self
.cal_type 
== "NORMAL": 
 388             cal_days 
= BusCalDays
 
 391             if val 
== cal_days
[-1]: 
 392                 width 
= width 
+ self
.restW
 
 394             day 
= AbrWeekday
[val
] 
 399             dw
,dh 
= DC
.GetTextExtent(day
) 
 402             diffy 
= (height
-dh
)/2 
 404             x 
= self
.gridx
[cnt_x
] 
 405             y 
= self
.gridy
[cnt_y
] 
 407             pointWH 
= (width
, height
) 
 408             if self
.hide_grid 
== False: 
 409                 pen 
= wx
.Pen(MakeColor(self
.GetColor(COLOR_GRID_LINES
)), 1, wx
.SOLID
) 
 411                 pen 
= wx
.Pen(MakeColor(self
.GetColor(COLOR_BACKGROUND
)), 1, wx
.SOLID
) 
 413             DC
.DrawRectangle( pointXY
, pointWH
) 
 415             old_pen 
= DC
.GetPen() 
 417             pen 
= wx
.Pen(MakeColor(self
.colors
[COLOR_3D_LIGHT
]), 1, wx
.SOLID
) 
 419             # draw the horizontal hilight 
 420             startPoint 
= wx
.Point(x 
+ 1 , y 
+ 1) 
 421             endPoint   
= wx
.Point(x 
+ width 
- 1, y 
+ 1) 
 422             DC
.DrawLine(startPoint
, endPoint 
) 
 424             # draw the vertical hilight 
 425             startPoint 
= wx
.Point(x 
+ 1 , y 
+ 1) 
 426             endPoint   
= wx
.Point(x 
+ 1, y 
+ height 
- 2) 
 427             DC
.DrawLine(startPoint
, endPoint 
) 
 429             pen 
= wx
.Pen(MakeColor(self
.colors
[COLOR_3D_DARK
]), 1, wx
.SOLID
) 
 432             # draw the horizontal lowlight 
 433             startPoint 
= wx
.Point(x 
+ 1, y 
+ height 
- 2) 
 434             endPoint   
= wx
.Point(x 
+ width 
- 1, y 
+ height 
- 2) 
 435             DC
.DrawLine(startPoint
, endPoint 
) 
 437             # draw the vertical lowlight 
 438             startPoint 
= wx
.Point(x 
+ width 
- 2 , y 
+ 2) 
 439             endPoint   
= wx
.Point(x 
+ width 
- 2, y 
+ height 
- 2) 
 440             DC
.DrawLine(startPoint
, endPoint 
) 
 442             pen 
= wx
.Pen(MakeColor(self
.colors
[COLOR_FONT
]), 1, wx
.SOLID
) 
 446             point 
= (x
+diffx
, y
+diffy
) 
 447             DC
.DrawText(day
, point
) 
 450     # draw the day numbers 
 451     def DrawNum(self
, DC
):       
 452         f 
= wx
.Font(10, self
.font
, wx
.NORMAL
, self
.bold
)      # initial font setting 
 454         if self
.num_auto 
== True: 
 455             test_size 
= self
.max_num_size      
# max size 
 459                 f
.SetPointSize(test_size
) 
 461                 tw
,th 
= DC
.GetTextExtent(test_day
) 
 463                 if tw 
< self
.cellW 
and th 
< self
.cellH
: 
 466                 test_size 
= test_size 
- 1 
 468             f
.SetPointSize(self
.num_size
)   # set fixed size 
 473         for val 
in self
.cal_days
: 
 474             x 
= self
.gridx
[cnt_x
] 
 475             y 
= self
.gridy
[cnt_y
] 
 477             self
.DrawDayText(x
, y
, val
, f
, DC
) 
 485     def DrawDayText(self
, x
, y
, text
, font
, DC
): 
 488             num_color 
= self
.cal_sel
[num_val
][0] 
 490             num_color 
= self
.colors
[COLOR_FONT
] 
 492         DC
.SetTextForeground(MakeColor(num_color
)) 
 495         tw
,th 
= DC
.GetTextExtent(text
) 
 497         if self
.num_align_horz 
== wx
.ALIGN_CENTRE
: 
 498             adj_h 
= (self
.cellW 
- tw
)/2 
 499         elif self
.num_align_horz 
== wx
.ALIGN_RIGHT
: 
 500             adj_h 
= self
.cellW 
- tw
 
 502             adj_h 
= 0   # left alignment 
 504         adj_h 
= adj_h 
+ self
.num_indent_horz
 
 506         if self
.num_align_vert 
== wx
.ALIGN_CENTRE
: 
 507             adj_v 
= (self
.cellH 
- th
)/2 
 508         elif self
.num_align_vert 
== wx
.ALIGN_BOTTOM
: 
 509             adj_v 
= self
.cellH 
- th
 
 511             adj_v 
= 0   # left alignment 
 513         adj_v 
= adj_v 
+ self
.num_indent_vert
 
 515         DC
.DrawText(text
, (x
+adj_h
, y
+adj_v
)) 
 517     # calculate the dimensions in the center of the drawing area 
 519         borderW 
= self
.x_mrg 
* 2 
 520         borderH 
= self
.y_mrg 
+ self
.y_end 
+ self
.title_offset
 
 522         self
.cellW 
= int((self
.sizew
-borderW
)/7) 
 523         self
.cellH 
= int((self
.sizeh
-borderH
)/7) 
 525         self
.restW 
= ((self
.sizew 
- borderW
)%7 ) - 1 
 527         # week title adjustment 
 528         self
.weekHdrCellH 
= int(self
.cellH
*self
.cal_week_scale
) 
 529         # recalculate the cell height exkl. the week header and 
 530         # subtracting the size 
 531         self
.cellH 
= int((self
.sizeh
-borderH
-self
.weekHdrCellH
)/6) 
 533         self
.restH 
= ((self
.sizeh
-borderH
-self
.weekHdrCellH
)%6 ) - 1 
 534         self
.calW 
= self
.cellW 
* 7 
 535         self
.calH 
= self
.cellH 
* 6 + self
.weekHdrCellH
 
 537     # highlighted selected days 
 538     def DrawSel(self
, DC
): 
 540         for key 
in self
.cal_sel
.keys(): 
 541             sel_color 
= self
.cal_sel
[key
][1] 
 542             brush 
= wx
.Brush(MakeColor(sel_color
), wx
.SOLID
) 
 545             if self
.hide_grid 
is False: 
 546                 DC
.SetPen(wx
.Pen(MakeColor(self
.colors
[COLOR_GRID_LINES
]), 0)) 
 548                 DC
.SetPen(wx
.Pen(MakeColor(self
.colors
[COLOR_BACKGROUND
]), 0)) 
 550             nkey 
= key 
+ self
.st_pos 
-1 
 553             DC
.DrawRectangle((rect
.x
, rect
.y
), (rect
.width
, rect
.height
)) 
 555     # calculate and draw the grid lines 
 556     def DrawGrid(self
, DC
): 
 557         DC
.SetPen(wx
.Pen(MakeColor(self
.colors
[COLOR_GRID_LINES
]), 0)) 
 562         self
.x_st 
= self
.cx_st 
+ self
.x_mrg
 
 563         # start postion of draw 
 564         self
.y_st 
= self
.cy_st 
+ self
.y_mrg 
+ self
.title_offset
 
 568         y2 
= y1 
+ self
.calH 
+ self
.restH
 
 574             if self
.hide_grid 
is False: 
 575                 DC
.DrawLine((x1
, y1
), (x1
, y2
)) 
 577             self
.gridx
.append(x1
) 
 583         x2 
= x1 
+ self
.calW 
+ self
.restW
 
 589             if self
.hide_grid 
is False: 
 590                 DC
.DrawLine((x1
, y1
), (x2
, y1
)) 
 592             self
.gridy
.append(y1
) 
 595                 y1 
= y1 
+ self
.weekHdrCellH
 
 599     def GetColor(self
, name
): 
 600         return MakeColor(self
.colors
[name
]) 
 602     def SetColor(self
, name
, value
): 
 603         self
.colors
[name
] = MakeColor(value
) 
 605 class PrtCalDraw(CalDraw
): 
 606     def InitValues(self
): 
 609         # start draw border location 
 613         # draw offset position 
 618     # calculate the dimensions in the center of the drawing area 
 619     def SetPSize(self
, pwidth
, pheight
):     
 620         self
.pwidth 
= int(pwidth
)/self
.scale
 
 621         self
.pheight 
= int(pheight
)/self
.scale
 
 623     def SetPreview(self
, preview
): 
 624         self
.preview 
= preview
 
 626 class Calendar(wx
.Window
): 
 627     def __init__(self
, parent
, id, pos
=wx
.DefaultPosition
, size
=wx
.DefaultSize
): 
 628         wx
.Window
.__init
__(self
, parent
, id, pos
, size
) 
 630         # set the calendar control attributes 
 633         self
.hide_grid 
= False 
 634         self
.hide_title 
= False 
 635         self
.show_weekend 
= False 
 636         self
.cal_type 
= "NORMAL" 
 637         self
.outer_border 
= True 
 638         self
.num_align_horz 
= wx
.ALIGN_CENTRE
 
 639         self
.num_align_vert 
= wx
.ALIGN_CENTRE
 
 640         self
.colors 
= DefaultColors() 
 645         self
.select_list 
= [] 
 647         self
.SetBackgroundColour(MakeColor(self
.colors
[COLOR_BACKGROUND
])) 
 648         self
.Bind(wx
.EVT_LEFT_DOWN
, self
.OnLeftEvent
) 
 649         self
.Bind(wx
.EVT_LEFT_DCLICK
, self
.OnLeftDEvent
) 
 650         self
.Bind(wx
.EVT_RIGHT_DOWN
, self
.OnRightEvent
) 
 651         self
.Bind(wx
.EVT_RIGHT_DCLICK
, self
.OnRightDEvent
) 
 653         self
.sel_key 
= None      #  last used by 
 654         self
.sel_lst 
= []        # highlighted selected days 
 656         # default calendar for current month 
 662         self
.Bind(wx
.EVT_PAINT
, self
.OnPaint
) 
 663         self
.Bind(wx
.EVT_SIZE
, self
.OnSize
) 
 665     def GetColor(self
, name
): 
 666         return MakeColor(self
.colors
[name
]) 
 668     def SetColor(self
, name
, value
): 
 669         self
.colors
[name
] = MakeColor(value
) 
 671     # control some of the main calendar attributes 
 674         self
.hide_title 
= True 
 677         self
.hide_grid 
= True 
 679     # determine the calendar rectangle click area and draw a selection 
 681     def ProcessClick(self
, event
): 
 682         self
.x
, self
.y 
= event
.GetX(), event
.GetY() 
 683         key 
= self
.GetDayHit(self
.x
, self
.y
) 
 686     # tab mouse click events and process 
 688     def OnLeftEvent(self
, event
): 
 690         self
.shiftkey 
= event
.ShiftDown() 
 691         self
.ctrlkey 
= event
.ControlDown() 
 692         self
.ProcessClick(event
) 
 694     def OnLeftDEvent(self
, event
): 
 696         self
.ProcessClick(event
) 
 698     def OnRightEvent(self
, event
): 
 700         self
.ProcessClick(event
) 
 702     def OnRightDEvent(self
, event
): 
 703         self
.click 
= 'DRIGHT' 
 704         self
.ProcessClick(event
) 
 706     def SetSize(self
, set_size
): 
 709     def SetSelDay(self
, sel
): 
 710         # list of highlighted days 
 713     # get the current date 
 716         self
.month 
= dt
.month
 
 720     # set the current day 
 721     def SetCurrentDay(self
): 
 723         self
.set_day 
= self
.day
 
 725     # get the date, day, month, year set in calendar 
 728         return self
.day
, self
.month
, self
.year
 
 739     # set the day, month, and year 
 741     def SetDayValue(self
, day
): 
 744     def SetMonth(self
, month
): 
 745         if month 
>= 1 and month 
<= 12: 
 751     def SetYear(self
, year
): 
 754     # increment year and month 
 757         self
.year 
= self
.year 
+ 1 
 761         self
.year 
= self
.year 
- 1 
 765         self
.month 
= self
.month 
+ 1 
 768             self
.year 
= self
.year 
+ 1 
 772         self
.month 
= self
.month 
- 1 
 775             self
.year 
= self
.year 
- 1 
 778     # test to see if the selection has a date and create event 
 780     def TestDay(self
, key
): 
 782             self
.day 
= int(self
.cal_days
[key
]) 
 789             # Changed 12/1/03 by jmg (see above) to support 2.5 event binding 
 790             evt 
= wx
.PyCommandEvent(wxEVT_COMMAND_PYCALENDAR_DAY_CLICKED
, self
.GetId()) 
 791             evt
.click
, evt
.day
, evt
.month
, evt
.year 
= self
.click
, self
.day
, self
.month
, self
.year
 
 792             evt
.shiftkey 
= self
.shiftkey
 
 793             evt
.ctrlkey 
= self
.ctrlkey
 
 794             self
.GetEventHandler().ProcessEvent(evt
) 
 796             self
.set_day 
= self
.day
 
 799     # find the clicked area rectangle 
 801     def GetDayHit(self
, mx
, my
): 
 802         for key 
in self
.rg
.keys(): 
 804             ms_rect 
= wx
.Rect(mx
, my
, 1, 1) 
 805             if wx
.IntersectRect(ms_rect
, val
) is not None: 
 806                 result 
= self
.TestDay(key
) 
 813     def SetWeekColor(self
, font_color
, week_color
):      
 814         # set font and background color for week title 
 815         self
.colors
[COLOR_HEADER_FONT
] = MakeColor(font_color
) 
 816         self
.colors
[COLOR_HEADER_BACKGROUND
] = MakeColor(week_color
) 
 817         self
.colors
[COLOR_3D_LIGHT
] = MakeColor(week_color
) 
 818         self
.colors
[COLOR_3D_DARK
] = MakeColor(week_color
) 
 820     def SetTextAlign(self
, vert
, horz
): 
 821         self
.num_align_horz 
= horz
 
 822         self
.num_align_vert 
= vert
 
 824     def AddSelect(self
, list, font_color
, back_color
): 
 825         list_val 
= [list, font_color
, back_color
] 
 826         self
.select_list
.append(list_val
) 
 828     def ShowWeekEnd(self
): 
 830         self
.show_weekend 
= True 
 832     def SetBusType(self
): 
 833         self
.cal_type 
= "BUS" 
 835     def OnSize(self
, evt
): 
 839     def OnPaint(self
, event
): 
 840         DC 
= wx
.PaintDC(self
) 
 843     def DoDrawing(self
, DC
): 
 844         #DC = wx.PaintDC(self) 
 850             self
.caldraw 
= CalDraw(self
) 
 853         cal
.hide_grid 
= self
.hide_grid
 
 854         cal
.hide_title 
= self
.hide_title
 
 855         cal
.show_weekend 
= self
.show_weekend
 
 856         cal
.cal_type 
= self
.cal_type
 
 857         cal
.outer_border 
= self
.outer_border
 
 858         cal
.num_align_horz 
= self
.num_align_horz
 
 859         cal
.num_align_vert 
= self
.num_align_vert
 
 860         cal
.colors 
= self
.colors
 
 862         if self
.size 
is None: 
 863             size 
= self
.GetClientSize() 
 870         cal
.SetCal(self
.year
, self
.month
) 
 872         # these have to set after SetCal as SetCal would overwrite them again. 
 873         cal
.set_x_mrg 
= self
.set_x_mrg 
 
 874         cal
.set_y_mrg 
= self
.set_y_mrg 
 
 875         cal
.set_y_end 
= self
.set_y_end 
 
 877         for val 
in self
.select_list
: 
 878             cal
.AddSelect(val
[0], val
[1], val
[2]) 
 880         cal
.DrawCal(DC
, self
.sel_lst
) 
 882         self
.rg 
= cal
.GetRect() 
 883         self
.cal_days 
= cal
.GetCal() 
 884         self
.st_pos 
= cal
.GetOffset() 
 885         self
.ymax 
= DC
.MaxY() 
 887         if self
.set_day 
!= None: 
 888             self
.SetDay(self
.set_day
) 
 892     # draw the selection rectangle 
 893     def DrawRect(self
, key
, fgcolor 
= 'BLACK', width 
= 0): 
 897         DC 
= wx
.ClientDC(self
) 
 900         brush 
= wx
.Brush(wx
.Colour(0, 0xFF, 0x80), wx
.TRANSPARENT
) 
 904             DC
.SetPen(wx
.Pen(MakeColor(fgcolor
), width
)) 
 906             DC
.SetPen(wx
.Pen(MakeColor(self
.GetColor(COLOR_GRID_LINES
)), width
)) 
 909         DC
.DrawRectangle((rect
.x
, rect
.y
), (rect
.width
, rect
.height
)) 
 913     # set the day selection 
 915     def SetDay(self
, day
): 
 916         day 
= day 
+ self
.st_pos 
- 1 
 919     def SelectDay(self
, key
): 
 921         # clear large selection 
 922         self
.DrawRect(self
.sel_key
, self
.GetColor(COLOR_BACKGROUND
), sel_size
) 
 924         if self
.hide_grid 
is False: 
 925             self
.DrawRect(self
.sel_key
, self
.GetColor(COLOR_GRID_LINES
), sel_size
) 
 927         self
.DrawRect(key
, self
.GetColor(COLOR_HIGHLIGHT_BACKGROUND
), sel_size
) 
 930         self
.select_day 
= None 
 934     def SetMargin(self
, xmarg
, ymarg
): 
 935         self
.set_x_mrg 
= xmarg
 
 936         self
.set_y_mrg 
= ymarg
 
 937         self
.set_y_end 
= ymarg
 
 939 class CalenDlg(wx
.Dialog
): 
 940     def __init__(self
, parent
, month
=None, day 
= None, year
=None): 
 941         wx
.Dialog
.__init
__(self
, parent
, -1, "Event Calendar", wx
.DefaultPosition
, (280, 360)) 
 943         # set the calendar and attributes 
 944         self
.calend 
= Calendar(self
, -1, (20, 60), (240, 200)) 
 947             self
.calend
.SetCurrentDay() 
 948             start_month 
= self
.calend
.GetMonth() 
 949             start_year 
= self
.calend
.GetYear() 
 951             self
.calend
.month 
= start_month 
= month
 
 952             self
.calend
.year 
= start_year 
= year
 
 953             self
.calend
.SetDayValue(day
) 
 955         self
.calend
.HideTitle() 
 958         # get month list from DateTime 
 959         monthlist 
= GetMonthList() 
 962         self
.date 
= wx
.ComboBox(self
, -1, Month
[start_month
], (20, 20), (90, -1),  
 963                                 monthlist
, wx
.CB_DROPDOWN
) 
 964         self
.Bind(wx
.EVT_COMBOBOX
, self
.EvtComboBox
, self
.date
) 
 966         # alternate spin button to control the month 
 967         h 
= self
.date
.GetSize().height
 
 968         self
.m_spin 
= wx
.SpinButton(self
, -1, (130, 20), (h
*2, h
), wx
.SP_VERTICAL
) 
 969         self
.m_spin
.SetRange(1, 12) 
 970         self
.m_spin
.SetValue(start_month
) 
 971         self
.Bind(wx
.EVT_SPIN
, self
.OnMonthSpin
, self
.m_spin
) 
 973         # spin button to control the year 
 974         self
.dtext 
= wx
.TextCtrl(self
, -1, str(start_year
), (160, 20), (60, -1)) 
 975         h 
= self
.dtext
.GetSize().height
 
 977         self
.y_spin 
= wx
.SpinButton(self
, -1, (220, 20), (h
*2, h
), wx
.SP_VERTICAL
) 
 978         self
.y_spin
.SetRange(1980, 2010) 
 979         self
.y_spin
.SetValue(start_year
) 
 981         self
.Bind(wx
.EVT_SPIN
, self
.OnYrSpin
, self
.y_spin
) 
 982         self
.Bind(EVT_CALENDAR
, self
.MouseClick
, self
.calend
) 
 988         btn 
= wx
.Button(self
, -1, ' Ok ', (x_pos
, y_pos
), but_size
) 
 989         self
.Bind(wx
.EVT_BUTTON
, self
.OnOk
, btn
) 
 991         btn 
= wx
.Button(self
, -1, ' Close ', (x_pos 
+ 120, y_pos
), but_size
) 
 992         self
.Bind(wx
.EVT_BUTTON
, self
.OnCancel
, btn
) 
 994     def OnOk(self
, event
): 
 995         self
.EndModal(wx
.ID_OK
) 
 997     def OnCancel(self
, event
): 
 998         self
.EndModal(wx
.ID_CANCEL
) 
1000     # log the mouse clicks 
1001     def MouseClick(self
, evt
): 
1002         self
.month 
= evt
.month
 
1003         # result click type and date 
1004         self
.result 
= [evt
.click
, str(evt
.day
), Month
[evt
.month
], str(evt
.year
)]   
1006         if evt
.click 
== 'DLEFT': 
1007             self
.EndModal(wx
.ID_OK
) 
1009     # month and year spin selection routines 
1010     def OnMonthSpin(self
, event
): 
1011         month 
= event
.GetPosition() 
1012         self
.date
.SetValue(Month
[month
]) 
1013         self
.calend
.SetMonth(month
) 
1014         self
.calend
.Refresh() 
1016     def OnYrSpin(self
, event
): 
1017         year 
= event
.GetPosition() 
1018         self
.dtext
.SetValue(str(year
)) 
1019         self
.calend
.SetYear(year
) 
1020         self
.calend
.Refresh() 
1022     def EvtComboBox(self
, event
): 
1023         name 
= event
.GetString() 
1024         monthval 
= self
.date
.FindString(name
) 
1025         self
.m_spin
.SetValue(monthval
+1) 
1027         self
.calend
.SetMonth(monthval
+1) 
1030     # set the calendar for highlighted days 
1032     def ResetDisplay(self
): 
1033         month 
= self
.calend
.GetMonth() 
1034         self
.calend
.Refresh()