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  import shutil
     12
     13
     14  import wx
     15
     16
     17  if __name__ == '__main__':
     18          sys.path.insert(0, '../../')
     19  from Gnumed.pycommon import gmI18N
     20  from Gnumed.pycommon import gmTools
     21  from Gnumed.pycommon import gmDispatcher
     22  from Gnumed.pycommon import gmPrinting
     23  from Gnumed.pycommon import gmDateTime
     24  from Gnumed.pycommon import gmShellAPI
     25  from Gnumed.pycommon import gmMimeLib
     26
     27  from Gnumed.business import gmForms
     28  from Gnumed.business import gmPerson
     29
     30  from Gnumed.wxpython import gmGuiHelpers
     31  from Gnumed.wxpython import gmListWidgets
     32  from Gnumed.wxpython import gmMacro
     33  from Gnumed.wxpython import gmEditArea
     34  from Gnumed.wxpython.gmDocumentWidgets import save_files_as_new_document
     35
     36
     37  _log = logging.getLogger('gm.ui')
     38
     39  _ID_FORM_DISPOSAL_PRINT_NOW, \
     40  _ID_FORM_DISPOSAL_MAIL_NOW, \
     41  _ID_FORM_DISPOSAL_FAX_NOW, \
     42  _ID_FORM_DISPOSAL_TRAY_NOW, \
     43  _ID_FORM_DISPOSAL_ARCHIVE_NOW, \
     44  _ID_FORM_DISPOSAL_SAVE_NOW = range(6)
     45
     46  #============================================================
     47  # generic form generation and handling convenience functions
     48  #------------------------------------------------------------
     49 -def print_doc_from_template(parent=None, jobtype=None, episode=None):
     50
     51          form = generate_form_from_template (
     52                  parent = parent,
     53                  excluded_template_types = [
     54                          u'gnuplot script',
     55                          u'visual progress note',
     56                          u'invoice'
     57                  ],
     58                  edit = True
     59          )
     60          if form is None:
     61                  return False
     62
     63          if form in [True, False]:       # returned by special OOo/LO handling
     64                  return form
     65
     66          return act_on_generated_forms (
     67                  parent = parent,
     68                  forms = [form],
     69                  jobtype = jobtype,
     70                  episode_name = u'administrative',
     71                  review_copy_as_normal = True
     72          )
     73
     74  #------------------------------------------------------------
     75  # eventually this should become superfluous when there's a
     76  # standard engine wrapper around OOo
     77 -def print_doc_from_ooo_template(template=None):
     78
     79          # export template to file
     80          filename = template.export_to_file()
     81          if filename is None:
     82                  gmGuiHelpers.gm_show_error (
     83                          _(      'Error exporting form template\n'
     84                                  '\n'
     85                                  ' "%s" (%s)'
     86                          ) % (template['name_long'], template['external_version']),
     87                          _('Letter template export')
     88                  )
     89                  return False
     90
     91          try:
     92                  doc = gmForms.cOOoLetter(template_file = filename, instance_type = template['instance_type'])
     93          except ImportError:
     94                  gmGuiHelpers.gm_show_error (
     95                          _('Cannot connect to OpenOffice.\n\n'
     96                            'The UNO bridge module for Python\n'
     97                            'is not installed.'
     98                          ),
     99                          _('Letter writer')
    100                  )
    101                  return False
    102
    103          if not doc.open_in_ooo():
    104                  gmGuiHelpers.gm_show_error (
    105                          _('Cannot connect to OpenOffice.\n'
    106                            '\n'
    107                            'You may want to increase the option\n'
    108                            '\n'
    109                            ' <%s>'
    110                          ) % _('OOo startup time'),
    111                          _('Letter writer')
    112                  )
    113                  try: os.remove(filename)
    114                  except: pass
    115                  return False
    116
    117          doc.show(False)
    118          ph_handler = gmMacro.gmPlaceholderHandler()
    119          doc.replace_placeholders(handler = ph_handler)
    120
    121          filename = filename.replace('.ott', '.odt').replace('-FormTemplate-', '-FormInstance-')
    122          doc.save_in_ooo(filename = filename)
    123
    124          doc.show(True)
    125
    126          return True
    127
    128  #------------------------------------------------------------
    129 -def generate_form_from_template(parent=None, template_types=None, edit=None, template=None, excluded_template_types=None):
    130          """If <edit> is None it will honor the template setting."""
    131
    132          if parent is None:
    133                  parent = wx.GetApp().GetTopWindow()
    134
    135          # 1) get template to use
    136          if template is None:
    137                  template = manage_form_templates (
    138                          parent = parent,
    139                          active_only = True,
    140                          template_types = template_types,
    141                          excluded_types = excluded_template_types
    142                  )
    143                  if template is None:
    144                          gmDispatcher.send(signal = 'statustext', msg = _('No document template selected.'), beep = False)
    145                          return None
    146
    147          if template['engine'] == u'O':
    148                  return print_doc_from_ooo_template(template = template)
    149
    150          wx.BeginBusyCursor()
    151
    152          # 2) process template
    153          try:
    154                  form = template.instantiate()
    155          except KeyError:
    156                  _log.exception('cannot instantiate document template [%s]', template)
    157                  gmGuiHelpers.gm_show_error (
    158                          aMessage = _('Invalid document template [%s - %s (%s)]') % (name, ver, template['engine']),
    159                          aTitle = _('Generating document from template')
    160                  )
    161                  wx.EndBusyCursor()
    162                  return None
    163          ph = gmMacro.gmPlaceholderHandler()
    164          #ph.debug = True
    165          form.substitute_placeholders(data_source = ph)
    166          if edit is None:
    167                  if form.template['edit_after_substitution']:
    168                          edit = True
    169                  else:
    170                          edit = False
    171          if edit:
    172                  wx.EndBusyCursor()
    173                  form.edit()
    174                  wx.BeginBusyCursor()
    175
    176          # 3) generate output
    177          pdf_name = form.generate_output()
    178          wx.EndBusyCursor()
    179          if pdf_name is not None:
    180                  return form
    181
    182          gmGuiHelpers.gm_show_error (
    183                  aMessage = _('Error generating document printout.'),
    184                  aTitle = _('Generating document printout')
    185          )
    186          return None
    187
    188  #------------------------------------------------------------
    189 -def act_on_generated_forms(parent=None, forms=None, jobtype=None, episode_name=None, progress_note=None, review_copy_as_normal=False):
    190          """This function assumes that .generate_output() has already been called on each form."""
    191
    192          if len(forms) == 0:
    193                  return True
    194
    195          no_of_printables = 0
    196          for form in forms:
    197                  no_of_printables += len(form.final_output_filenames)
    198
    199          if no_of_printables == 0:
    200                  return True
    201
    202          soap_lines = []
    203
    204          #-----------------------------
    205          def save_soap(soap=None):
    206                  if soap.strip() == u'':
    207                          return
    208                  pat = gmPerson.gmCurrentPatient()
    209                  emr = pat.get_emr()
    210                  epi = emr.add_episode(episode_name = episode_name, is_open = False)
    211                  emr.add_clin_narrative (
    212                          soap_cat = None,
    213                          note = soap,
    214                          episode = epi
    215                  )
    216          #-----------------------------
    217          def archive_forms(episode_name=None):
    218                  if episode_name is None:
    219                          epi = None                              # will ask for episode further down
    220                  else:
    221                          pat = gmPerson.gmCurrentPatient()
    222                          emr = pat.get_emr()
    223                          epi = emr.add_episode(episode_name = episode_name, is_open = False)
    224
    225                  for form in forms:
    226                          files2import = []
    227                          files2import.extend(form.final_output_filenames)
    228                          files2import.extend(form.re_editable_filenames)
    229                          if len(files2import) == 0:
    230                                  continue
    231                          save_files_as_new_document (
    232                                  parent = parent,
    233                                  filenames = files2import,
    234                                  document_type = form.template['instance_type'],
    235                                  unlock_patient = False,
    236                                  episode = epi,
    237                                  review_as_normal = review_copy_as_normal,
    238                                  reference = None
    239                          )
    240
    241                  return True
    242          #-----------------------------
    243          def save_forms():
    244                  # anything to do ?
    245                  files2save = []
    246                  form_names = []
    247                  for form in forms:
    248                          files2save.extend(form.final_output_filenames)
    249                          form_names.append(u'%s (%s)' % (form.template['name_long'], form.template['external_version']))
    250                  if len(files2save) == 0:
    251                          return True
    252                  # get path
    253                  path = os.path.expanduser(os.path.join('~', 'gnumed'))
    254                  dlg = wx.DirDialog (
    255                          parent = parent,
    256                          message = _('Select directory in which to create patient directory ...'),
    257                          defaultPath = path,
    258                          style = wx.DD_DEFAULT_STYLE
    259                  )
    260                  result = dlg.ShowModal()
    261                  path = dlg.GetPath()
    262                  dlg.Destroy()
    263                  if result != wx.ID_OK:
    264                          return
    265                  # save forms
    266                  pat = gmPerson.gmCurrentPatient()
    267                  path = os.path.join(path, pat.dirname)
    268                  gmTools.mkdir(path)
    269                  _log.debug('form saving path: %s', path)
    270                  for form in forms:
    271                          for filename in form.final_output_filenames:
    272                                  shutil.copy2(filename, path)
    273                  soap_lines.append(_('Saved to disk: %s') % u', '.join(form_names))
    274                  return True
    275          #-----------------------------
    276          def print_forms():
    277                  # anything to do ?
    278                  files2print = []
    279                  form_names = []
    280                  for form in forms:
    281                          files2print.extend(form.final_output_filenames)
    282                          form_names.append(u'%s (%s)' % (form.template['name_long'], form.template['external_version']))
    283                  if len(files2print) == 0:
    284                          return True
    285                  # print
    286                  printed = gmPrinting.print_files(filenames = files2print, jobtype = jobtype)
    287                  if not printed:
    288                          gmGuiHelpers.gm_show_error (
    289                                  aMessage = _('Error printing documents.'),
    290                                  aTitle = _('Printing [%s]') % jobtype
    291                          )
    292                          return False
    293                  soap_lines.append(_('Printed: %s') % u', '.join(form_names))
    294                  return True
    295          #-----------------------------
    296          def mail_forms():
    297                  # anything to do ?
    298                  files2mail = []
    299                  form_names = []
    300                  for form in forms:
    301                          files2mail.extend(form.final_output_filenames)
    302                          form_names.append(u'%s (%s)' % (form.template['name_long'], form.template['external_version']))
    303                  if len(files2mail) == 0:
    304                          return True
    305                  found, external_cmd = gmShellAPI.detect_external_binary('gm-mail_doc')
    306                  if not found:
    307                          return False
    308                  # send mail
    309                  cmd = u'%s %s' % (external_cmd, u' '.join(files2mail))
    310                  if os.name == 'nt':
    311                          blocking = True
    312                  else:
    313                          blocking = False
    314                  success = gmShellAPI.run_command_in_shell (
    315                          command = cmd,
    316                          blocking = blocking
    317                  )
    318                  if not success:
    319                          gmGuiHelpers.gm_show_error (
    320                                  aMessage = _('Error mailing documents.'),
    321                                  aTitle = _('Mailing documents')
    322                          )
    323                          return False
    324                  soap_lines.append(_('Mailed: %s') % u', '.join(form_names))
    325                  return True
    326          #-----------------------------
    327          def fax_forms(fax_number=None):
    328                  # anything to do ?
    329                  files2fax = []
    330                  form_names = []
    331                  for form in forms:
    332                          files2fax.extend(form.final_output_filenames)
    333                          form_names.append(u'%s (%s)' % (form.template['name_long'], form.template['external_version']))
    334                  if len(files2fax) == 0:
    335                          return True
    336                  found, external_cmd = gmShellAPI.detect_external_binary('gm-fax_doc')
    337                  if not found:
    338                          return False
    339                  # send fax
    340                  cmd = u'%s "%s" %s' % (external_cmd, fax_number, u' '.join(files2fax))
    341                  if os.name == 'nt':
    342                          blocking = True
    343                  else:
    344                          blocking = False
    345                  success = gmShellAPI.run_command_in_shell (
    346                          command = cmd,
    347                          blocking = blocking
    348                  )
    349                  if not success:
    350                          gmGuiHelpers.gm_show_error (
    351                                  aMessage = _('Error faxing documents to\n\n  %s') % fax_number,
    352                                  aTitle = _('Faxing documents')
    353                          )
    354                          return False
    355                  soap_lines.append(_('Faxed to %s: %s') % (fax_number, u', '.join(form_names)))
    356                  return True
    357          #-----------------------------
    358
    359          if parent is None:
    360                  parent = wx.GetApp().GetTopWindow()
    361
    362          if jobtype is None:
    363                  jobtype = 'generic_document'
    364
    365          dlg = cFormDisposalDlg(parent, -1)
    366          dlg.forms = forms
    367          dlg.progress_note = progress_note
    368          dlg.episode_name = episode_name
    369          action_code = dlg.ShowModal()
    370
    371          if action_code == wx.ID_CANCEL:
    372                  dlg.Destroy()
    373                  return True
    374
    375          forms = dlg._LCTRL_forms.get_item_data()
    376          if len(forms) == 0:
    377                  dlg.Destroy()
    378                  return True
    379
    380          progress_note = dlg.progress_note
    381          episode_name = dlg._PRW_episode.GetValue().strip()
    382          do_save = dlg._CHBOX_save.GetValue()
    383          do_print = dlg._CHBOX_print.GetValue()
    384          do_mail = dlg._CHBOX_mail.GetValue()
    385          fax_number = dlg._PRW_fax.GetValue().strip()
    386          dlg.Destroy()
    387
    388          if action_code == wx.ID_OK:
    389                  if episode_name != u'':
    390                          result = archive_forms(episode_name = episode_name)
    391                  if do_save:
    392                          result = save_forms()
    393                  if do_print:
    394                          result = print_forms()
    395                  if do_mail:
    396                          result = mail_forms()
    397                  if fax_number != u'':
    398                          result = fax_forms(fax_number = fax_number)
    399                  if progress_note != u'':
    400                          soap_lines.insert(0, progress_note)
    401                  if len(soap_lines) > 0:
    402                          save_soap(soap = u'\n'.join(soap_lines))
    403                  return result
    404
    405          success = False
    406          keep_a_copy = False
    407          if action_code == _ID_FORM_DISPOSAL_PRINT_NOW:
    408                  if episode_name != u'':
    409                          keep_a_copy = True
    410                  success = print_forms()
    411
    412          elif action_code == _ID_FORM_DISPOSAL_ARCHIVE_NOW:
    413                  if episode_name == u'':
    414                          episode_name = None
    415                  keep_a_copy = True
    416                  success = True
    417
    418          elif action_code == _ID_FORM_DISPOSAL_SAVE_NOW:
    419                  if episode_name != u'':
    420                          keep_a_copy = True
    421                  success = save_forms()
    422
    423          elif action_code == _ID_FORM_DISPOSAL_MAIL_NOW:
    424                  if episode_name != u'':
    425                          keep_a_copy = True
    426                  success = mail_forms()
    427
    428          elif action_code == _ID_FORM_DISPOSAL_FAX_NOW:
    429                  if episode_name != u'':
    430                          keep_a_copy = True
    431                  success = fax_forms(fax_number = fax_number)
    432
    433          elif action_code == _ID_FORM_DISPOSAL_TRAY_NOW:
    434                  # not implemented
    435                  success = False
    436
    437          if not success:
    438                  return False
    439
    440          if progress_note != u'':
    441                  soap_lines.insert(0, progress_note)
    442          if len(soap_lines) > 0:
    443                  save_soap(soap = u'\n'.join(soap_lines))
    444
    445          if keep_a_copy:
    446                  archive_forms(episode_name = episode_name)
    447
    448          return True
    449
    450  #============================================================
    451  from Gnumed.wxGladeWidgets import wxgFormDisposalDlg
    452
    453 -class cFormDisposalDlg(wxgFormDisposalDlg.wxgFormDisposalDlg):
    454
    455 -        def __init__(self, *args, **kwargs):
    456
    457                  wxgFormDisposalDlg.wxgFormDisposalDlg.__init__(self, *args, **kwargs)
    458
    459                  self.__init_ui()
    460
    461          #--------------------------------------------------------
    462          # properties
    463          #--------------------------------------------------------
    464 -        def _set_msg(self, msg):
    465                  self._LBL_msg.SetLabel(msg)
    466                  self._LBL_msg.Refresh()
    467
    468          message = property(lambda x:x, _set_msg)
    469
    470          #--------------------------------------------------------
    471 -        def _set_forms(self, forms):
    472                  items = [ f.template['name_long'] for f in forms ]
    473                  self._LCTRL_forms.set_string_items(items)
    474                  self._LCTRL_forms.set_data(forms)
    475
    476          forms = property(lambda x:x, _set_forms)
    477
    478          #--------------------------------------------------------
    479 -        def _get_note(self):
    480                  return self._TCTRL_soap.GetValue().strip()
    481
    482 -        def _set_note(self, note):
    483                  if note is None:
    484                          note = u''
    485                  self._TCTRL_soap.SetValue(note)
    486
    487          progress_note = property(_get_note, _set_note)
    488
    489          #--------------------------------------------------------
    490 -        def _get_episode_name(self):
    491                  return self._PRW_episode.GetValue().strip()
    492
    493 -        def _set_episode_name(self, episode_name):
    494                  if episode_name is None:
    495                          episode_name = u''
    496                  self._PRW_episode.SetValue(episode_name)
    497
    498          episode_name = property(_get_episode_name, _set_episode_name)
    499
    500          #--------------------------------------------------------
    501          # internal helpers
    502          #--------------------------------------------------------
    503 -        def __init_ui(self):
    504                  self._LCTRL_forms.set_columns([_('Form')])
    505
    506                  self.__mail_script_exists, path = gmShellAPI.detect_external_binary(binary = r'gm-mail_doc')
    507                  if not self.__mail_script_exists:
    508                          self._LBL_mail.Disable()
    509                          self._CHBOX_mail.SetLabel(_('<gm-mail_doc(.bat) not found>'))
    510                          self._CHBOX_mail.SetValue(False)
    511                          self._CHBOX_mail.Disable()
    512                          self._BTN_mail.Disable()
    513
    514                  self.__fax_script_exists, path = gmShellAPI.detect_external_binary(binary = r'gm-fax_doc')
    515                  if not self.__fax_script_exists:
    516                          self._LBL_fax.Disable()
    517                          self._PRW_fax.SetText(_('<gm-fax_doc(.bat) not found>'), data = None)
    518                          self._PRW_fax.display_as_disabled(True)
    519                          self._PRW_fax.Disable()
    520                          self._BTN_fax.Disable()
    521
    522                  self._LBL_tray.Disable()
    523                  self._CHBOX_tray.SetValue(False)
    524                  self._CHBOX_tray.Disable()
    525                  self._BTN_tray.Disable()
    526
    527          #--------------------------------------------------------
    528          # event handlers
    529          #--------------------------------------------------------
    530 -        def _on_print_button_pressed(self, event):
    531                  self.EndModal(_ID_FORM_DISPOSAL_PRINT_NOW)
    532          #--------------------------------------------------------
    533 -        def _on_mail_button_pressed(self, event):
    534                  event.Skip()
    535                  if not self.__mail_script_exists:
    536                          return
    537                  self.EndModal(_ID_FORM_DISPOSAL_MAIL_NOW)
    538          #--------------------------------------------------------
    539 -        def _on_fax_button_pressed(self, event):
    540                  event.Skip()
    541                  if not self.__fax_script_exists:
    542                          return
    543                  self.EndModal(_ID_FORM_DISPOSAL_FAX_NOW)
    544          #--------------------------------------------------------
    545 -        def _on_tray_button_pressed(self, event):
    546                  self.EndModal(_ID_FORM_DISPOSAL_TRAY_NOW)
    547          #--------------------------------------------------------
    548 -        def _on_archive_button_pressed(self, event):
    549                  self.EndModal(_ID_FORM_DISPOSAL_ARCHIVE_NOW)
    550          #--------------------------------------------------------
    551 -        def _on_save_button_pressed(self, event):
    552                  self.EndModal(_ID_FORM_DISPOSAL_SAVE_NOW)
    553          #--------------------------------------------------------
    554 -        def _on_show_forms_button_pressed(self, event):
    555                  event.Skip()
    556                  forms2show = self._LCTRL_forms.get_selected_item_data()
    557                  if len(forms2show) == 0:
    558                          return
    559                  for form in forms2show:
    560                          for filename in form.final_output_filenames:
    561                                  gmMimeLib.call_viewer_on_file(filename, block = True)
    562          #--------------------------------------------------------
    563 -        def _on_delete_forms_button_pressed(self, event):
    564                  print "Event handler '_on_delete_forms_button_pressed' not implemented!"
    565                  event.Skip()
    566          #--------------------------------------------------------
    567 -        def _on_ok_button_pressed(self, event):
    568                  self.EndModal(wx.ID_OK)
    569
    570  #============================================================
    571  # form template management
    572  #------------------------------------------------------------
    573 -def edit_template(parent=None, template=None, single_entry=False):
    574          ea = cFormTemplateEAPnl(parent = parent, id = -1)
    575          ea.data = template
    576          ea.mode = gmTools.coalesce(template, 'new', 'edit')
    577          dlg = gmEditArea.cGenericEditAreaDlg2(parent = parent, id = -1, edit_area = ea, single_entry = single_entry)
    578          dlg.SetTitle(gmTools.coalesce(template, _('Adding new form template'), _('Editing form template')))
    579          if dlg.ShowModal() == wx.ID_OK:
    580                  dlg.Destroy()
    581                  return True
    582          dlg.Destroy()
    583          return False
    584
    585  #------------------------------------------------------------
    586 -def manage_form_templates(parent=None, template_types=None, active_only=False, excluded_types=None, msg=None):
    587
    588          if parent is None:
    589                  parent = wx.GetApp().GetTopWindow()
    590
    591          #-------------------------
    592          def edit(template=None):
    593                  return edit_template(parent = parent, template = template)
    594          #-------------------------
    595          def delete(template):
    596                  delete = gmGuiHelpers.gm_show_question (
    597                          aTitle = _('Deleting form template.'),
    598                          aMessage = _(
    599                                  'Are you sure you want to delete\n'
    600                                  'the following form template ?\n\n'
    601                                  ' "%s (%s)"\n\n'
    602                                  'You can only delete templates which\n'
    603                                  'have not yet been used to generate\n'
    604                                  'any forms from.'
    605                          ) % (template['name_long'], template['external_version'])
    606                  )
    607                  if delete:
    608                          # FIXME: make this a priviledged operation ?
    609                          gmForms.delete_form_template(template = template)
    610                          return True
    611                  return False
    612          #-------------------------
    613          def refresh(lctrl):
    614                  templates = gmForms.get_form_templates(active_only = active_only, template_types = template_types, excluded_types = excluded_types)
    615                  lctrl.set_string_items(items = [ [t['name_long'], t['external_version'], gmForms.form_engine_names[t['engine']]] for t in templates ])
    616                  lctrl.set_data(data = templates)
    617          #-------------------------
    618          template = gmListWidgets.get_choices_from_list (
    619                  parent = parent,
    620                  msg = msg,
    621                  caption = _('Select letter or form template.'),
    622                  columns = [_('Template'), _('Version'), _('Type')],
    623                  edit_callback = edit,
    624                  new_callback = edit,
    625                  delete_callback = delete,
    626                  refresh_callback = refresh,
    627                  single_selection = True
    628          )
    629
    630          return template
    631
    632  #------------------------------------------------------------
    633  from Gnumed.wxGladeWidgets import wxgFormTemplateEditAreaPnl
    634
    635 -class cFormTemplateEAPnl(wxgFormTemplateEditAreaPnl.wxgFormTemplateEditAreaPnl, gmEditArea.cGenericEditAreaMixin):
    636
    637 -        def __init__(self, *args, **kwargs):
    638
    639                  try:
    640                          data = kwargs['template']
    641                          del kwargs['template']
    642                  except KeyError:
    643                          data = None
    644
    645                  wxgFormTemplateEditAreaPnl.wxgFormTemplateEditAreaPnl.__init__(self, *args, **kwargs)
    646                  gmEditArea.cGenericEditAreaMixin.__init__(self)
    647
    648                  self.full_filename = None
    649
    650                  self.mode = 'new'
    651                  self.data = data
    652                  if data is not None:
    653                          self.mode = 'edit'
    654
    655                  self.__init_ui()
    656          #----------------------------------------------------------------
    657 -        def __init_ui(self):
    658                  self._PRW_name_long.matcher = gmForms.cFormTemplateNameLong_MatchProvider()
    659                  self._PRW_name_short.matcher = gmForms.cFormTemplateNameShort_MatchProvider()
    660                  self._PRW_template_type.matcher = gmForms.cFormTemplateType_MatchProvider()
    661          #----------------------------------------------------------------
    662          # generic Edit Area mixin API
    663          #----------------------------------------------------------------
    664 -        def _valid_for_save(self):
    665
    666                  validity = True
    667
    668                  # self._TCTRL_filename
    669                  self.display_tctrl_as_valid(tctrl = self._TCTRL_filename, valid = True)
    670                  fname = self._TCTRL_filename.GetValue().strip()
    671                  # 1) new template: file must exist
    672                  if self.data is None:
    673                          try:
    674                                  open(fname, 'r').close()
    675                          except:
    676                                  validity = False
    677                                  self.display_tctrl_as_valid(tctrl = self._TCTRL_filename, valid = False)
    678                                  self.status_message = _('You must select a template file before saving.')
    679                                  self._TCTRL_filename.SetFocus()
    680                  # 2) existing template
    681                  # - empty = no change
    682                  # - does not exist: name change in DB field
    683                  # - does exist: reload from filesystem
    684
    685                  # self._PRW_instance_type
    686                  if self._PRW_instance_type.GetValue().strip() == u'':
    687                          validity = False
    688                          self._PRW_instance_type.display_as_valid(False)
    689                          self.status_message = _('You must enter a type for documents created with this template.')
    690                          self._PRW_instance_type.SetFocus()
    691                  else:
    692                          self._PRW_instance_type.display_as_valid(True)
    693
    694                  # self._PRW_template_type
    695                  if self._PRW_template_type.GetData() is None:
    696                          validity = False
    697                          self._PRW_template_type.display_as_valid(False)
    698                          self.status_message = _('You must enter a type for this template.')
    699                          self._PRW_template_type.SetFocus()
    700                  else:
    701                          self._PRW_template_type.display_as_valid(True)
    702
    703                  # self._TCTRL_external_version
    704                  if self._TCTRL_external_version.GetValue().strip() == u'':
    705                          validity = False
    706                          self.display_tctrl_as_valid(tctrl = self._TCTRL_external_version, valid = False)
    707                          self.status_message = _('You must enter a version for this template.')
    708                          self._TCTRL_external_version.SetFocus()
    709                  else:
    710                          self.display_tctrl_as_valid(tctrl = self._TCTRL_external_version, valid = True)
    711
    712                  # self._PRW_name_short
    713                  if self._PRW_name_short.GetValue().strip() == u'':
    714                          validity = False
    715                          self._PRW_name_short.display_as_valid(False)
    716                          self.status_message = _('Missing short name for template.')
    717                          self._PRW_name_short.SetFocus()
    718                  else:
    719                          self._PRW_name_short.display_as_valid(True)
    720
    721                  # self._PRW_name_long
    722                  if self._PRW_name_long.GetValue().strip() == u'':
    723                          validity = False
    724                          self._PRW_name_long.display_as_valid(False)
    725                          self.status_message = _('Missing long name for template.')
    726                          self._PRW_name_long.SetFocus()
    727                  else:
    728                          self._PRW_name_long.display_as_valid(True)
    729
    730                  return validity
    731          #----------------------------------------------------------------
    732 -        def _save_as_new(self):
    733                  data = gmForms.create_form_template (
    734                          template_type = self._PRW_template_type.GetData(),
    735                          name_short = self._PRW_name_short.GetValue().strip(),
    736                          name_long = self._PRW_name_long.GetValue().strip()
    737                  )
    738                  data['external_version'] = self._TCTRL_external_version.GetValue()
    739                  data['instance_type'] = self._PRW_instance_type.GetValue().strip()
    740                  data['filename'] = os.path.split(self._TCTRL_filename.GetValue().strip())[1]
    741                  data['in_use'] = self._CHBOX_active.GetValue()
    742                  data['edit_after_substitution'] = self._CHBOX_editable.GetValue()
    743                  data['engine'] = gmForms.form_engine_abbrevs[self._CH_engine.GetSelection()]
    744                  data.save()
    745
    746                  data.update_template_from_file(filename = self._TCTRL_filename.GetValue().strip())
    747
    748                  self.data = data
    749                  return True
    750          #----------------------------------------------------------------
    751 -        def _save_as_update(self):
    752                  self.data['pk_template_type'] = self._PRW_template_type.GetData()
    753                  self.data['name_short'] = self._PRW_name_short.GetValue().strip()
    754                  self.data['name_long'] = self._PRW_name_long.GetValue().strip()
    755                  self.data['external_version'] = self._TCTRL_external_version.GetValue()
    756                  tmp = self._PRW_instance_type.GetValue().strip()
    757                  if tmp not in [self.data['instance_type'], self.data['l10n_instance_type']]:
    758                          self.data['instance_type'] = tmp
    759                  tmp = os.path.split(self._TCTRL_filename.GetValue().strip())[1]
    760                  if tmp != u'':
    761                          self.data['filename'] = tmp
    762                  self.data['in_use'] = self._CHBOX_active.GetValue()
    763                  self.data['edit_after_substitution'] = self._CHBOX_editable.GetValue()
    764                  self.data['engine'] = gmForms.form_engine_abbrevs[self._CH_engine.GetSelection()]
    765                  self.data.save()
    766
    767                  fname = self._TCTRL_filename.GetValue().strip()
    768                  try:
    769                          open(fname, 'r').close()
    770                          self.data.update_template_from_file(filename = fname)
    771                  except:
    772                          pass # filename column already updated
    773
    774                  return True
    775          #----------------------------------------------------------------
    776 -        def _refresh_as_new(self):
    777                  self._PRW_name_long.SetText(u'')
    778                  self._PRW_name_short.SetText(u'')
    779                  self._TCTRL_external_version.SetValue(u'')
    780                  self._PRW_template_type.SetText(u'')
    781                  self._PRW_instance_type.SetText(u'')
    782                  self._TCTRL_filename.SetValue(u'')
    783                  self._CH_engine.SetSelection(0)
    784                  self._CHBOX_active.SetValue(True)
    785                  self._CHBOX_editable.SetValue(True)
    786                  self._LBL_status.SetLabel(u'')
    787                  self._BTN_export.Enable(False)
    788
    789                  self._PRW_name_long.SetFocus()
    790          #----------------------------------------------------------------
    791 -        def _refresh_as_new_from_existing(self):
    792                  self._refresh_as_new()
    793          #----------------------------------------------------------------
    794 -        def _refresh_from_existing(self):
    795                  self._PRW_name_long.SetText(self.data['name_long'])
    796                  self._PRW_name_short.SetText(self.data['name_short'])
    797                  self._TCTRL_external_version.SetValue(self.data['external_version'])
    798                  self._PRW_template_type.SetText(self.data['l10n_template_type'], data = self.data['pk_template_type'])
    799                  self._PRW_instance_type.SetText(self.data['l10n_instance_type'], data = self.data['instance_type'])
    800                  self._TCTRL_filename.SetValue(self.data['filename'])
    801                  self._CH_engine.SetSelection(gmForms.form_engine_abbrevs.index(self.data['engine']))
    802                  self._CHBOX_active.SetValue(self.data['in_use'])
    803                  self._CHBOX_editable.SetValue(self.data['edit_after_substitution'])
    804                  self._LBL_status.SetLabel(_('last modified %s by %s') % (
    805                          gmDateTime.pydt_strftime(self.data['last_modified'], '%Y %B %d'),
    806                          self.data['modified_by']
    807                  ))
    808
    809                  self._TCTRL_filename.Enable(True)
    810                  self._BTN_load.Enable(True)
    811                  self._BTN_export.Enable(True)
    812
    813                  self._BTN_load.SetFocus()
    814          #----------------------------------------------------------------
    815          # event handlers
    816          #----------------------------------------------------------------
    817 -        def _on_load_button_pressed(self, event):
    818                  engine_abbrev = gmForms.form_engine_abbrevs[self._CH_engine.GetSelection()]
    819
    820                  wildcards = []
    821                  try:
    822                          wildcards.append(u'%s (%s)|%s' % (
    823                                  gmForms.form_engine_names[engine_abbrev],
    824                                  gmForms.form_engine_template_wildcards[engine_abbrev],
    825                                  gmForms.form_engine_template_wildcards[engine_abbrev]
    826                          ))
    827                  except KeyError:
    828                          pass
    829                  wildcards.append(u"%s (*)|*" % _('all files'))
    830                  wildcards.append(u"%s (*.*)|*.*" % _('all files (Windows)'))
    831
    832                  dlg = wx.FileDialog (
    833                          parent = self,
    834                          message = _('Choose a form template file'),
    835                          defaultDir = os.path.expanduser(os.path.join('~', 'gnumed')),
    836                          defaultFile = '',
    837                          wildcard = '|'.join(wildcards),
    838                          style = wx.OPEN | wx.HIDE_READONLY | wx.FILE_MUST_EXIST
    839                  )
    840                  result = dlg.ShowModal()
    841                  if result != wx.ID_CANCEL:
    842                          self._TCTRL_filename.SetValue(dlg.GetPath())
    843                  dlg.Destroy()
    844
    845                  event.Skip()
    846          #----------------------------------------------------------------
    847 -        def _on_export_button_pressed(self, event):
    848                  if self.data is None:
    849                          return
    850
    851                  engine_abbrev = gmForms.form_engine_abbrevs[self._CH_engine.GetSelection()]
    852
    853                  wildcards = []
    854                  try:
    855                          wildcards.append(u'%s (%s)|%s' % (
    856                                  gmForms.form_engine_names[engine_abbrev],
    857                                  gmForms.form_engine_template_wildcards[engine_abbrev],
    858                                  gmForms.form_engine_template_wildcards[engine_abbrev]
    859                          ))
    860                  except KeyError:
    861                          pass
    862                  wildcards.append(u"%s (*)|*" % _('all files'))
    863                  wildcards.append(u"%s (*.*)|*.*" % _('all files (Windows)'))
    864
    865                  dlg = wx.FileDialog (
    866                          parent = self,
    867                          message = _('Enter a filename to save the template to'),
    868                          defaultDir = os.path.expanduser(os.path.join('~', 'gnumed')),
    869                          defaultFile = '',
    870                          wildcard = '|'.join(wildcards),
    871                          style = wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT | wx.HIDE_READONLY
    872                  )
    873                  result = dlg.ShowModal()
    874                  if result != wx.ID_CANCEL:
    875                          fname = dlg.GetPath()
    876                          self.data.export_to_file(filename = fname)
    877                  dlg.Destroy()
    878
    879                  event.Skip()
    880
    881  #============================================================
    882  # main
    883  #------------------------------------------------------------
    884  if __name__ == '__main__':
    885
    886          gmI18N.activate_locale()
    887          gmI18N.install_domain(domain = 'gnumed')
    888
    889          #----------------------------------------
    890 -        def test_cFormTemplateEAPnl():
    891                  app = wx.PyWidgetTester(size = (400, 300))
    892                  pnl = cFormTemplateEAPnl(app.frame, -1, template = gmForms.cFormTemplate(aPK_obj=4))
    893                  app.frame.Show(True)
    894                  app.MainLoop()
    895                  return
    896          #----------------------------------------
    897          if (len(sys.argv) > 1) and (sys.argv[1] == 'test'):
    898                  test_cFormTemplateEAPnl()
    899
    900  #============================================================
    901