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

# Source Code for Module Gnumed.wxpython.gui.gmXdtViewer

      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/
     34 -class cXdtListPnl(wxgXdtListPnl.wxgXdtListPnl):
     35 -        def __init__(self, *args, **kwargs):
     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          #--------------------------------------------------------------
     48 -        def __init_ui(self):
     49                  for col in range(len(self.__cols)):
     50                          self._LCTRL_xdt.InsertColumn(col, self.__cols[col])
     51          #--------------------------------------------------------------
     52          # external API
     53          #--------------------------------------------------------------
     54 -        def select_file(self, path=None):
     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          #--------------------------------------------------------------
     76 -        def load_file(self, filename=None):
     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          #--------------------------------------------------------------
    155 -        def _on_load_button_pressed(self, evt):
    156                  self.load_file()
    157          #--------------------------------------------------------------
    158          # plugin API
    159          #--------------------------------------------------------------
    160 -        def repopulate_ui(self):
    161  #               if self.filename is None:
    162  #                       self.load_file()
    163                  return
    164  #=============================================================================
    165 -class gmXdtViewerPanel(wx.Panel):
    166 -        def __init__(self, parent, aFileName = None):
    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          #-------------------------------------------------------------------------
    205 -        def Populate(self):
    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          #-------------------------------------------------------------------------
    233 -        def __decode_xdt(self):
    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          #-------------------------------------------------------------------------
    263 -        def OnRightDown(self, event):
    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          #-------------------------------------------------------------------------
    271 -        def getColumnText(self, index, col):
    272                  item = self.list.GetItem(index, col)
    273                  return item.GetText()
    274          #-------------------------------------------------------------------------
    275 -        def OnItemSelected(self, event):
    276                  self.currentItem = event.m_itemIndex
    277          #-------------------------------------------------------------------------
    278 -        def OnItemDeselected(self, evt):
    279                  item = evt.GetItem()
    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          #-------------------------------------------------------------------------
    285 -        def OnItemActivated(self, event):
    286                  self.currentItem = event.m_itemIndex
    287          #-------------------------------------------------------------------------
    288 -        def OnItemDelete(self, event):
    289                  pass
    290          #-------------------------------------------------------------------------
    291 -        def OnColClick(self, event):
    292                  pass
    293          #-------------------------------------------------------------------------
    294 -        def OnColRightClick(self, event):
    295                  item = self.list.GetColumn(event.GetColumn())
    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          #-------------------------------------------------------------------------
    306 -        def OnDoubleClick(self, event):
    307                  event.Skip()
    308          #-------------------------------------------------------------------------
    309 -        def OnRightClick(self, event):
    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          #-------------------------------------------------------------------------
    336 -        def OnPopupOne(self, event):
    337                  print "FindItem:", self.list.FindItem(-1, "Roxette")
    338                  print "FindItemData:", self.list.FindItemData(-1, 11)
    339          #-------------------------------------------------------------------------
    340 -        def OnPopupTwo(self, event):
    341                  pass
    342          #-------------------------------------------------------------------------
    343 -        def OnPopupThree(self, event):
    344                  self.list.ClearAll()
    345                  wx.CallAfter(self.PopulateList)
    346                  #wxYield()
    347                  #self.PopulateList()
    348          #-------------------------------------------------------------------------
    349 -        def OnPopupFour(self, event):
    350                  self.list.DeleteAllItems()
    351          #-------------------------------------------------------------------------
    352 -        def OnPopupFive(self, event):
    353                  item = self.list.GetItem(self.currentItem)
    354                  print item.m_text, item.m_itemId, self.list.GetItemData(self.currentItem)
    355          #-------------------------------------------------------------------------
    356 -        def OnSize(self, event):
    357                  w,h = self.GetClientSizeTuple()
    358                  self.list.SetDimensions(0, 0, w, h)
    359  #======================================================
    360 -class gmXdtViewer(gmPlugin.cNotebookPlugin):
    361          """Plugin to encapsulate xDT list-in-panel viewer"""
    362
    363          tab_name = _('xDT viewer')
    364
    365 -        def name(self):
    366                  return gmXdtViewer.tab_name
    367
    368 -        def GetWidget(self, parent):
    369                  self._widget = cXdtListPnl(parent, -1)
    370                  return self._widget
    371
    372 -        def MenuInfo(self):
    373                  return ('tools', _('&xDT viewer'))
    374
    375 -        def can_receive_focus(self):
    376                  return True
    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
    387 -        class TestApp (wx.App):
    388 -                def OnInit (self):
    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