Package Gnumed :: Package wxpython :: Package gui :: Module gmXdtViewer
[frames] | no frames]

Source Code for Module Gnumed.wxpython.gui.gmXdtViewer

  1  # -*- coding: utf-8 -*- 
  2  """GNUmed xDT viewer. 
  3   
  4  TODO: 
  5   
  6  - popup menu on right-click 
  7    - import this line 
  8    - import all lines like this 
  9    - search 
 10    - print 
 11    - ... 
 12  """ 
 13  #============================================================================= 
 14  __author__ = "S.Hilbert, K.Hilbert" 
 15   
 16  import sys, os, os.path, io, logging 
 17   
 18   
 19  import wx 
 20   
 21   
 22  from Gnumed.wxpython import gmGuiHelpers, gmPlugin 
 23  from Gnumed.pycommon import gmI18N, gmDispatcher 
 24  from Gnumed.business import gmXdtMappings, gmXdtObjects 
 25  from Gnumed.wxGladeWidgets import wxgXdtListPnl 
 26  from Gnumed.wxpython import gmAccessPermissionWidgets 
 27   
 28   
 29  _log = logging.getLogger('gm.ui') 
30 31 #============================================================================= 32 # FIXME: this belongs elsewhere under wxpython/ 33 -class cXdtListPnl(wxgXdtListPnl.wxgXdtListPnl):
34 - def __init__(self, *args, **kwargs):
35 wxgXdtListPnl.wxgXdtListPnl.__init__(self, *args, **kwargs) 36 37 self.filename = None 38 39 self.__cols = [ 40 _('Field name'), 41 _('Interpreted content'), 42 _('xDT field ID'), 43 _('Raw content') 44 ] 45 self.__init_ui()
46 #--------------------------------------------------------------
47 - def __init_ui(self):
48 for col in range(len(self.__cols)): 49 self._LCTRL_xdt.InsertColumn(col, self.__cols[col])
50 #-------------------------------------------------------------- 51 # external API 52 #--------------------------------------------------------------
53 - def select_file(self, path=None):
54 if path is None: 55 root_dir = os.path.expanduser(os.path.join('~', 'gnumed')) 56 else: 57 root_dir = path 58 # get file name 59 # - via file select dialog 60 dlg = wx.FileDialog ( 61 parent = self, 62 message = _("Choose an xDT file"), 63 defaultDir = root_dir, 64 defaultFile = '', 65 wildcard = '%s (*.xDT)|*.?DT;*.?dt|%s (*)|*|%s (*.*)|*.*' % (_('xDT files'), _('all files'), _('all files (Win)')), 66 style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST 67 ) 68 choice = dlg.ShowModal() 69 fname = None 70 if choice == wx.ID_OK: 71 fname = dlg.GetPath() 72 dlg.DestroyLater() 73 return fname
74 #--------------------------------------------------------------
75 - def load_file(self, filename=None):
76 if filename is None: 77 filename = self.select_file() 78 if filename is None: 79 return True 80 81 self.filename = None 82 83 try: 84 f = open(filename, 'r') 85 except IOError: 86 gmGuiHelpers.gm_show_error ( 87 _('Cannot access xDT file\n\n' 88 ' [%s]'), 89 _('loading xDT file') 90 ) 91 return False 92 f.close() 93 94 encoding = gmXdtObjects.determine_xdt_encoding(filename = filename) 95 if encoding is None: 96 encoding = 'utf8' 97 gmDispatcher.send(signal = 'statustext', msg = _('Encoding missing in xDT file. Assuming [%s].') % encoding) 98 _log.warning('xDT file [%s] does not define an encoding, assuming [%s]' % (filename, encoding)) 99 100 try: 101 xdt_file = io.open(filename, mode = 'rt', encoding = encoding, errors = 'replace') 102 except IOError: 103 gmGuiHelpers.gm_show_error ( 104 _('Cannot access xDT file\n\n' 105 ' [%s]'), 106 _('loading xDT file') 107 ) 108 return False 109 110 # parse and display file 111 self._LCTRL_xdt.DeleteAllItems() 112 113 self._LCTRL_xdt.InsertItem(index=0, label=_('name of xDT file')) 114 self._LCTRL_xdt.SetItem(index=0, column=1, label=filename) 115 116 idx = 1 117 for line in xdt_file: 118 line = line.replace('\015','') 119 line = line.replace('\012','') 120 length, field, content = line[:3], line[3:7], line[7:] 121 122 try: 123 left = gmXdtMappings.xdt_id_map[field] 124 except KeyError: 125 left = field 126 127 try: 128 right = gmXdtMappings.xdt_map_of_content_maps[field][content] 129 except KeyError: 130 right = content 131 132 self._LCTRL_xdt.InsertItem(index=idx, label=left) 133 self._LCTRL_xdt.SetItem(index=idx, column=1, label=right) 134 self._LCTRL_xdt.SetItem(index=idx, column=2, label=field) 135 self._LCTRL_xdt.SetItem(index=idx, column=3, label=content) 136 idx += 1 137 138 xdt_file.close() 139 140 self._LCTRL_xdt.SetColumnWidth(0, wx.LIST_AUTOSIZE) 141 self._LCTRL_xdt.SetColumnWidth(1, wx.LIST_AUTOSIZE) 142 143 self._LCTRL_xdt.SetFocus() 144 self._LCTRL_xdt.SetItemState ( 145 item = 0, 146 state = wx.LIST_STATE_SELECTED | wx.LIST_STATE_FOCUSED, 147 stateMask = wx.LIST_STATE_SELECTED | wx.LIST_STATE_FOCUSED 148 ) 149 150 self.filename = filename
151 #-------------------------------------------------------------- 152 # event handlers 153 #--------------------------------------------------------------
154 - def _on_load_button_pressed(self, evt):
155 self.load_file()
156 #-------------------------------------------------------------- 157 # plugin API 158 #--------------------------------------------------------------
159 - def repopulate_ui(self):
160 # if self.filename is None: 161 # self.load_file() 162 return
163 #=============================================================================
164 -class gmXdtViewerPanel(wx.Panel):
165 - def __init__(self, parent, aFileName = None):
166 wx.Panel.__init__(self, parent, -1, style=wx.WANTS_CHARS) 167 168 # our actual list 169 tID = wx.NewId() 170 self.list = gmXdtListCtrl( 171 self, 172 tID, 173 style=wx.LC_REPORT | wx.SUNKEN_BORDER | wx.LC_VRULES 174 )#|wx.LC_HRULES) 175 176 self.list.InsertColumn(0, _("XDT field")) 177 self.list.InsertColumn(1, _("XDT field content")) 178 179 self.filename = aFileName 180 181 # set up events 182 wx.EVT_SIZE(self, self.OnSize) 183 184 wx.EVT_LIST_ITEM_SELECTED(self, tID, self.OnItemSelected) 185 wx.EVT_LIST_ITEM_DESELECTED(self, tID, self.OnItemDeselected) 186 wx.EVT_LIST_ITEM_ACTIVATED(self, tID, self.OnItemActivated) 187 wx.EVT_LIST_DELETE_ITEM(self, tID, self.OnItemDelete) 188 189 wx.EVT_LIST_COL_CLICK(self, tID, self.OnColClick) 190 wx.EVT_LIST_COL_RIGHT_CLICK(self, tID, self.OnColRightClick) 191 # wx.EVT_LIST_COL_BEGIN_DRAG(self, tID, self.OnColBeginDrag) 192 # wx.EVT_LIST_COL_DRAGGING(self, tID, self.OnColDragging) 193 # wx.EVT_LIST_COL_END_DRAG(self, tID, self.OnColEndDrag) 194 195 wx.EVT_LEFT_DCLICK(self.list, self.OnDoubleClick) 196 wx.EVT_RIGHT_DOWN(self.list, self.OnRightDown) 197 198 if wx.Platform == '__WXMSW__': 199 wx.EVT_COMMAND_RIGHT_CLICK(self.list, tID, self.OnRightClick) 200 elif wx.Platform == '__WXGTK__': 201 wx.EVT_RIGHT_UP(self.list, self.OnRightClick)
202 203 #-------------------------------------------------------------------------
204 - def Populate(self):
205 206 # populate list 207 items = self.__decode_xdt() 208 for item_idx in range(len(items),0,-1): 209 data = items[item_idx] 210 idx = self.list.InsertItem(info=wx.ListItem()) 211 self.list.SetItem(index=idx, column=0, label=data[0]) 212 self.list.SetItem(index=idx, column=1, label=data[1]) 213 #self.list.SetItemData(item_idx, item_idx) 214 215 # reaspect 216 self.list.SetColumnWidth(0, wx.LIST_AUTOSIZE) 217 self.list.SetColumnWidth(1, wx.LIST_AUTOSIZE) 218 219 # show how to select an item 220 #self.list.SetItemState(5, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED) 221 222 # show how to change the colour of a couple items 223 #item = self.list.GetItem(1) 224 #item.SetTextColour(wx.BLUE) 225 #self.list.SetItem(item) 226 #item = self.list.GetItem(4) 227 #item.SetTextColour(wxRED) 228 #self.list.SetItem(item) 229 230 self.currentItem = 0
231 #-------------------------------------------------------------------------
232 - def __decode_xdt(self):
233 if self.filename is None: 234 _log.error("Need name of file to parse !") 235 return None 236 237 xDTFile = fileinput.input(self.filename) 238 items = {} 239 i = 1 240 for line in xDTFile: 241 # remove trailing CR and/or LF 242 line = string.replace(line,'\015','') 243 line = string.replace(line,'\012','') 244 length ,ID, content = line[:3], line[3:7], line[7:] 245 246 try: 247 left = xdt_id_map[ID] 248 except KeyError: 249 left = ID 250 251 try: 252 right = xdt_map_of_content_maps[ID][content] 253 except KeyError: 254 right = content 255 256 items[i] = (left, right) 257 i = i + 1 258 259 fileinput.close() 260 return items
261 #-------------------------------------------------------------------------
262 - def OnRightDown(self, event):
263 self.x = event.GetX() 264 self.y = event.GetY() 265 item, flags = self.list.HitTest((self.x, self.y)) 266 if flags & wx.LIST_HITTEST_ONITEM: 267 self.list.Select(item) 268 event.Skip()
269 #-------------------------------------------------------------------------
270 - def getColumnText(self, index, col):
271 item = self.list.GetItem(index, col) 272 return item.GetText()
273 #-------------------------------------------------------------------------
274 - def OnItemSelected(self, event):
275 self.currentItem = event.ItemIndex
276 #-------------------------------------------------------------------------
277 - def OnItemDeselected(self, evt):
278 item = evt.GetItem()
279 280 # Show how to reselect something we don't want deselected 281 # if evt.ItemIndex == 11: 282 # wxCallAfter(self.list.SetItemState, 11, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED) 283 #-------------------------------------------------------------------------
284 - def OnItemActivated(self, event):
285 self.currentItem = event.ItemIndex
286 #-------------------------------------------------------------------------
287 - def OnItemDelete(self, event):
288 pass
289 #-------------------------------------------------------------------------
290 - def OnColClick(self, event):
291 pass
292 #-------------------------------------------------------------------------
293 - def OnColRightClick(self, event):
294 item = self.list.GetColumn(event.GetColumn())
295 #------------------------------------------------------------------------- 296 # def OnColBeginDrag(self, event): 297 # pass 298 #------------------------------------------------------------------------- 299 # def OnColDragging(self, event): 300 # pass 301 #------------------------------------------------------------------------- 302 # def OnColEndDrag(self, event): 303 # pass 304 #-------------------------------------------------------------------------
305 - def OnDoubleClick(self, event):
306 event.Skip()
307 #-------------------------------------------------------------------------
308 - def OnRightClick(self, event):
309 return 310 menu = wx.Menu() 311 tPopupID1 = 0 312 tPopupID2 = 1 313 tPopupID3 = 2 314 tPopupID4 = 3 315 tPopupID5 = 5 316 317 # Show how to put an icon in the menu 318 item = wx.MenuItem(menu, tPopupID1,"One") 319 item.SetBitmap(images.getSmilesBitmap()) 320 321 menu.AppendItem(item) 322 menu.Append(tPopupID2, "Two") 323 menu.Append(tPopupID3, "ClearAll and repopulate") 324 menu.Append(tPopupID4, "DeleteAllItems") 325 menu.Append(tPopupID5, "GetItem") 326 wx.EVT_MENU(self, tPopupID1, self.OnPopupOne) 327 wx.EVT_MENU(self, tPopupID2, self.OnPopupTwo) 328 wx.EVT_MENU(self, tPopupID3, self.OnPopupThree) 329 wx.EVT_MENU(self, tPopupID4, self.OnPopupFour) 330 wx.EVT_MENU(self, tPopupID5, self.OnPopupFive) 331 self.PopupMenu(menu, wxPoint(self.x, self.y)) 332 menu.DestroyLater() 333 event.Skip()
334 #-------------------------------------------------------------------------
335 - def OnPopupOne(self, event):
336 print("FindItem:", self.list.FindItem(-1, "Roxette")) 337 print("FindItemData:", self.list.FindItemData(-1, 11))
338 #-------------------------------------------------------------------------
339 - def OnPopupTwo(self, event):
340 pass
341 #-------------------------------------------------------------------------
342 - def OnPopupThree(self, event):
343 self.list.ClearAll() 344 wx.CallAfter(self.PopulateList)
345 #wxYield() 346 #self.PopulateList() 347 #-------------------------------------------------------------------------
348 - def OnPopupFour(self, event):
349 self.list.DeleteAllItems()
350 #-------------------------------------------------------------------------
351 - def OnPopupFive(self, event):
352 item = self.list.GetItem(self.currentItem) 353 print(item.Text, item.Id, self.list.GetItemData(self.currentItem))
354 #-------------------------------------------------------------------------
355 - def OnSize(self, event):
356 w,h = self.GetClientSize() 357 self.list.SetDimensions(0, 0, w, h)
358 #======================================================
359 -class gmXdtViewer(gmPlugin.cNotebookPlugin):
360 """Plugin to encapsulate xDT list-in-panel viewer""" 361 362 tab_name = _('xDT viewer') 363 required_minimum_role = 'non-clinical access' 364 365 @gmAccessPermissionWidgets.verify_minimum_required_role ( 366 required_minimum_role, 367 activity = _('loading plugin <%s>') % tab_name, 368 return_value_on_failure = False, 369 fail_silently = False 370 )
371 - def register(self):
373 #------------------------------------------------- 374
375 - def name(self):
376 return gmXdtViewer.tab_name
377
378 - def GetWidget(self, parent):
379 self._widget = cXdtListPnl(parent, -1) 380 return self._widget
381
382 - def MenuInfo(self):
383 return ('tools', _('&xDT viewer'))
384
385 - def can_receive_focus(self):
386 return True
387 #====================================================== 388 # main 389 #------------------------------------------------------ 390 if __name__ == '__main__': 391 from Gnumed.pycommon import gmCfg2 392 393 cfg = gmCfg2.gmCfgData() 394 cfg.add_cli(long_options=['xdt-file='])
395 #--------------------- 396 # set up dummy app 397 - class TestApp (wx.App):
398 - def OnInit (self):
399 400 fname = "" 401 # has the user manually supplied a config file on the command line ? 402 fname = cfg.get(option = '--xdt-file', source_order = [('cli', 'return')]) 403 if fname is not None: 404 _log.debug('XDT file is [%s]' % fname) 405 # file valid ? 406 if not os.access(fname, os.R_OK): 407 title = _('Opening xDT file') 408 msg = _('Cannot open xDT file.\n' 409 '[%s]') % fname 410 gmGuiHelpers.gm_show_error(msg, title) 411 return False 412 else: 413 title = _('Opening xDT file') 414 msg = _('You must provide an xDT file on the command line.\n' 415 'Format: --xdt-file=<file>') 416 gmGuiHelpers.gm_show_error(msg, title) 417 return False 418 419 frame = wx.Frame( 420 parent = None, 421 id = -1, 422 title = _("XDT Viewer"), 423 size = wx.Size(800,600) 424 ) 425 pnl = gmXdtViewerPanel(frame, fname) 426 pnl.Populate() 427 frame.Show(1) 428 return True
429 #--------------------- 430 try: 431 app = TestApp () 432 app.MainLoop () 433 except Exception: 434 _log.exception('Unhandled exception.') 435 raise 436 437 #============================================================================= 438