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
16
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
44
45
47 """
48 The new pregnancy calculator.
49 """
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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
72 self.xfer_cal_date_to=LMP_FIELD
73
74
75
76 self.ustxt=wx.DateTime_Today()
77
78
79
80
81
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
96
97 label = wx.StaticText(self,-1,_("LMP"),size = (50,20))
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))
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
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
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
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
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
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
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
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
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
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
285 szr_main_lf.Add(btn_reset,0,wx.EXPAND)
286
287
288
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
295
296
297
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
309
310 if(self.xfer_cal_date_to==LMP_FIELD):
311
312
313
314
315
316
317
318
319 self.lmp = self.lmp_cal.GetDate ().GetTicks ()
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
327 lmp_txt = wx.DateTime()
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
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
358 self.usdate = self.lmp_cal.GetDate ().GetTicks ()
359 usdatetxt = wx.DateTime()
360 usdatetxt.SetTimeT(self.usdate)
361 self.txtdate.SetValue(self.PurgeTime(usdatetxt))
362
363
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
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
381
382
384
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)
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())
399
400
403
406
407
408
409
412
413
415 time_loc=string.find(str(date),":00:00")
416 date_str=str(date)
417 return date_str[:(time_loc-3)]
418
419
423
424
426 self.lmp_cal.SetDate(self.ustxt)
427 self.xfer_cal_date_to=US_FIELD
428 event.Skip()
429
430
431
432
433
434
435 if __name__ == '__main__':
436 wx.InitAllImageHandlers()
437
443
444 import gettext
445 _ = gettext.gettext
446 gettext.textdomain ('gnumed')
447 app = TestApp()
448 app.MainLoop()
449
450
451