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