Package Gnumed :: Package wxpython :: Module gmPatPicWidgets |
[frames] | no frames]

# Source Code for Module Gnumed.wxpython.gmPatPicWidgets

      1  """GNUmed patient picture widget."""
      2
      3  #=====================================================================
      4  __author__  = "R.Terry <rterry@gnumed.net>,\
      5                             I.Haywood <i.haywood@ugrad.unimelb.edu.au>,\
      6                             K.Hilbert <Karsten.Hilbert@gmx.net>"
      7  __license__ = "GPL v2 or later"
      8
      9  # standard lib
     10  import sys, os, os.path, logging
     11
     12
     13  # 3rd party
     14  import wx, wx.lib.imagebrowser
     15
     16
     17  # GNUmed
     18  from Gnumed.pycommon import gmDispatcher, gmTools, gmI18N
     19  from Gnumed.business import gmDocuments, gmPerson
     20  from Gnumed.wxpython import gmGuiHelpers
     21
     22
     23  _log = logging.getLogger('gm.ui')
     24
     25
     26  ID_AcquirePhoto = wx.NewId()
     27  ID_ImportPhoto = wx.NewId()
     28  ID_Refresh = wx.NewId()
     29
     30  #=====================================================================
     31 -class cPatientPicture(wx.StaticBitmap):
     32          """A patient picture control ready for display.
     33                  with popup menu to import/export
     34                  remove or Acquire from a device
     35          """
     36 -        def __init__(self, *args, **kwargs):
     37
     38                  wx.StaticBitmap.__init__(self, *args, **kwargs)
     39
     40                  paths = gmTools.gmPaths(app_name = u'gnumed', wx = wx)
     41                  self.__fallback_pic_name = os.path.join(paths.system_app_data_dir, 'bitmaps', 'empty-face-in-bust.png')
     42                  self.__desired_width = 50
     43                  self.__desired_height = 54
     44                  self.__pat = gmPerson.gmCurrentPatient()
     45
     46                  self.__init_ui()
     47                  self.__register_events()
     48          #-----------------------------------------------------------------
     49          # event handling
     50          #-----------------------------------------------------------------
     51 -        def __register_events(self):
     52                  # wxPython events
     53                  wx.EVT_RIGHT_UP(self, self._on_RightClick_photo)
     54                  wx.EVT_MENU(self, ID_AcquirePhoto, self._on_AcquirePhoto)
     55                  wx.EVT_MENU(self, ID_ImportPhoto, self._on_ImportPhoto)
     56                  wx.EVT_MENU(self, ID_Refresh, self._on_refresh_from_backend)
     57
     58                  # dispatcher signals
     59                  gmDispatcher.connect(receiver=self._on_post_patient_selection, signal = u'post_patient_selection')
     60          #-----------------------------------------------------------------
     61 -        def _on_post_patient_selection(self):
     62                  self.__reload_photo()
     63          #-----------------------------------------------------------------
     64 -        def _on_RightClick_photo(self, event):
     65                  if not self.__pat.connected:
     66                          gmDispatcher.send(signal='statustext', msg=_('No active patient.'))
     67                          return False
     68                  self.PopupMenu(self.__photo_menu, event.GetPosition())
     69          #-----------------------------------------------------------------
     70 -        def _on_refresh_from_backend(self, evt):
     71                  self.__reload_photo()
     72          #-----------------------------------------------------------------
     73 -        def _on_ImportPhoto(self, event):
     74                  """Import an existing photo."""
     75
     76                  # get from file system
     77                  imp_dlg = wx.lib.imagebrowser.ImageDialog(parent = self, set_dir = os.path.expanduser('~'))
     78                  imp_dlg.Centre()
     79                  if imp_dlg.ShowModal() != wx.ID_OK:
     80                          return
     81
     82                  self.__import_pic_into_db(fname = imp_dlg.GetFile())
     83                  self.__reload_photo()
     84          #-----------------------------------------------------------------
     85 -        def _on_AcquirePhoto(self, event):
     86
     87                  # get from image source
     88                  from Gnumed.pycommon import gmScanBackend
     89
     90                  try:
     91                          fnames = gmScanBackend.acquire_pages_into_files (
     92                                  delay = 5,
     93                                  tmpdir = os.path.expanduser(os.path.join('~', '.gnumed', 'tmp')),
     94                                  calling_window = self
     95                          )
     96                  except OSError:
     97                          _log.exception('problem acquiring image from source')
     98                          gmGuiHelpers.gm_show_error (
     99                                  aMessage = _(
    100                                          'No image could be acquired from the source.\n\n'
    101                                          'This may mean the scanner driver is not properly installed.\n\n'
    102                                          'On Windows you must install the TWAIN Python module\n'
    103                                          'while on Linux and MacOSX it is recommended to install\n'
    104                                          'the XSane package.'
    105                                  ),
    106                                  aTitle = _('Acquiring photo')
    107                          )
    108                          return
    109
    110                  if fnames is False:
    111                          gmGuiHelpers.gm_show_error (
    112                                  aMessage = _('Patient photo could not be acquired from source.'),
    113                                  aTitle = _('Acquiring photo')
    114                          )
    115                          return
    116
    117                  if len(fnames) == 0:            # no pages scanned
    118                          return
    119
    120                  self.__import_pic_into_db(fname=fnames[0])
    121                  self.__reload_photo()
    122          #-----------------------------------------------------------------
    123          # internal API
    124          #-----------------------------------------------------------------
    125 -        def __init_ui(self):
    126                  # pre-make context menu
    127                  self.__photo_menu = wx.Menu()
    128                  self.__photo_menu.Append(ID_Refresh, _('Refresh from database'))
    129                  self.__photo_menu.AppendSeparator()
    130                  self.__photo_menu.Append(ID_AcquirePhoto, _("Acquire from imaging device"))
    131                  self.__photo_menu.Append(ID_ImportPhoto, _("Import from file"))
    132
    133                  self.__set_pic_from_file()
    134          #-----------------------------------------------------------------
    135 -        def __import_pic_into_db(self, fname=None):
    136
    137                  docs = gmDocuments.search_for_document(patient_id = self.__pat.ID, type_id = gmDocuments.MUGSHOT)
    138                  if len(docs) == 0:
    139                          emr = self.__pat.get_emr()
    140                          epi = emr.add_episode(episode_name=_('Administration'))
    141                          enc = emr.active_encounter
    142                          doc = gmDocuments.create_document (
    143                                  document_type = gmDocuments.MUGSHOT,
    144                                  episode = epi['pk_episode'],
    145                                  encounter = enc['pk_encounter']
    146                          )
    147                  else:
    148                          doc = docs[0]
    149
    150                  obj = doc.add_part(file=fname)
    151                  return True
    152          #-----------------------------------------------------------------
    153 -        def __reload_photo(self):
    154                  """(Re)fetch patient picture from DB."""
    155
    156                  doc_folder = self.__pat.get_document_folder()
    157                  photo = doc_folder.get_latest_mugshot()
    158
    159                  if photo is None:
    160                          fname = None
    161                          self.SetToolTipString (_(
    162                                  'Patient picture.\n'
    163                                  '\n'
    164                                  'Right-click for context menu.'
    165                          ))
    166  #                       gmDispatcher.send(signal='statustext', msg=_('Cannot get most recent patient photo from database.'))
    167                  else:
    168                          fname = photo.export_to_file()
    169                          self.SetToolTipString (_(
    170                                  'Patient picture (%s).\n'
    171                                  '\n'
    172                                  'Right-click for context menu.'
    173                          ) % photo['date_generated'].strftime('%b %Y').decode(gmI18N.get_encoding()))
    174
    175                  return self.__set_pic_from_file(fname)
    176          #-----------------------------------------------------------------
    177 -        def __set_pic_from_file(self, fname=None):
    178                  if fname is None:
    179                          fname = self.__fallback_pic_name
    180                  try:
    181                          img_data = wx.Image(fname, wx.BITMAP_TYPE_ANY)
    182                          img_data.Rescale(self.__desired_width, self.__desired_height)
    183                          bmp_data = wx.BitmapFromImage(img_data)
    184                  except:
    185                          _log.exception('cannot set patient picture from [%s]', fname)
    186                          gmDispatcher.send(signal='statustext', msg=_('Cannot set patient picture from [%s].') % fname)
    187                          return False
    188                  del img_data
    189                  self.SetBitmap(bmp_data)
    190                  self.__pic_name = fname
    191
    192                  return True
    193
    194  #====================================================
    195  # main
    196  #----------------------------------------------------
    197  if __name__ == "__main__":
    198          app = wx.PyWidgetTester(size = (200, 200))
    199          app.SetWidget(cPatientPicture, -1)
    200          app.MainLoop()
    201  #====================================================
    202