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

# Source Code for Module Gnumed.wxpython.gmFormWidgets

      1  """GNUmed form/letter handling widgets."""
      2
      3  #================================================================
      4  __author__ = "Karsten Hilbert <Karsten.Hilbert@gmx.net>"
      5  __license__ = "GPL v2 or later"
      6
      7
      8  import os.path
      9  import sys
     10  import logging
     11
     12
     13  import wx
     14
     15
     16  if __name__ == '__main__':
     17          sys.path.insert(0, '../../')
     18  from Gnumed.pycommon import gmI18N
     19  from Gnumed.pycommon import gmTools
     20  from Gnumed.pycommon import gmDispatcher
     21  from Gnumed.pycommon import gmPrinting
     22  from Gnumed.pycommon import gmDateTime
     23
     24  from Gnumed.business import gmForms
     25  from Gnumed.business import gmPerson
     26
     27  from Gnumed.wxpython import gmGuiHelpers
     28  from Gnumed.wxpython import gmListWidgets
     29  from Gnumed.wxpython import gmMacro
     30
     31
     32  _log = logging.getLogger('gm.ui')
     33
     34  #============================================================
     35  # convenience functions
     36  #============================================================
     37 -def print_doc_from_template(parent=None, jobtype=None, keep_a_copy=True, episode=None):
     38
     39          if parent is None:
     40                  parent = wx.GetApp().GetTopWindow()
     41
     42          # 1) get template
     43          template = manage_form_templates(parent = parent, active_only = True, excluded_types = ['gnuplot script', 'visual progress note', 'invoice'])
     44          if template is None:
     45                  gmDispatcher.send(signal = 'statustext', msg = _('No document template selected.'))
     46                  return None
     47
     48          if template['engine'] == u'O':
     49                  return print_doc_from_ooo_template(template = template)
     50
     51          wx.BeginBusyCursor()
     52
     53          # 2) process template
     54          try:
     55                  form = template.instantiate()
     56          except KeyError:
     57                  wx.EndBusyCursor()
     58                  gmGuiHelpers.gm_show_error (
     59                          aMessage = _('Error creating printable document.\n\nThere is no engine for this type of template.'),
     60                          aTitle = _('Printing document')
     61                  )
     62                  return False
     63          ph = gmMacro.gmPlaceholderHandler()
     64          #ph.debug = True
     65          form.substitute_placeholders(data_source = ph)
     66          form.edit()
     67          printable_file = form.generate_output()
     68          if printable_file is None:
     69                  wx.EndBusyCursor()
     70                  gmGuiHelpers.gm_show_error (
     71                          aMessage = _('Error creating printable document.'),
     72                          aTitle = _('Printing document')
     73                  )
     74                  return False
     75
     76          # 3) print template
     77          if jobtype is None:
     78                  jobtype = 'generic_document'
     79
     80          printed = gmPrinting.print_files(filenames = [printable_file], jobtype = jobtype)
     81          if not printed:
     82                  wx.EndBusyCursor()
     83                  gmGuiHelpers.gm_show_error (
     84                          aMessage = _('Error printing document (%s).') % jobtype,
     85                          aTitle = _('Printing document')
     86                  )
     87                  return False
     88
     89          pat = gmPerson.gmCurrentPatient()
     90          emr = pat.get_emr()
     91          if episode is None:
     92                  episode = emr.add_episode(episode_name = 'administration', is_open = False)
     93          emr.add_clin_narrative (
     94                  soap_cat = None,
     95                  note = _('%s printed from template [%s - %s]') % (jobtype, template['name_long'], template['external_version']),
     96                  episode = episode
     97          )
     98
     99          # 4) keep a copy
    100          if keep_a_copy:
    101                  files2import = []
    102                  files2import.extend(form.final_output_filenames)
    103                  files2import.extend(form.re_editable_filenames)
    104                  gmDispatcher.send (
    105                          signal = u'import_document_from_files',
    106                          filenames = files2import,
    107                          document_type = template['instance_type'],
    108                          unlock_patient = True
    109                  )
    110
    111          wx.EndBusyCursor()
    112
    113          return True
    114  #------------------------------------------------------------
    115  # eventually this should become superfluous when there's a
    116  # standard engine wrapper around OOo
    117 -def print_doc_from_ooo_template(template=None):
    118
    119          # export template to file
    120          filename = template.export_to_file()
    121          if filename is None:
    122                  gmGuiHelpers.gm_show_error (
    123                          _(      'Error exporting form template\n'
    124                                  '\n'
    125                                  ' "%s" (%s)'
    126                          ) % (template['name_long'], template['external_version']),
    127                          _('Letter template export')
    128                  )
    129                  return False
    130
    131          try:
    132                  doc = gmForms.cOOoLetter(template_file = filename, instance_type = template['instance_type'])
    133          except ImportError:
    134                  gmGuiHelpers.gm_show_error (
    135                          _('Cannot connect to OpenOffice.\n\n'
    136                            'The UNO bridge module for Python\n'
    137                            'is not installed.'
    138                          ),
    139                          _('Letter writer')
    140                  )
    141                  return False
    142
    143          if not doc.open_in_ooo():
    144                  gmGuiHelpers.gm_show_error (
    145                          _('Cannot connect to OpenOffice.\n'
    146                            '\n'
    147                            'You may want to increase the option\n'
    148                            '\n'
    149                            ' <%s>'
    150                          ) % _('OOo startup time'),
    151                          _('Letter writer')
    152                  )
    153                  try: os.remove(filename)
    154                  except: pass
    155                  return False
    156
    157          doc.show(False)
    158          ph_handler = gmMacro.gmPlaceholderHandler()
    159          doc.replace_placeholders(handler = ph_handler)
    160
    161          filename = filename.replace('.ott', '.odt').replace('-FormTemplate-', '-FormInstance-')
    162          doc.save_in_ooo(filename = filename)
    163
    164          doc.show(True)
    165
    166          return True
    167  #------------------------------------------------------------
    168 -def manage_form_templates(parent=None, template_types=None, active_only=False, excluded_types=None, msg=None):
    169
    170          if parent is None:
    171                  parent = wx.GetApp().GetTopWindow()
    172
    173          #-------------------------
    174          def edit(template=None):
    175                  dlg = cFormTemplateEditAreaDlg(parent, -1, template=template)
    176                  return (dlg.ShowModal() == wx.ID_OK)
    177          #-------------------------
    178          def delete(template):
    179                  delete = gmGuiHelpers.gm_show_question (
    180                          aTitle = _('Deleting form template.'),
    181                          aMessage = _(
    182                                  'Are you sure you want to delete\n'
    183                                  'the following form template ?\n\n'
    184                                  ' "%s (%s)"\n\n'
    185                                  'You can only delete templates which\n'
    186                                  'have not yet been used to generate\n'
    187                                  'any forms from.'
    188                          ) % (template['name_long'], template['external_version'])
    189                  )
    190                  if delete:
    191                          # FIXME: make this a priviledged operation ?
    192                          gmForms.delete_form_template(template = template)
    193                          return True
    194                  return False
    195          #-------------------------
    196          def refresh(lctrl):
    197                  templates = gmForms.get_form_templates(active_only = active_only, template_types = template_types, excluded_types = excluded_types)
    198                  lctrl.set_string_items(items = [ [t['name_long'], t['external_version'], gmForms.form_engine_names[t['engine']]] for t in templates ])
    199                  lctrl.set_data(data = templates)
    200          #-------------------------
    201          template = gmListWidgets.get_choices_from_list (
    202                  parent = parent,
    203                  msg = msg,
    204                  caption = _('Select letter or form template.'),
    205                  columns = [_('Template'), _('Version'), _('Type')],
    206                  edit_callback = edit,
    207                  new_callback = edit,
    208                  delete_callback = delete,
    209                  refresh_callback = refresh,
    210                  single_selection = True
    211          )
    212
    213          return template
    214  #------------------------------------------------------------
    215 -def create_new_letter(parent=None):
    216
    217          # 1) have user select template
    218          template = manage_form_templates(parent = parent, active_only = True, excluded_types = ['gnuplot script', 'visual progress note'])
    219          if template is None:
    220                  return
    221
    222          wx.BeginBusyCursor()
    223
    224          # 2) export template to file
    225          filename = template.export_to_file()
    226          if filename is None:
    227                  wx.EndBusyCursor()
    228                  gmGuiHelpers.gm_show_error (
    229                          _(      'Error exporting form template\n'
    230                                  '\n'
    231                                  ' "%s" (%s)'
    232                          ) % (template['name_long'], template['external_version']),
    233                          _('Letter template export')
    234                  )
    235                  return
    236
    237          try:
    238                  doc = gmForms.cOOoLetter(template_file = filename, instance_type = template['instance_type'])
    239          except ImportError:
    240                  wx.EndBusyCursor()
    241                  gmGuiHelpers.gm_show_error (
    242                          _('Cannot connect to OpenOffice.\n\n'
    243                            'The UNO bridge module for Python\n'
    244                            'is not installed.'
    245                          ),
    246                          _('Letter writer')
    247                  )
    248                  return
    249
    250          if not doc.open_in_ooo():
    251                  wx.EndBusyCursor()
    252                  gmGuiHelpers.gm_show_error (
    253                          _('Cannot connect to OpenOffice.\n'
    254                            '\n'
    255                            'You may want to increase the option\n'
    256                            '\n'
    257                            ' <%s>'
    258                          ) % _('OOo startup time'),
    259                          _('Letter writer')
    260                  )
    261                  try: os.remove(filename)
    262                  except: pass
    263                  return
    264
    265          doc.show(False)
    266          ph_handler = gmMacro.gmPlaceholderHandler()
    267
    268          wx.EndBusyCursor()
    269
    270          doc.replace_placeholders(handler = ph_handler)
    271
    272          wx.BeginBusyCursor()
    273          filename = filename.replace('.ott', '.odt').replace('-FormTemplate-', '-FormInstance-')
    274          doc.save_in_ooo(filename = filename)
    275          wx.EndBusyCursor()
    276
    277          doc.show(True)
    278  #============================================================
    279  from Gnumed.wxGladeWidgets import wxgFormTemplateEditAreaPnl
    280
    281 -class cFormTemplateEditAreaPnl(wxgFormTemplateEditAreaPnl.wxgFormTemplateEditAreaPnl):
    282
    283 -        def __init__(self, *args, **kwargs):
    284                  try:
    285                          self.__template = kwargs['template']
    286                          del kwargs['template']
    287                  except KeyError:
    288                          self.__template = None
    289
    290                  wxgFormTemplateEditAreaPnl.wxgFormTemplateEditAreaPnl.__init__(self, *args, **kwargs)
    291
    292                  self._PRW_name_long.matcher = gmForms.cFormTemplateNameLong_MatchProvider()
    293                  self._PRW_name_short.matcher = gmForms.cFormTemplateNameShort_MatchProvider()
    294                  self._PRW_template_type.matcher = gmForms.cFormTemplateType_MatchProvider()
    295
    296                  self.refresh()
    297
    298                  self.full_filename = None
    299          #--------------------------------------------------------
    300 -        def refresh(self, template = None):
    301                  if template is not None:
    302                          self.__template = template
    303
    304                  if self.__template is None:
    305                          self._PRW_name_long.SetText(u'')
    306                          self._PRW_name_short.SetText(u'')
    307                          self._TCTRL_external_version.SetValue(u'')
    308                          self._PRW_template_type.SetText(u'')
    309                          self._PRW_instance_type.SetText(u'')
    310                          self._TCTRL_filename.SetValue(u'')
    311                          self._CH_engine.SetSelection(0)
    312                          self._CHBOX_active.SetValue(True)
    313
    314                          self._TCTRL_date_modified.SetValue(u'')
    315                          self._TCTRL_modified_by.SetValue(u'')
    316
    317                          self._BTN_export.Enable(False)
    318                  else:
    319                          self._PRW_name_long.SetText(self.__template['name_long'])
    320                          self._PRW_name_short.SetText(self.__template['name_short'])
    321                          self._TCTRL_external_version.SetValue(self.__template['external_version'])
    322                          self._PRW_template_type.SetText(self.__template['l10n_template_type'], data = self.__template['pk_template_type'])
    323                          self._PRW_instance_type.SetText(self.__template['l10n_instance_type'], data = self.__template['instance_type'])
    324                          self._TCTRL_filename.SetValue(self.__template['filename'])
    325                          self._CH_engine.SetSelection(gmForms.form_engine_abbrevs.index(self.__template['engine']))
    326                          self._CHBOX_active.SetValue(self.__template['in_use'])
    327
    328                          self._TCTRL_date_modified.SetValue(gmDateTime.pydt_strftime(self.__template['last_modified'], '%Y %b %d'))
    329                          self._TCTRL_modified_by.SetValue(self.__template['modified_by'])
    330
    331                          self._TCTRL_filename.Enable(True)
    332                          self._BTN_load.Enable(not self.__template['has_instances'])
    333
    334                          self._BTN_export.Enable(True)
    335
    336                  self._PRW_name_long.SetFocus()
    337          #--------------------------------------------------------
    338 -        def __valid_for_save(self):
    339                  error = False
    340
    341                  if gmTools.coalesce(self._PRW_name_long.GetValue(), u'').strip() == u'':
    342                          error = True
    343                          self._PRW_name_long.SetBackgroundColour('pink')
    344                  else:
    345                          self._PRW_name_long.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
    346
    347                  if gmTools.coalesce(self._PRW_name_short.GetValue(), u'').strip() == u'':
    348                          error = True
    349                          self._PRW_name_short.SetBackgroundColour('pink')
    350                  else:
    351                          self._PRW_name_short.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
    352
    353                  if gmTools.coalesce(self._TCTRL_external_version.GetValue(), u'').strip() == u'':
    354                          error = True
    355                          self._TCTRL_external_version.SetBackgroundColour('pink')
    356                  else:
    357                          self._TCTRL_external_version.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
    358
    359                  if gmTools.coalesce(self._PRW_template_type.GetValue(), u'').strip() == u'':
    360                          error = True
    361                          self._PRW_template_type.SetBackgroundColour('pink')
    362                  else:
    363                          self._PRW_template_type.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
    364
    365                  if gmTools.coalesce(self._PRW_instance_type.GetValue(), u'').strip() == u'':
    366                          error = True
    367                          self._PRW_instance_type.SetBackgroundColour('pink')
    368                  else:
    369                          self._PRW_instance_type.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
    370
    371                  if self.__template is None and self.full_filename is None:
    372                          error = True
    373                          gmDispatcher.send(signal = 'statustext', msg = _('You must select a template file before saving.'), beep = True)
    374
    375                  return not error
    376          #--------------------------------------------------------
    377 -        def save(self):
    378                  if not self.__valid_for_save():
    379                          return False
    380
    381                  if self.__template is None:
    382                          self.__template = gmForms.create_form_template (
    383                                  template_type = self._PRW_template_type.GetData(),
    384                                  name_short = self._PRW_name_short.GetValue().strip(),
    385                                  name_long = self._PRW_name_long.GetValue().strip()
    386                          )
    387                  else:
    388                          self.__template['pk_template_type'] = self._PRW_template_type.GetData()
    389                          self.__template['name_short'] = self._PRW_name_short.GetValue().strip()
    390                          self.__template['name_long'] = self._PRW_name_long.GetValue().strip()
    391
    392                  if not self.__template['has_instances']:
    393                          if self.full_filename is not None:
    394                                  self.__template.update_template_from_file(filename = self.full_filename)
    395
    396                  self.__template['external_version'] = self._TCTRL_external_version.GetValue()
    397                  tmp = self._PRW_instance_type.GetValue().strip()
    398                  if tmp not in [self.__template['instance_type'], self.__template['l10n_instance_type']]:
    399                          self.__template['instance_type'] = tmp
    400                  self.__template['filename'] = self._TCTRL_filename.GetValue()
    401                  self.__template['in_use'] = self._CHBOX_active.GetValue()
    402                  self.__template['engine'] = gmForms.form_engine_abbrevs[self._CH_engine.GetSelection()]
    403
    404                  self.__template.save()
    405                  return True
    406          #--------------------------------------------------------
    407          # event handlers
    408          #--------------------------------------------------------
    409 -        def _on_load_button_pressed(self, evt):
    410
    411                  engine_abbrev = gmForms.form_engine_abbrevs[self._CH_engine.GetSelection()]
    412
    413                  wildcards = []
    414                  try:
    415                          wildcards.append(u'%s (%s)|%s' % (
    416                                  gmForms.form_engine_names[engine_abbrev],
    417                                  gmForms.form_engine_template_wildcards[engine_abbrev],
    418                                  gmForms.form_engine_template_wildcards[engine_abbrev]
    419                          ))
    420                  except KeyError:
    421                          pass
    422
    423                  wildcards.append(u"%s (*)|*" % _('all files'))
    424                  wildcards.append(u"%s (*.*)|*.*" % _('all files (Windows)'))
    425
    426                  dlg = wx.FileDialog (
    427                          parent = self,
    428                          message = _('Choose a form template file'),
    429                          defaultDir = os.path.expanduser(os.path.join('~', 'gnumed')),
    430                          defaultFile = '',
    431                          wildcard = '|'.join(wildcards),
    432                          style = wx.OPEN | wx.HIDE_READONLY | wx.FILE_MUST_EXIST
    433                  )
    434                  result = dlg.ShowModal()
    435                  if result != wx.ID_CANCEL:
    436                          self.full_filename = dlg.GetPath()
    437                          fname = os.path.split(self.full_filename)[1]
    438                          self._TCTRL_filename.SetValue(fname)
    439                  dlg.Destroy()
    440          #--------------------------------------------------------
    441 -        def _on_export_button_pressed(self, event):
    442
    443                  if self.__template is None:
    444                          return
    445
    446                  engine_abbrev = gmForms.form_engine_abbrevs[self._CH_engine.GetSelection()]
    447
    448                  wildcards = []
    449                  try:
    450                          wildcards.append(u'%s (%s)|%s' % (
    451                                  gmForms.form_engine_names[engine_abbrev],
    452                                  gmForms.form_engine_template_wildcards[engine_abbrev],
    453                                  gmForms.form_engine_template_wildcards[engine_abbrev]
    454                          ))
    455                  except KeyError:
    456                          pass
    457                  wildcards.append(u"%s (*)|*" % _('all files'))
    458                  wildcards.append(u"%s (*.*)|*.*" % _('all files (Windows)'))
    459
    460                  dlg = wx.FileDialog (
    461                          parent = self,
    462                          message = _('Enter a filename to save the template in'),
    463                          defaultDir = os.path.expanduser(os.path.join('~', 'gnumed')),
    464                          defaultFile = '',
    465                          wildcard = '|'.join(wildcards),
    466                          style = wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT | wx.HIDE_READONLY
    467                  )
    468                  result = dlg.ShowModal()
    469                  if result != wx.ID_CANCEL:
    470                          fname = dlg.GetPath()
    471                          self.__template.export_to_file(filename = fname)
    472
    473                  dlg.Destroy()
    474  #============================================================
    475  from Gnumed.wxGladeWidgets import wxgFormTemplateEditAreaDlg
    476
    477 -class cFormTemplateEditAreaDlg(wxgFormTemplateEditAreaDlg.wxgFormTemplateEditAreaDlg):
    478
    479 -        def __init__(self, *args, **kwargs):
    480                  try:
    481                          template = kwargs['template']
    482                          del kwargs['template']
    483                  except KeyError:
    484                          template = None
    485
    486                  wxgFormTemplateEditAreaDlg.wxgFormTemplateEditAreaDlg.__init__(self, *args, **kwargs)
    487
    488                  self._PNL_edit_area.refresh(template=template)
    489          #--------------------------------------------------------
    490 -        def _on_save_button_pressed(self, evt):
    491                  if self._PNL_edit_area.save():
    492                          if self.IsModal():
    493                                  self.EndModal(wx.ID_OK)
    494                          else:
    495                                  self.Close()
    496  #============================================================
    497  # main
    498  #------------------------------------------------------------
    499  if __name__ == '__main__':
    500
    501          gmI18N.activate_locale()
    502          gmI18N.install_domain(domain = 'gnumed')
    503
    504          #----------------------------------------
    505 -        def test_cFormTemplateEditAreaPnl():
    506                  app = wx.PyWidgetTester(size = (400, 300))
    507                  pnl = cFormTemplateEditAreaPnl(app.frame, -1, template = gmForms.cFormTemplate(aPK_obj=4))
    508                  app.frame.Show(True)
    509                  app.MainLoop()
    510                  return
    511          #----------------------------------------
    512          if (len(sys.argv) > 1) and (sys.argv[1] == 'test'):
    513                  test_cFormTemplateEditAreaPnl()
    514
    515  #============================================================
    516