| Home | Trees | Indices | Help |
|
|---|
|
|
1 """GNUmed xDT viewer.
2
3 TODO:
4
5 - popup menu on right-click
6 - import this line
7 - import all lines like this
8 - search
9 - print
10 - ...
11 """
12 #=============================================================================
13 # $Source: /home/ncq/Projekte/cvs2git/vcs-mirror/gnumed/gnumed/client/wxpython/gui/gmXdtViewer.py,v $
14 # $Id: gmXdtViewer.py,v 1.39 2009-06-29 15:12:49 ncq Exp $
15 __version__ = "$Revision: 1.39 $"
16 __author__ = "S.Hilbert, K.Hilbert"
17
18 import sys, os, os.path, codecs, logging
19
20
21 import wx
22
23
24 from Gnumed.wxpython import gmGuiHelpers, gmPlugin
25 from Gnumed.pycommon import gmI18N, gmDispatcher
26 from Gnumed.business import gmXdtMappings, gmXdtObjects
27 from Gnumed.wxGladeWidgets import wxgXdtListPnl
28
29 _log = logging.getLogger('gm.ui')
30 _log.info(__version__)
31
32 #=============================================================================
33 # FIXME: this belongs elsewhere under wxpython/
36 wxgXdtListPnl.wxgXdtListPnl.__init__(self, *args, **kwargs)
37
38 self.filename = None
39
40 self.__cols = [
41 _('Field name'),
42 _('Interpreted content'),
43 _('xDT field ID'),
44 _('Raw content')
45 ]
46 self.__init_ui()
47 #--------------------------------------------------------------
51 #--------------------------------------------------------------
52 # external API
53 #--------------------------------------------------------------
55 if path is None:
56 root_dir = os.path.expanduser(os.path.join('~', 'gnumed', 'xDT'))
57 else:
58 root_dir = path
59 # get file name
60 # - via file select dialog
61 dlg = wx.FileDialog (
62 parent = self,
63 message = _("Choose an xDT file"),
64 defaultDir = root_dir,
65 defaultFile = '',
66 wildcard = '%s (*.xDT)|*.?DT;*.?dt|%s (*)|*|%s (*.*)|*.*' % (_('xDT files'), _('all files'), _('all files (Win)')),
67 style = wx.OPEN | wx.FILE_MUST_EXIST
68 )
69 choice = dlg.ShowModal()
70 fname = None
71 if choice == wx.ID_OK:
72 fname = dlg.GetPath()
73 dlg.Destroy()
74 return fname
75 #--------------------------------------------------------------
77 if filename is None:
78 filename = self.select_file()
79 if filename is None:
80 return True
81
82 self.filename = None
83
84 try:
85 f = file(filename, 'r')
86 except IOError:
87 gmGuiHelpers.gm_show_error (
88 _('Cannot access xDT file\n\n'
89 ' [%s]'),
90 _('loading xDT file')
91 )
92 return False
93 f.close()
94
95 encoding = gmXdtObjects.determine_xdt_encoding(filename = filename)
96 if encoding is None:
97 encoding = 'utf8'
98 gmDispatcher.send(signal = 'statustext', msg = _('Encoding missing in xDT file. Assuming [%s].') % encoding)
99 _log.warning('xDT file [%s] does not define an encoding, assuming [%s]' % (filename, encoding))
100
101 try:
102 xdt_file = codecs.open(filename=filename, mode='rU', encoding=encoding, errors='replace')
103 except IOError:
104 gmGuiHelpers.gm_show_error (
105 _('Cannot access xDT file\n\n'
106 ' [%s]'),
107 _('loading xDT file')
108 )
109 return False
110
111 # parse and display file
112 self._LCTRL_xdt.DeleteAllItems()
113
114 self._LCTRL_xdt.InsertStringItem(index=0, label=_('name of xDT file'))
115 self._LCTRL_xdt.SetStringItem(index=0, col=1, label=filename)
116
117 idx = 1
118 for line in xdt_file:
119 line = line.replace('\015','')
120 line = line.replace('\012','')
121 length, field, content = line[:3], line[3:7], line[7:]
122
123 try:
124 left = gmXdtMappings.xdt_id_map[field]
125 except KeyError:
126 left = field
127
128 try:
129 right = gmXdtMappings.xdt_map_of_content_maps[field][content]
130 except KeyError:
131 right = content
132
133 self._LCTRL_xdt.InsertStringItem(index=idx, label=left)
134 self._LCTRL_xdt.SetStringItem(index=idx, col=1, label=right)
135 self._LCTRL_xdt.SetStringItem(index=idx, col=2, label=field)
136 self._LCTRL_xdt.SetStringItem(index=idx, col=3, label=content)
137 idx += 1
138
139 xdt_file.close()
140
141 self._LCTRL_xdt.SetColumnWidth(0, wx.LIST_AUTOSIZE)
142 self._LCTRL_xdt.SetColumnWidth(1, wx.LIST_AUTOSIZE)
143
144 self._LCTRL_xdt.SetFocus()
145 self._LCTRL_xdt.SetItemState (
146 item = 0,
147 state = wx.LIST_STATE_SELECTED | wx.LIST_STATE_FOCUSED,
148 stateMask = wx.LIST_STATE_SELECTED | wx.LIST_STATE_FOCUSED
149 )
150
151 self.filename = filename
152 #--------------------------------------------------------------
153 # event handlers
154 #--------------------------------------------------------------
157 #--------------------------------------------------------------
158 # plugin API
159 #--------------------------------------------------------------
164 #=============================================================================
167 wx.Panel.__init__(self, parent, -1, style=wx.WANTS_CHARS)
168
169 # our actual list
170 tID = wx.NewId()
171 self.list = gmXdtListCtrl(
172 self,
173 tID,
174 style=wx.LC_REPORT | wx.SUNKEN_BORDER | wx.LC_VRULES
175 )#|wx.LC_HRULES)
176
177 self.list.InsertColumn(0, _("XDT field"))
178 self.list.InsertColumn(1, _("XDT field content"))
179
180 self.filename = aFileName
181
182 # set up events
183 wx.EVT_SIZE(self, self.OnSize)
184
185 wx.EVT_LIST_ITEM_SELECTED(self, tID, self.OnItemSelected)
186 wx.EVT_LIST_ITEM_DESELECTED(self, tID, self.OnItemDeselected)
187 wx.EVT_LIST_ITEM_ACTIVATED(self, tID, self.OnItemActivated)
188 wx.EVT_LIST_DELETE_ITEM(self, tID, self.OnItemDelete)
189
190 wx.EVT_LIST_COL_CLICK(self, tID, self.OnColClick)
191 wx.EVT_LIST_COL_RIGHT_CLICK(self, tID, self.OnColRightClick)
192 # wx.EVT_LIST_COL_BEGIN_DRAG(self, tID, self.OnColBeginDrag)
193 # wx.EVT_LIST_COL_DRAGGING(self, tID, self.OnColDragging)
194 # wx.EVT_LIST_COL_END_DRAG(self, tID, self.OnColEndDrag)
195
196 wx.EVT_LEFT_DCLICK(self.list, self.OnDoubleClick)
197 wx.EVT_RIGHT_DOWN(self.list, self.OnRightDown)
198
199 if wx.Platform == '__WXMSW__':
200 wx.EVT_COMMAND_RIGHT_CLICK(self.list, tID, self.OnRightClick)
201 elif wx.Platform == '__WXGTK__':
202 wx.EVT_RIGHT_UP(self.list, self.OnRightClick)
203
204 #-------------------------------------------------------------------------
206
207 # populate list
208 items = self.__decode_xdt()
209 for item_idx in range(len(items),0,-1):
210 data = items[item_idx]
211 idx = self.list.InsertItem(info=wx.ListItem())
212 self.list.SetStringItem(index=idx, col=0, label=data[0])
213 self.list.SetStringItem(index=idx, col=1, label=data[1])
214 #self.list.SetItemData(item_idx, item_idx)
215
216 # reaspect
217 self.list.SetColumnWidth(0, wx.LIST_AUTOSIZE)
218 self.list.SetColumnWidth(1, wx.LIST_AUTOSIZE)
219
220 # show how to select an item
221 #self.list.SetItemState(5, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED)
222
223 # show how to change the colour of a couple items
224 #item = self.list.GetItem(1)
225 #item.SetTextColour(wx.BLUE)
226 #self.list.SetItem(item)
227 #item = self.list.GetItem(4)
228 #item.SetTextColour(wxRED)
229 #self.list.SetItem(item)
230
231 self.currentItem = 0
232 #-------------------------------------------------------------------------
234 if self.filename is None:
235 _log.error("Need name of file to parse !")
236 return None
237
238 xDTFile = fileinput.input(self.filename)
239 items = {}
240 i = 1
241 for line in xDTFile:
242 # remove trailing CR and/or LF
243 line = string.replace(line,'\015','')
244 line = string.replace(line,'\012','')
245 length ,ID, content = line[:3], line[3:7], line[7:]
246
247 try:
248 left = xdt_id_map[ID]
249 except KeyError:
250 left = ID
251
252 try:
253 right = xdt_map_of_content_maps[ID][content]
254 except KeyError:
255 right = content
256
257 items[i] = (left, right)
258 i = i + 1
259
260 fileinput.close()
261 return items
262 #-------------------------------------------------------------------------
264 self.x = event.GetX()
265 self.y = event.GetY()
266 item, flags = self.list.HitTest((self.x, self.y))
267 if flags & wx.LIST_HITTEST_ONITEM:
268 self.list.Select(item)
269 event.Skip()
270 #-------------------------------------------------------------------------
274 #-------------------------------------------------------------------------
277 #-------------------------------------------------------------------------
280
281 # Show how to reselect something we don't want deselected
282 # if evt.m_itemIndex == 11:
283 # wxCallAfter(self.list.SetItemState, 11, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED)
284 #-------------------------------------------------------------------------
287 #-------------------------------------------------------------------------
290 #-------------------------------------------------------------------------
293 #-------------------------------------------------------------------------
296 #-------------------------------------------------------------------------
297 # def OnColBeginDrag(self, event):
298 # pass
299 #-------------------------------------------------------------------------
300 # def OnColDragging(self, event):
301 # pass
302 #-------------------------------------------------------------------------
303 # def OnColEndDrag(self, event):
304 # pass
305 #-------------------------------------------------------------------------
308 #-------------------------------------------------------------------------
310 return
311 menu = wx.Menu()
312 tPopupID1 = 0
313 tPopupID2 = 1
314 tPopupID3 = 2
315 tPopupID4 = 3
316 tPopupID5 = 5
317
318 # Show how to put an icon in the menu
319 item = wx.MenuItem(menu, tPopupID1,"One")
320 item.SetBitmap(images.getSmilesBitmap())
321
322 menu.AppendItem(item)
323 menu.Append(tPopupID2, "Two")
324 menu.Append(tPopupID3, "ClearAll and repopulate")
325 menu.Append(tPopupID4, "DeleteAllItems")
326 menu.Append(tPopupID5, "GetItem")
327 wx.EVT_MENU(self, tPopupID1, self.OnPopupOne)
328 wx.EVT_MENU(self, tPopupID2, self.OnPopupTwo)
329 wx.EVT_MENU(self, tPopupID3, self.OnPopupThree)
330 wx.EVT_MENU(self, tPopupID4, self.OnPopupFour)
331 wx.EVT_MENU(self, tPopupID5, self.OnPopupFive)
332 self.PopupMenu(menu, wxPoint(self.x, self.y))
333 menu.Destroy()
334 event.Skip()
335 #-------------------------------------------------------------------------
337 print "FindItem:", self.list.FindItem(-1, "Roxette")
338 print "FindItemData:", self.list.FindItemData(-1, 11)
339 #-------------------------------------------------------------------------
342 #-------------------------------------------------------------------------
346 #wxYield()
347 #self.PopulateList()
348 #-------------------------------------------------------------------------
351 #-------------------------------------------------------------------------
353 item = self.list.GetItem(self.currentItem)
354 print item.m_text, item.m_itemId, self.list.GetItemData(self.currentItem)
355 #-------------------------------------------------------------------------
359 #======================================================
361 """Plugin to encapsulate xDT list-in-panel viewer"""
362
363 tab_name = _('xDT viewer')
364
367
371
373 return ('tools', _('&xDT viewer'))
374
377 #======================================================
378 # main
379 #------------------------------------------------------
380 if __name__ == '__main__':
381 from Gnumed.pycommon import gmCfg2
382
383 cfg = gmCfg2.gmCfgData()
384 cfg.add_cli(long_options=['xdt-file='])
385 #---------------------
386 # set up dummy app
389
390 fname = ""
391 # has the user manually supplied a config file on the command line ?
392 fname = cfg.get(option = '--xdt-file', source_order = [('cli', 'return')])
393 if fname is not None:
394 _log.debug('XDT file is [%s]' % fname)
395 # file valid ?
396 if not os.access(fname, os.R_OK):
397 title = _('Opening xDT file')
398 msg = _('Cannot open xDT file.\n'
399 '[%s]') % fname
400 gmGuiHelpers.gm_show_error(msg, title)
401 return False
402 else:
403 title = _('Opening xDT file')
404 msg = _('You must provide an xDT file on the command line.\n'
405 'Format: --xdt-file=<file>')
406 gmGuiHelpers.gm_show_error(msg, title)
407 return False
408
409 frame = wx.Frame(
410 parent = None,
411 id = -1,
412 title = _("XDT Viewer"),
413 size = wx.Size(800,600)
414 )
415 pnl = gmXdtViewerPanel(frame, fname)
416 pnl.Populate()
417 frame.Show(1)
418 return True
419 #---------------------
420 try:
421 app = TestApp ()
422 app.MainLoop ()
423 except StandardError:
424 _log.exception('Unhandled exception.')
425 raise
426
427 #=============================================================================
428 # $Log: gmXdtViewer.py,v $
429 # Revision 1.39 2009-06-29 15:12:49 ncq
430 # - do not force loading of an xDT file on tab-in anymore
431 #
432 # Revision 1.38 2009/01/15 11:41:18 ncq
433 # - improved list layout
434 #
435 # Revision 1.37 2008/03/06 18:32:31 ncq
436 # - standard lib logging only
437 #
438 # Revision 1.36 2008/01/30 14:03:42 ncq
439 # - use signal names directly
440 # - switch to std lib logging
441 #
442 # Revision 1.35 2008/01/28 16:15:50 ncq
443 # - fix typo
444 #
445 # Revision 1.34 2008/01/22 12:26:24 ncq
446 # - better tab names
447 #
448 # Revision 1.33 2008/01/05 16:42:02 ncq
449 # - no more logging in gm_show_*()
450 #
451 # Revision 1.32 2007/12/26 20:19:34 ncq
452 # - add = to long options
453 #
454 # Revision 1.31 2007/12/26 14:35:51 ncq
455 # - move to gmLog2/gmCfg2
456 #
457 # Revision 1.30 2007/12/11 12:49:26 ncq
458 # - explicit signal handling
459 #
460 # Revision 1.29 2007/08/29 14:43:43 ncq
461 # - show xDT field ID in third column to enable more comfortable debugging
462 #
463 # Revision 1.28 2007/08/12 00:12:41 ncq
464 # - no more gmSignals.py
465 #
466 # Revision 1.27 2007/05/21 13:06:39 ncq
467 # - proper chatch-all wildcard * rather than *.*
468 #
469 # Revision 1.26 2007/05/14 13:11:25 ncq
470 # - use statustext() signal
471 #
472 # Revision 1.25 2007/01/21 12:22:44 ncq
473 # - use determine_xdt_encoding()
474 #
475 # Revision 1.24 2006/11/24 10:01:31 ncq
476 # - gm_beep_statustext() -> gm_statustext()
477 #
478 # Revision 1.23 2006/10/31 16:05:40 ncq
479 # - exit first scan as soon as encoding was found
480 # - assume iso8859-1 if not found
481 # - display LDT file name in first line of list control
482 #
483 # Revision 1.22 2006/10/30 16:48:13 ncq
484 # - bring back in line with the plugin framework
485 #
486 # Revision 1.21 2006/07/19 20:32:11 ncq
487 # - cleanup
488 #
489 # Revision 1.20 2005/12/06 16:44:16 ncq
490 # - make it work standalone again
491 #
492 # Revision 1.19 2005/09/28 21:27:30 ncq
493 # - a lot of wx2.6-ification
494 #
495 # Revision 1.18 2005/09/26 18:01:52 ncq
496 # - use proper way to import wx26 vs wx2.4
497 # - note: THIS WILL BREAK RUNNING THE CLIENT IN SOME PLACES
498 # - time for fixup
499 #
500 # Revision 1.17 2004/08/04 17:16:02 ncq
501 # - wx.NotebookPlugin -> cNotebookPlugin
502 # - derive cNotebookPluginOld from cNotebookPlugin
503 # - make cNotebookPluginOld warn on use and implement old
504 # explicit "main.notebook.raised_plugin"/ReceiveFocus behaviour
505 # - ReceiveFocus() -> receive_focus()
506 #
507 # Revision 1.16 2004/06/25 12:37:21 ncq
508 # - eventually fix the import gmI18N issue
509 #
510 # Revision 1.15 2004/06/13 22:31:49 ncq
511 # - gb['main.toolbar'] -> gb['main.top_panel']
512 # - self.internal_name() -> self.__class__.__name__
513 # - remove set_widget_reference()
514 # - cleanup
515 # - fix lazy load in _on_patient_selected()
516 # - fix lazy load in ReceiveFocus()
517 # - use self._widget in self.GetWidget()
518 # - override populate_with_data()
519 # - use gb['main.notebook.raised_plugin']
520 #
521 # Revision 1.14 2004/03/19 20:43:32 shilbert
522 # - fixed import
523 #
524 # Revision 1.13 2004/03/19 10:22:12 ncq
525 # - even better help
526 #
527 # Revision 1.12 2004/03/19 10:20:29 ncq
528 # - in standalone, display nice message upon xdt file load errors
529 #
530 # Revision 1.11 2004/03/19 08:27:50 ncq
531 # - fix imports, return BOOL from OnInit
532 #
533 # Revision 1.10 2004/03/18 09:43:02 ncq
534 # - import gmI18N if standalone
535 #
536 # Revision 1.9 2003/11/17 10:56:41 sjtan
537 #
538 # synced and commiting.
539 #
540 # Revision 1.1 2003/10/23 06:02:40 sjtan
541 #
542 # manual edit areas modelled after r.terry's specs.
543 #
544 # Revision 1.8 2003/06/26 21:41:51 ncq
545 # - fatal->verbose
546 #
547 # Revision 1.7 2003/04/28 12:12:18 ncq
548 # - refactor name(), better CANCEL handling on file select dialog
549 #
550 # Revision 1.6 2003/04/25 13:04:39 ncq
551 # - reorder variable use so fname is defined when logging
552 #
553 # Revision 1.5 2003/02/19 15:56:33 ncq
554 # - don't fail on malformed lines
555 #
556 # Revision 1.4 2003/02/19 12:42:38 ncq
557 # - further dict()ified __decode_xdt()
558 #
559 # Revision 1.3 2003/02/16 13:54:47 ncq
560 # - renamed command line option to --xdt-file=
561 #
562 # Revision 1.2 2003/02/15 15:33:58 ncq
563 # - typo
564 #
565 # Revision 1.1 2003/02/15 14:21:49 ncq
566 # - on demand loading of Manual
567 # - further pluginization of showmeddocs
568 #
569 # Revision 1.5 2003/02/15 13:52:08 ncq
570 # - hey, works as a plugin too, now :-))
571 #
572 # Revision 1.4 2003/02/15 12:17:28 ncq
573 # - much better suited for plugin use
574 #
575 # Revision 1.3 2003/02/15 10:53:10 ncq
576 # - works standalone
577 #
578 # Revision 1.2 2003/02/13 15:51:09 ncq
579 # - added TODO
580 #
581 # Revision 1.1 2003/02/13 15:25:15 ncq
582 # - first version, works standalone only
583 #
584
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Mon Nov 29 04:04:47 2010 | http://epydoc.sourceforge.net |