| Home | Trees | Indices | Help |
|
|---|
|
|
1 """GNUmed patient EMR timeline browser.
2
3 Uses the excellent TheTimlineProject.
4 """
5 #================================================================
6 __author__ = "Karsten.Hilbert@gmx.net"
7 __license__ = "GPL v2 or later"
8
9 # std lib
10 import sys
11 import logging
12 import os.path
13
14
15 # 3rd party
16 import wx
17
18
19 # GNUmed libs
20 if __name__ == '__main__':
21 sys.path.insert(0, '../../')
22 from Gnumed.pycommon import gmDispatcher
23 from Gnumed.pycommon import gmTools
24 from Gnumed.pycommon import gmMimeLib
25 from Gnumed.pycommon import gmDateTime
26
27 from Gnumed.business import gmPerson
28
29 from Gnumed.wxpython import gmRegetMixin
30
31 from Gnumed.exporters import gmTimelineExporter
32
33
34 _log = logging.getLogger('gm.ui.tl')
35
36 #============================================================
37 from Gnumed.timelinelib.canvas.data import TimePeriod
38
39 # activate experimental container features
40 from Gnumed.timelinelib.features.experimental import experimentalfeatures
41 experimentalfeatures.EXTENDED_CONTAINER_HEIGHT.set_active(True)
42 experimentalfeatures.EXTENDED_CONTAINER_STRATEGY.set_active(True)
43
44 from Gnumed.timelinelib.canvas.data.timeperiod import TimePeriod
45 from Gnumed.timelinelib.calendar.gregorian.gregorian import GregorianDateTime
46
47 #------------------------------------------------------------
48 from Gnumed.timelinelib.canvas import TimelineCanvas # works because of __init__.py
49
51
53 TimelineCanvas.__init__(self, args[0]) # args[0] should be "parent"
54
55 self.__init_ui()
56 self.__register_interests()
57
58 #--------------------------------------------------------
60 appearance = self.GetAppearance()
61 appearance.set_balloons_visible(True)
62 appearance.set_hide_events_done(False)
63 appearance.set_colorize_weekends(True)
64 appearance.set_display_checkmark_on_events_done(True)
65
66 self.InitDragScroll(direction = wx.BOTH)
67 self.InitZoomSelect()
68 return
69 """
70 appearance.set_legend_visible(self.config.show_legend)
71 appearance.set_minor_strip_divider_line_colour(self.config.minor_strip_divider_line_colour)
72 appearance.set_major_strip_divider_line_colour(self.config.major_strip_divider_line_colour)
73 appearance.set_now_line_colour(self.config.now_line_colour)
74 appearance.set_weekend_colour(self.config.weekend_colour)
75 appearance.set_bg_colour(self.config.bg_colour)
76 appearance.set_draw_period_events_to_right(self.config.draw_point_events_to_right)
77 appearance.set_text_below_icon(self.config.text_below_icon)
78 appearance.set_minor_strip_font(self.config.minor_strip_font)
79 appearance.set_major_strip_font(self.config.major_strip_font)
80 appearance.set_balloon_font(self.config.balloon_font)
81 appearance.set_legend_font(self.config.legend_font)
82 appearance.set_center_event_texts(self.config.center_event_texts)
83 appearance.set_never_show_period_events_as_point_events(self.config.never_show_period_events_as_point_events)
84 appearance.set_week_start(self.config.get_week_start())
85 appearance.set_use_inertial_scrolling(self.config.use_inertial_scrolling)
86 appearance.set_fuzzy_icon(self.config.fuzzy_icon)
87 appearance.set_locked_icon(self.config.locked_icon)
88 appearance.set_hyperlink_icon(self.config.hyperlink_icon)
89 appearance.set_vertical_space_between_events(self.config.vertical_space_between_events)
90 appearance.set_skip_s_in_decade_text(self.config.skip_s_in_decade_text)
91 appearance.set_never_use_time(self.config.never_use_time)
92 appearance.set_legend_pos(self.config.legend_pos)
93 """
94 #--------------------------------------------------------
95 # event handling
96 #--------------------------------------------------------
98 self.Bind(wx.EVT_MOUSEWHEEL, self._on_mousewheel_action)
99 self.Bind(wx.EVT_MOTION, self._on_mouse_motion)
100 self.Bind(wx.EVT_LEFT_DCLICK, self._on_left_dclick)
101 self.Bind(wx.EVT_LEFT_DOWN, self._on_left_down)
102 self.Bind(wx.EVT_LEFT_UP, self._on_left_up)
103 self.Bind(wx.EVT_RIGHT_DOWN, self._on_right_down)
104 self.Bind(wx.EVT_RIGHT_UP, self._on_right_up)
105
106 #self.Bind(wx.EVT_MIDDLE_DOWN, self._on_middle_down)
107
108 #--------------------------------------------------------
110 # not scrolling or zooming:
111 self.DisplayBalloons(evt)
112
113 # in case we are drag-scrolling:
114 self.DragScroll(evt)
115
116 # in case we are drag-zooming:
117 self.DragZoom(evt)
118
119 #--------------------------------------------------------
121 self.SpecialScrollVerticallyOnMouseWheel(evt)
122
123 #--------------------------------------------------------
125 self.CenterAtCursor(evt)
126
127 #--------------------------------------------------------
129 self.StartDragScroll(evt)
130
131 #--------------------------------------------------------
133 self.StopDragScroll()
134
135 #--------------------------------------------------------
137 self.StartZoomSelect(evt)
138
139 #--------------------------------------------------------
141 # right down-up sequence w/o mouse motion leads to
142 # "cannot zoom in deeper than 1 minute"
143 try:
144 self.StopDragZoom()
145 except ValueError:
146 _log.exception('drag-zoom w/o mouse motion')
147
148 #--------------------------------------------------------
149 # internal API
150 #--------------------------------------------------------
152 now = gmDateTime.pydt_now_here()
153 g_now = GregorianDateTime(now.year, now.month, now.day, now.hour, now.minute, now.second).to_time()
154 self.Navigate(lambda tp: tp.center(g_now))
155
156 #--------------------------------------------------------
158 self.set_timeline(None)
159
160 #--------------------------------------------------------
162 from Gnumed.timelinelib.db import db_open
163 db = db_open(tl_file)
164 db.display_in_canvas(self)
165 self.fit_care_era()
166
167 #--------------------------------------------------------
169 if filename is None:
170 filename = gmTools.get_unique_filename(suffix = '.svg')
171 self.SaveAsSvg(filename)
172 return filename
173
174 #--------------------------------------------------------
176 if filename is None:
177 filename = gmTools.get_unique_filename(suffix = '.png')
178 self.SaveAsPng(filename)
179 return filename
180
181 #--------------------------------------------------------
183 all_events = self.controller.get_timeline().get_all_events()
184 if len(all_events) == 0:
185 period4all_events = None
186 start = self._first_time(all_events)
187 end = self._last_time(all_events)
188 period4all_events = TimePeriod(start, end).zoom(-1)
189
190 if period4all_events is None:
191 return
192 if period4all_events.is_period():
193 self.Navigate(lambda tp: tp.update(period4all_events.start_time, period4all_events.end_time))
194 else:
195 self.Navigate(lambda tp: tp.center(period4all_events.mean_time()))
196
197 #--------------------------------------------------------
199 start_time = lambda event: event.get_start_time()
200 return start_time(min(events, key=start_time))
201
202 #--------------------------------------------------------
206
207 #--------------------------------------------------------
209 all_eras = self.controller.get_timeline().get_all_eras()
210 care_era = [ e for e in all_eras if e.name == gmTimelineExporter.ERA_NAME_CARE_PERIOD ][0]
211 era_period = care_era.time_period
212 if era_period.is_period():
213 self.Navigate(lambda tp: tp.update(era_period.start_time, era_period.end_time))
214 else:
215 self.Navigate(lambda tp: tp.center(era_period.mean_time()))
216
217 #--------------------------------------------------------
219 end = gmDateTime.pydt_now_here()
220 g_end = GregorianDateTime(end.year, end.month, end.day, end.hour, end.minute, end.second).to_time()
221 g_start = GregorianDateTime(end.year - 1, end.month, end.day, end.hour, end.minute, end.second).to_time()
222 last_year = TimePeriod(g_start, g_end)
223 self.Navigate(lambda tp: tp.update(last_year.start_time, last_year.end_time))
224
225 #============================================================
226 from Gnumed.wxGladeWidgets import wxgEMRTimelinePluginPnl
227
228 -class cEMRTimelinePluginPnl(wxgEMRTimelinePluginPnl.wxgEMRTimelinePluginPnl, gmRegetMixin.cRegetOnPaintMixin):
229 """Panel holding a number of widgets. Used as notebook page."""
231 self.__tl_file = None
232 wxgEMRTimelinePluginPnl.wxgEMRTimelinePluginPnl.__init__(self, *args, **kwargs)
233 gmRegetMixin.cRegetOnPaintMixin.__init__(self)
234 # self.__init_ui()
235 self.__register_interests()
236
237 #--------------------------------------------------------
238 # event handling
239 #--------------------------------------------------------
241 gmDispatcher.connect(signal = 'pre_patient_unselection', receiver = self._on_pre_patient_unselection)
242 # gmDispatcher.connect(signal = u'post_patient_selection', receiver = self._schedule_data_reget)
243
244 #--------------------------------------------------------
246 self._PNL_timeline.clear_timeline()
247
248 #--------------------------------------------------------
251
252 #--------------------------------------------------------
271
272 #--------------------------------------------------------
278
279 #--------------------------------------------------------
289
290 #--------------------------------------------------------
293
294 #--------------------------------------------------------
297
298 #--------------------------------------------------------
301
302 #--------------------------------------------------------
305
306 #--------------------------------------------------------
309
310 #--------------------------------------------------------
313
314 #--------------------------------------------------------
315 # notebook plugin glue
316 #--------------------------------------------------------
319
320 #--------------------------------------------------------
321 # internal API
322 #--------------------------------------------------------
323 # def __init_ui(self):
324 # pass
325 #--------------------------------------------------------
326 # reget mixin API
327 #
328 # remember to call
329 # self._schedule_data_reget()
330 # whenever you learn of data changes from database
331 # listener threads, dispatcher signals etc.
332 #--------------------------------------------------------
334 pat = gmPerson.gmCurrentPatient()
335 if not pat.connected:
336 return True
337
338 wx.BeginBusyCursor()
339 try:
340 self.__tl_file = gmTimelineExporter.create_timeline_file(patient = pat)
341 self._PNL_timeline.open_timeline(self.__tl_file)
342 except Exception: # more specifically: TimelineIOError
343 _log.exception('cannot load EMR from timeline XML')
344 self._PNL_timeline.clear_timeline()
345 self.__tl_file = gmTimelineExporter.create_fake_timeline_file(patient = pat)
346 self._PNL_timeline.open_timeline(self.__tl_file)
347 return True
348 finally:
349 wx.EndBusyCursor()
350
351 return True
352
353 #============================================================
354
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Fri Jan 25 02:55:27 2019 | http://epydoc.sourceforge.net |