Package Gnumed :: Package wxpython :: Module gmPregWidgets
[frames] | no frames]

Source Code for Module Gnumed.wxpython.gmPregWidgets

  1  """GNUmed pregnancy related dates caculcator. 
  2   
  3  Calculates from LMP: 
  4   - EDC 
  5   - 18th week ultrasound scan 
  6   
  7  Naegele's rule is easy for manual calculation, but a pain to code 
  8  Enter Haywood's rule ;-), human gestation is defined as 24192000 seconds. 
  9  (Ian, can you please explain a bit more ?) 
 10   
 11  TODO: 
 12  ideally, tool should query backend for parity, race, etc. for exact measurement 
 13  """ 
 14  #==================================================================== 
 15  # $Source: /home/ncq/Projekte/cvs2git/vcs-mirror/gnumed/gnumed/client/wxpython/gmPregWidgets.py,v $ 
 16  # $Id: gmPregWidgets.py,v 1.6 2005-09-28 21:27:30 ncq Exp $ 
 17  __version__ = "$Revision: 1.6 $" 
 18  __author__ = "M. Bonert, R. Terry, I. Haywood" 
 19  __licence__ = "GPL" 
 20   
 21  import math, zlib, cPickle, random, string, os.path 
 22   
 23  try: 
 24          import wxversion 
 25          import wx 
 26  except ImportError: 
 27          from wxPython import wx 
 28          from wxPython import calender 
 29          from wxPython.lib.rcsizer import RowColSizer 
 30   
 31  LMP_FIELD = 0 
 32  US_FIELD = 1 
 33   
 34  ID_LMP = wx.NewId() 
 35  ID_DUE = wx.NewId() 
 36  ID_DAY = wx.NewId() 
 37  ID_WEEK = wx.NewId() 
 38  ID_MENU = wx.NewId() 
 39   
 40  GESTATION = 24192000 
 41  WEEK = 604800 
 42  DAY = 86400 
 43  US18_52 = 10886400      # 18 weeks in seconds (for 18/52 Ultrasound) 
 44   
 45  #==================================================================== 
46 -class cPregCalcFrame (wx.Frame):
47 """ 48 The new pregnancy calculator. 49 """ 50 51 #TODO 52 # IMPROVE removal of time from txt_lmp, txtedc, txtdue (?) 53 # see: def PurgeTime(self, date): 54 # 55 # explore idea of 'status bar' across bottom -- something to make 56 # clear how to use the calculator 57 # 58 # change the set-up of the RowColSizer(), shrink the size of the 'Weeks' & 'Days' fields 59 # make column on right side of preg. calc. more compact 60 # 61 # clean-up the names of the variables (some could be named more descriptively) 62 # 63 # add ability to type in LMP and Scan Date with keyboard (as opposed to only clicking on calendar) 64 # make movement between fields possible with 'tab' & 'enter' 65
66 - def __init__ (self, parent):
67 myStyle = wxMINIMIZE_BOX | wx.CAPTION | wx.ALIGN_CENTER | \ 68 wxALIGN_CENTER_VERTICAL | wx.TAB_TRAVERSAL | wx.STAY_ON_TOP 69 wx.Frame.__init__(self, parent, -1, _("Pregnancy Calculator"), style=myStyle) 70 71 # initialization of variables used in the control & calculation 72 self.xfer_cal_date_to=LMP_FIELD # controls which variable (LMP or Ultrasound) a calendar event changes 73 # (if == 0): {calendar selection modifies LMP} 74 # (if == 1): {calendar selection modifies Ultrasound Date} 75 76 self.ustxt=wx.DateTime_Today() # avoids problem - one would have if the user clicked on 77 # ultrasound date 78 # BONUS: makes the preg. calculator useful for EDC calcs given 79 # a date and the gestation time 80 81 # get icon 82 if __name__ == '__main__': 83 png_fname = os.path.join('..', 'bitmaps', 'preg_calculator.png') 84 else: 85 from Gnumed.pycommon import gmGuiBroker 86 gb = gmGuiBroker.GuiBroker() 87 png_fname = os.path.join(gb['gnumed_dir'], 'bitmaps', 'preg_calculator.png') 88 icon = wx.EmptyIcon() 89 icon.LoadFile(png_fname, wx.BITMAP_TYPE_PNG) 90 self.SetIcon(icon) 91 92 szr_rc = RowColSizer() 93 94 #------------------------------ 95 # sizer holding the 'LMP' stuff 96 #------------------------------ 97 label = wx.StaticText(self,-1,_("LMP"),size = (50,20)) #label Lmp 98 label.SetFont(wx.Font(12,wx.SWISS,wx.NORMAL,wx.NORMAL,False,'')) 99 label.SetForegroundColour(wx.Colour(0,0,0)) 100 101 self.txt_lmp = wx.TextCtrl(self,-1,"",size=(100,20)) # text for lmp 102 self.txt_lmp.SetFont(wx.Font(12,wx.SWISS,wx.NORMAL,wx.NORMAL,False,'')) 103 self.txt_lmp.SetToolTip(wx.ToolTip(_("Click on calendar to enter the last menstrual period date"))) 104 tiplmp=self.txt_lmp.GetToolTip() 105 106 szr_row1 = wx.BoxSizer(wx.HORIZONTAL) 107 szr_row1.Add(self.txt_lmp,1,wx.EXPAND|wx.ALL,2) 108 wx.EVT_SET_FOCUS(self.txt_lmp, self.OnSetFocus_lmp) 109 110 szr_lmp = wx.BoxSizer(wx.HORIZONTAL) 111 szr_lmp.Add(label, 1, 0, 0) 112 szr_lmp.Add((10,1),0,0) 113 szr_rc.Add(szr_lmp, flag=wx.EXPAND, row=0, col=1) 114 szr_rc.Add(szr_row1, flag=wx.EXPAND, row=0, col=2, colspan=5) 115 #------------------------------ 116 # sizer holding the 'Gest.' stuff 117 #------------------------------ 118 label = wx.StaticText(self,-1,_("Gest."),size = (50,20)) 119 label.SetFont(wx.Font(12,wx.SWISS,wx.NORMAL,wx.NORMAL,False,'')) 120 label.SetForegroundColour(wx.Colour(0,0,0)) 121 122 self.txtgest = wx.TextCtrl(self,-1,"",size=(100,20)) 123 self.txtgest.Enable(False) 124 self.txtgest.SetFont(wx.Font(12,wx.SWISS,wx.NORMAL,wx.NORMAL,False,'')) 125 self.txtgest_szr = wx.BoxSizer(wx.HORIZONTAL) 126 self.txtgest_szr.Add(self.txtgest,1,wx.EXPAND|wx.ALL,2) 127 128 szr_gest = wx.BoxSizer(wx.HORIZONTAL) 129 szr_gest.Add(label, 1, 0, 0) 130 szr_gest.Add((10,1),0,0) 131 szr_rc.Add(szr_gest, flag=wx.EXPAND, row=1, col=1) 132 szr_rc.Add(self.txtgest_szr, flag=wx.EXPAND, row=1, col=2, colspan=5) 133 134 #------------------------------ 135 # sizer holding the 'EDC' stuff 136 #------------------------------ 137 label = wx.StaticText(self,-1,_("EDC"),size = (50,20)) 138 label.SetFont(wx.Font(12,wx.SWISS,wx.NORMAL,wx.NORMAL,False,'')) 139 label.SetForegroundColour(wx.Colour(0,0,0)) 140 141 self.txtedc = wx.TextCtrl(self,-1,"",size=(100,20)) 142 self.txtedc.Enable(False) 143 self.txtedc.SetFont(wx.Font(12,wx.SWISS,wx.NORMAL,wx.NORMAL,False,'')) 144 szr_txtedc = wx.BoxSizer(wx.HORIZONTAL) 145 szr_txtedc.Add(self.txtedc,1,wx.EXPAND|wx.ALL,2) 146 szr_edc = wx.BoxSizer(wx.HORIZONTAL) 147 szr_edc.Add(label,1,0,0) 148 szr_edc.Add((10,1),0,0) 149 szr_rc.Add(szr_edc, flag=wx.EXPAND, row=2, col=1) 150 szr_rc.Add(szr_txtedc, flag=wx.EXPAND, row=2, col=2, colspan=5) 151 152 #------------------------------ 153 # "Ultrasound Scan" label 154 #------------------------------ 155 us_label = wx.StaticText(self,-1,_("18 Week Ultrasound Scan"),size = (200,20)) 156 us_label.SetFont(wx.Font(10,wx.SWISS,wx.NORMAL,wx.BOLD,False,'')) 157 us_label.SetForegroundColour(wx.Colour(50,50,204)) 158 szr_backgrnd_18WkScanDue = wx.BoxSizer(wx.VERTICAL) 159 szr_backgrnd_18WkScanDue.Add((1,3), 0) 160 szr_backgrnd_18WkScanDue.Add(us_label,1,wx.EXPAND,1) 161 szr_rc.Add(szr_backgrnd_18WkScanDue, flag=wx.ALIGN_CENTRE_HORIZONTAL, row=3, col=2, colspan=5) 162 #------------------------------ 163 # sizer holding the 'Due' stuff 164 #------------------------------ 165 label = wx.StaticText(self,-1,_("Due"),size = (100,20)) 166 label.SetFont(wx.Font(12,wx.SWISS,wx.NORMAL,wx.NORMAL,False,'')) 167 label.SetForegroundColour(wx.Colour(0,0,0)) 168 169 self.txtdue = wx.TextCtrl(self,-1,"",size=(100,20)) 170 self.txtdue.Enable(False) 171 self.txtdue.SetFont(wx.Font(12,wx.SWISS,wx.NORMAL,wx.NORMAL,False,'')) 172 self.szr_txtdue = wx.BoxSizer(wx.HORIZONTAL) 173 self.szr_txtdue.Add(self.txtdue,1,wx.EXPAND|wx.ALL,2) 174 szr_due = wx.BoxSizer(wx.HORIZONTAL) 175 szr_due.Add(label,1,0,0) 176 szr_due.Add((10,1),0,0) 177 szr_rc.Add(szr_due, flag=wx.EXPAND, row=4, col=1) 178 szr_rc.Add(self.szr_txtdue, flag=wx.EXPAND, row=4, col=2, colspan=5) 179 180 #------------------------------ 181 # "Ultrasound Scan - Revised EDC" label 182 #------------------------------ 183 rev_edc_label = wx.StaticText(self,-1,_("Ultrasound Scan - Revised EDC"),size = (300,20)) 184 rev_edc_label.SetFont(wx.Font(10,wx.SWISS,wx.NORMAL,wx.BOLD,False,'')) 185 rev_edc_label.SetForegroundColour(wx.Colour(50,50,204)) 186 szr_backgrnd_RevEDCLabel = wx.BoxSizer(wx.VERTICAL) 187 szr_backgrnd_RevEDCLabel.Add((1,3), 0) 188 szr_backgrnd_RevEDCLabel.Add(rev_edc_label,1,wx.EXPAND,1) 189 szr_rc.Add(szr_backgrnd_RevEDCLabel, flag=wx.ALIGN_CENTRE_HORIZONTAL, row=5, col=2, colspan=5) 190 191 #------------------------------ 192 # sizer holding the 'newedc' stuff 193 #------------------------------ 194 label1 = wx.StaticText(self,-1,_("Scan Date"),size = (25,20)) 195 label1.SetFont(wx.Font(12,wx.SWISS,wx.NORMAL,wx.NORMAL,False,'')) 196 label1.SetForegroundColour(wx.Colour(0,0,0)) 197 self.txtdate = wx.TextCtrl(self,-1,"",size=(25,20)) 198 self.txtdate.SetFont(wx.Font(12,wx.SWISS,wx.NORMAL,wx.NORMAL,False,'')) 199 self.txtdate.SetToolTip(wx.ToolTip(_("Click on this field and then the ultrasound scan date on the calendar"))) 200 tipdue=self.txtdate.GetToolTip() 201 wx.ToolTip_Enable(1) 202 self.szr_txtdate = wx.BoxSizer(wx.HORIZONTAL) 203 self.szr_txtdate.Add(self.txtdate,1,wx.EXPAND|wx.ALL,2) 204 wx.EVT_SET_FOCUS(self.txtdate, self.OnSetFocus_USDate) 205 206 szr_label1 = wx.BoxSizer(wx.HORIZONTAL) 207 szr_label1.Add(label1,1,0,0) 208 szr_label1.Add((10,1),0,0) 209 szr_rc.Add(szr_label1, flag=wx.EXPAND, row=6, col=1) 210 szr_rc.Add(self.szr_txtdate, flag=wx.EXPAND, row=6, col=2, colspan=5) 211 212 #------------------------------ 213 214 label2 = wx.StaticText(self,-1,_("Weeks"),size = (25,20)) 215 label2.SetFont(wx.Font(12,wx.SWISS,wx.NORMAL,wx.NORMAL,False,'')) 216 label2.SetForegroundColour(wx.Colour(0,0,0)) 217 self.txtweeks = wx.SpinCtrl (self, -1, value = "0", min = 0, max = 42) 218 wx.EVT_SPINCTRL (self.txtweeks ,self.txtweeks.GetId(), self.EvtText_calcnewedc) 219 self.txtweeks.SetFont(wx.Font(12,wx.SWISS,wx.NORMAL,wx.NORMAL,False,'')) 220 self.szr_txtweeks = wx.BoxSizer(wx.HORIZONTAL) 221 self.szr_txtweeks.Add(self.txtweeks,1,wx.EXPAND|wx.ALL,2) 222 223 label3 = wx.StaticText(self,-1,_("Days"),size = (25,20)) 224 label3.SetFont(wx.Font(12,wx.SWISS,wx.NORMAL,wx.NORMAL,False,'')) 225 label3.SetForegroundColour(wx.Colour(0,0,0)) 226 self.txtdays = wx.SpinCtrl (self, -1, value = "0", min = 0, max = 6) 227 wx.EVT_SPINCTRL (self.txtdays ,self.txtdays.GetId(), self.EvtText_calcnewedc) 228 self.txtdays.SetFont(wx.Font(12,wx.SWISS,wx.NORMAL,wx.NORMAL,False,'')) 229 self.szr_txtdays = wx.BoxSizer(wx.HORIZONTAL) 230 self.szr_txtdays.Add(self.txtdays,1,wx.EXPAND|wx.ALL,2) 231 232 szr_label2 = wx.BoxSizer(wx.HORIZONTAL) 233 szr_label2.Add(label2,1,wx.ALIGN_CENTRE_VERTICAL,0) 234 szr_label2.Add((10,1),0,0) 235 szr_label3 = wx.BoxSizer(wx.HORIZONTAL) 236 szr_label3.Add((10,1),0,0) 237 szr_label3.Add(label3,1,wx.ALIGN_CENTRE_VERTICAL,0) 238 szr_label3.Add((10,1),0,0) 239 szr_rc.Add(szr_label2, flag=wx.EXPAND, row=7, col=1) 240 szr_rc.Add(self.szr_txtweeks, flag=wx.EXPAND, row=7, col=2, colspan=2) 241 szr_rc.Add(szr_label3, flag=wx.EXPAND, row=7, col=4) 242 szr_rc.Add(self.szr_txtdays, flag=wx.EXPAND, row=7, col=5, colspan=2) 243 244 #------------------------------ 245 # sizer holding the new (or revised) 'EDC' stuff 246 #------------------------------ 247 label = wx.StaticText(self,-1,_("Rev EDC"),size = (100,20)) 248 label.SetFont(wx.Font(12,wx.SWISS,wx.NORMAL,wx.NORMAL,False,'')) 249 label.SetForegroundColour(wx.Colour(0,0,0)) 250 251 self.txtnewedc = wx.TextCtrl(self,-1,"",size=(100,20)) 252 self.txtnewedc.Enable(False) 253 self.txtnewedc.SetFont(wx.Font(12,wx.SWISS,wx.NORMAL,wx.NORMAL,False,'')) 254 self.szr_txtnewedc = wx.BoxSizer(wx.HORIZONTAL) 255 self.szr_txtnewedc.Add(self.txtnewedc,1,wx.EXPAND|wx.ALL,2) 256 szr_label=wx.BoxSizer(wx.HORIZONTAL) 257 szr_label.Add(label,1,0,0) 258 szr_label.Add((10,1),0,0) 259 szr_rc.Add(szr_label, flag=wx.EXPAND, row=8, col=1) 260 szr_rc.Add(self.szr_txtnewedc, flag=wx.EXPAND, row=8, col=2, colspan=5) 261 self.btnPrint = wx.Button(self,1011,_('&Print')) 262 self.btnSave = wx.Button(self,1011,_('&Save')) 263 szr_buttons = wx.BoxSizer(wx.HORIZONTAL) 264 szr_buttons.Add(self.btnPrint,0,wx.EXPAND) 265 szr_buttons.Add(self.btnSave,0,wx.EXPAND) 266 szr_rc.Add(szr_buttons, flag=wx.EXPAND,row=9, col=3, colspan=4) 267 #------------------------------ 268 # Sizer holding stuff on the right 269 #------------------------------ 270 szr_main_rt = wx.BoxSizer(wx.VERTICAL) 271 szr_main_rt.Add(szr_rc) 272 wx.EVT_BUTTON(self,1010,self.EvtReset) 273 wx.EVT_BUTTON(self,1011,self.EvtPrint) 274 wx.EVT_BUTTON(self,1012,self.EvtSave) 275 #------------------------------ 276 # Add calendar (stuff on the left) 277 #------------------------------ 278 self.lmp_cal = wx.CalendarCtrl (self, ID_LMP,style = wx.RAISED_BORDER) 279 wx.EVT_CALENDAR_SEL_CHANGED(self.lmp_cal, ID_LMP, self.OnCalcByLMP) 280 281 szr_main_lf = wx.BoxSizer(wx.VERTICAL) 282 szr_main_lf.Add(self.lmp_cal,0,wx.ALIGN_CENTRE_HORIZONTAL) 283 btn_reset = wx.Button(self, 1010, _('&Reset')) 284 #szr_main_lf.Add(5,0,5) 285 szr_main_lf.Add(btn_reset,0,wx.EXPAND) 286 287 #-------------------------------------- 288 # Super-sizer holds all the stuff above 289 #-------------------------------------- 290 szr_main_top= wx.BoxSizer(wx.HORIZONTAL) 291 szr_main_top.Add(szr_main_lf,0,0) 292 szr_main_top.Add((15,0),0,0) 293 szr_main_top.Add(szr_main_rt,0,0) 294 #szr_main_top.Add(15,1,0,0) 295 296 #------------------------------ 297 # Put everything together in one big sizer 298 #------------------------------ 299 szr_main= wx.BoxSizer(wx.HORIZONTAL) 300 szr_main.Add(szr_main_top,1,wx.EXPAND|wx.ALL,10) 301 self.SetSizer (szr_main) 302 self.SetAutoLayout (1) 303 szr_main.Fit (self) 304 305 wx.EVT_CLOSE (self, self.OnClose )
306 307 #-----------------------------------------
308 - def OnCalcByLMP (self, event):
309 310 if(self.xfer_cal_date_to==LMP_FIELD): 311 # we do this the "UNIX Way" -- all dates are converted into seconds 312 # since midnight 1 Jan, 1970. 313 # .GetDate().GetTicks() returns time at 5AM. The -18000 second 314 # correction adjusts LMP to 12AM ??? NOT NEEDED 315 # is it possible there is a BUG in the wxPython 316 # Day Light Savings/Standard Time Calc? 317 318 #LMP = self.lmp_cal.GetDate ().GetTicks () - 18000 # Standard Time Fix (?) 319 self.lmp = self.lmp_cal.GetDate ().GetTicks () # Correct for Day Light Saving Time 320 today = wx.DateTime_Today().GetTicks() 321 due = self.lmp + GESTATION 322 gest = today - self.lmp 323 self.ultrasound18_52 = self.lmp + US18_52 324 325 # ----------------- 326 # FIXME: use gmDateInput in gmDateTimeInput.py 327 lmp_txt = wx.DateTime() # FIXME? - change format of date (?) 328 lmp_txt.SetTimeT(self.lmp) 329 self.txt_lmp.SetValue(self.PurgeTime(lmp_txt)) 330 331 # ----------------- 332 gest_week = gest / WEEK 333 gest_day = (gest % WEEK) / DAY 334 if(gest_day==1): 335 days_label=_('day') 336 else: 337 days_label=_('days') 338 if(gest_week==1): 339 weeks_label=_('week') 340 else: 341 weeks_label=_('weeks') 342 # txtgest_str = "%s %s, %s %s" % (gest_week, weeks_label, gest_day, days_label) 343 txtgest_str=str(gest_week)+" "+weeks_label+", "+str(gest_day)+" "+days_label 344 self.txtgest.SetValue(txtgest_str) 345 346 # ----------------- 347 edctxt = wx.DateTime() 348 edctxt.SetTimeT(due) 349 self.txtedc.SetValue(self.PurgeTime(edctxt)) 350 351 # ----------------- 352 self.ustxt = wx.DateTime() 353 self.ustxt.SetTimeT(self.ultrasound18_52) 354 self.txtdue.SetValue(self.PurgeTime(self.ustxt)) 355 356 else: 357 # set Ultrasound Date 358 self.usdate = self.lmp_cal.GetDate ().GetTicks () 359 usdatetxt = wx.DateTime() # FIXME? - change format of date 360 usdatetxt.SetTimeT(self.usdate) 361 self.txtdate.SetValue(self.PurgeTime(usdatetxt)) 362 363 # recalculate 'Rev EDC' if Ultrasound Scan Date is changed 364 if( self.txtnewedc.GetValue() !=""): 365 self.EvtText_calcnewedc(self)
366 367 #-----------------------------------------
368 - def EvtText_calcnewedc (self, event):
369 try: 370 weeks=self.txtweeks.GetValue() 371 days=self.txtdays.GetValue() 372 373 # get date of ultrasound 374 newedc=self.usdate+GESTATION-WEEK*weeks-DAY*days 375 376 wx.D=wx.DateTime() 377 wx.D.SetTimeT(newedc) 378 self.txtnewedc.SetValue(self.PurgeTime(wx.D)) 379 except: 380 pass # error handling - FIXME is 'try' statement necessary (?)
381 382 #-----------------------------------------
383 - def EvtReset(self, event):
384 # reset variables 385 self.txt_lmp.SetValue("") 386 self.txtgest.SetValue("") 387 self.txtedc.SetValue("") 388 self.txtdue.SetValue("") 389 390 self.txtdate.SetValue("") 391 self.ustxt=wx.DateTime_Today() 392 393 self.txtweeks.SetValue(0) # FIXME - MAKE IT RESET TO BLANK? 394 self.txtdays.SetValue(0) 395 self.txtnewedc.SetValue("") 396 397 self.xfer_cal_date_to=LMP_FIELD 398 self.lmp_cal.SetDate(wx.DateTime_Today()) # reset Calendar to current date
399 400 #-----------------------------------------
401 - def EvtPrint(self, event):
402 pass # TODO
403 #-----------------------------------------
404 - def EvtSave(self, event):
405 pass # TODO
406 #----------------------------------------- 407 #def EvtHandout(self, event): 408 # pass # TODO 409 #-------------------------------------------
410 - def OnClose (self, event):
411 self.Destroy ()
412 413 #-------------------------------------------
414 - def PurgeTime(self, date): # a not so elegant way of removing the time
415 time_loc=string.find(str(date),":00:00") 416 date_str=str(date) 417 return date_str[:(time_loc-3)]
418 419 #-------------------------------------------
420 - def OnSetFocus_lmp (self, event):
421 self.xfer_cal_date_to=LMP_FIELD 422 event.Skip() # required so wxTextCtrl box is selected
423 424 #-------------------------------------------
425 - def OnSetFocus_USDate (self, event):
426 self.lmp_cal.SetDate(self.ustxt) # flip calendar to 18/52 date 427 self.xfer_cal_date_to=US_FIELD 428 event.Skip()
429 430 431 432 #==================================================================== 433 # Main 434 #==================================================================== 435 if __name__ == '__main__': 436 wx.InitAllImageHandlers() 437 # set up dummy app
438 - class TestApp (wx.App):
439 - def OnInit (self):
440 frame = cPregCalcFrame(None) 441 frame.Show(1) 442 return 1
443 #--------------------- 444 import gettext 445 _ = gettext.gettext 446 gettext.textdomain ('gnumed') 447 app = TestApp() 448 app.MainLoop() 449 450 #===================================================================== 451