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

Source Code for Module Gnumed.wxpython.gmExportAreaWidgets

   1  """GNUmed patient export area widgets.""" 
   2  #================================================================ 
   3  __author__ = "Karsten.Hilbert@gmx.net" 
   4  __license__ = "GPL v2 or later" 
   5   
   6  # std lib 
   7  import sys 
   8  import logging 
   9  import os.path 
  10  import shutil 
  11   
  12   
  13  # 3rd party 
  14  import wx 
  15   
  16   
  17  # GNUmed libs 
  18  if __name__ == '__main__': 
  19          sys.path.insert(0, '../../') 
  20   
  21  from Gnumed.pycommon import gmDispatcher 
  22  from Gnumed.pycommon import gmTools 
  23  from Gnumed.pycommon import gmMimeLib 
  24  from Gnumed.pycommon import gmDateTime 
  25  from Gnumed.pycommon import gmPrinting 
  26  from Gnumed.pycommon import gmShellAPI 
  27  from Gnumed.pycommon import gmNetworkTools 
  28  from Gnumed.pycommon import gmCfg2 
  29  from Gnumed.pycommon import gmLog2 
  30   
  31  from Gnumed.business import gmPerson 
  32  from Gnumed.business import gmExportArea 
  33  from Gnumed.business import gmPraxis 
  34   
  35  from Gnumed.wxpython import gmRegetMixin 
  36  from Gnumed.wxpython import gmGuiHelpers 
  37  from Gnumed.wxpython import gmDocumentWidgets 
  38   
  39   
  40  _log = logging.getLogger('gm.ui') 
  41  _cfg = gmCfg2.gmCfgData() 
  42   
  43  #============================================================ 
44 -def _add_file_to_export_area(**kwargs):
45 try: 46 del kwargs['signal'] 47 del kwargs['sender'] 48 except KeyError: 49 pass 50 wx.CallAfter(add_file_to_export_area, **kwargs)
51
52 -def _add_files_to_export_area(**kwargs):
53 try: 54 del kwargs['signal'] 55 del kwargs['sender'] 56 except KeyError: 57 pass 58 wx.CallAfter(add_files_to_export_area, **kwargs)
59 60 #----------------------
61 -def add_file_to_export_area(parent=None, filename=None, hint=None, unlock_patient=False):
62 return add_files_to_export_area ( 63 parent = parent, 64 filenames = [filename], 65 hint = hint, 66 unlock_patient = unlock_patient 67 )
68 69 #----------------------
70 -def add_files_to_export_area(parent=None, filenames=None, hint=None, unlock_patient=False):
71 pat = gmPerson.gmCurrentPatient() 72 if not pat.connected: 73 gmDispatcher.send(signal = 'statustext', msg = _('Cannot add files to export area. No patient.'), beep = True) 74 return False 75 76 wx.BeginBusyCursor() 77 if parent is None: 78 parent = wx.GetApp().GetTopWindow() 79 if not pat.export_area.add_files(filenames = filenames, hint = hint): 80 wx.EndBusyCursor() 81 gmGuiHelpers.gm_show_error ( 82 aMessage = _('Cannot import files into export area.'), 83 aTitle = _('Export area') 84 ) 85 return False 86 87 wx.EndBusyCursor() 88 # remove non-temp files 89 tmp_dir = gmTools.gmPaths().tmp_dir 90 files2remove = [ f for f in filenames if not f.startswith(tmp_dir) ] 91 if len(files2remove) > 0: 92 do_delete = gmGuiHelpers.gm_show_question ( 93 _( 'Successfully imported files into export area.\n' 94 '\n' 95 'Do you want to delete imported files from the filesystem ?\n' 96 '\n' 97 ' %s' 98 ) % '\n '.join(files2remove), 99 _('Removing files') 100 ) 101 if do_delete: 102 for fname in files2remove: 103 gmTools.remove_file(fname) 104 else: 105 gmDispatcher.send(signal = 'statustext', msg = _('Imported files into export area.'), beep = True) 106 return True
107 108 #if unlock_patient: 109 # pat.locked = False 110 111 #---------------------- 112 gmDispatcher.connect(signal = 'add_file_to_export_area', receiver = _add_file_to_export_area) 113 gmDispatcher.connect(signal = 'add_files_to_export_area', receiver = _add_files_to_export_area) 114 115 #============================================================ 116 from Gnumed.wxGladeWidgets import wxgExportAreaExportToMediaDlg 117
118 -class cExportAreaExportToMediaDlg(wxgExportAreaExportToMediaDlg.wxgExportAreaExportToMediaDlg):
119
120 - def __init__(self, *args, **kwargs):
121 self.__patient = kwargs['patient'] 122 del kwargs['patient'] 123 self.__item_count = kwargs['item_count'] 124 del kwargs['item_count'] 125 super().__init__(*args, **kwargs) 126 127 self.__init_ui()
128 129 #-------------------------------------------------------- 130 # event handling 131 #--------------------------------------------------------
132 - def _on_reload_media_list_button_pressed(self, event):
133 event.Skip() 134 wx.BeginBusyCursor() 135 try: 136 self.__update_media_list() 137 finally: 138 wx.EndBusyCursor()
139 140 #--------------------------------------------------------
141 - def _on_media_selected(self, event):
142 self.__update_ui_state()
143 144 #--------------------------------------------------------
145 - def _on_media_deselected(self, event):
146 self.__update_ui_state()
147 148 #--------------------------------------------------------
149 - def _on_use_subdirectory_toggled(self, event):
150 event.Skip() 151 self.__update_ui_state()
152 153 #--------------------------------------------------------
154 - def _on_open_directory_button_pressed(self, event):
155 event.Skip() 156 path = self.__calc_path() 157 if not os.path.isdir(path): 158 return 159 gmMimeLib.call_viewer_on_file(path, block = False)
160 161 #--------------------------------------------------------
162 - def _on_clear_directory_button_pressed(self, event):
163 event.Skip() 164 path = self.__calc_path() 165 if not os.path.isdir(path): 166 return 167 168 delete_data = gmGuiHelpers.gm_show_question ( 169 title = _('Clearing out a directory'), 170 question = _( 171 'Do you really want to delete all existing data\n' 172 'from the following directory ?\n' 173 '\n' 174 ' %s\n' 175 '\n' 176 'Note, this can NOT be reversed without backups.' 177 ) % path, 178 cancel_button = False 179 ) 180 if delete_data: 181 gmTools.rm_dir_content(path) 182 self.__update_ui_state()
183 184 #--------------------------------------------------------
185 - def _on_save2media_button_pressed(self, event):
186 event.Skip() 187 188 path = self.__calc_path() 189 if path is None: 190 return # no media selected, should not happen 191 if path == -2: # not mounted, should not happen 192 return 193 if path == -1: # optical drive 194 if self.__burn_script is None: 195 return # no burn script, should not happen 196 197 self.EndModal(wx.ID_SAVE)
198 199 #-------------------------------------------------------- 200 # internal API 201 #--------------------------------------------------------
202 - def __init_ui(self):
203 msg = _( 204 '\n' 205 'Number of entries to export: %s\n' 206 '\n' 207 'Patient: %s\n' 208 '\n' 209 'Select the media to export onto below.\n' 210 ) % ( 211 self.__item_count, 212 self.__patient['description_gender'] 213 ) 214 self._LBL_header.Label = msg 215 self._LCTRL_removable_media.set_columns([_('Type'), _('Medium'), _('Details')]) 216 self._LCTRL_removable_media.set_column_widths([wx.LIST_AUTOSIZE, wx.LIST_AUTOSIZE]) 217 self._LCTRL_removable_media.set_resize_column() 218 self._LCTRL_removable_media.select_callback = self._on_media_selected 219 self._LCTRL_removable_media.deselect_callback = self._on_media_deselected 220 221 self.__update_media_list() 222 self.__update_ui_state()
223 224 #--------------------------------------------------------
225 - def __calc_path(self):
226 media = self._LCTRL_removable_media.get_selected_item_data(only_one = True) 227 if media is None: 228 return None 229 230 if media['type'] == 'cd': 231 return -1 232 233 if media['is_mounted'] is False: 234 return -2 235 236 mnt_path = media['mountpoint'] 237 if self._CHBOX_use_subdirectory.IsChecked(): 238 return os.path.join(mnt_path, self.__patient.subdir_name) 239 240 return mnt_path
241 242 #--------------------------------------------------------
243 - def __update_media_list(self):
244 245 self._LCTRL_removable_media.remove_items_safely() 246 items = [] 247 data = [] 248 249 found, self.__burn_script = gmShellAPI.detect_external_binary('gm-burn_doc') 250 251 # USB / MMC drives 252 removable_partitions = gmTools.enumerate_removable_partitions() 253 for key in removable_partitions: 254 part = removable_partitions[key] 255 if part['is_mounted'] is False: 256 continue 257 items.append ([ 258 part['bus'].upper(), 259 _('%s (%s %s) - %s free') % ( 260 part['fs_label'], 261 part['vendor'], 262 part['model'], 263 gmTools.size2str(part['bytes_free']) 264 ), 265 _('%s (%s): %s in %s on %s') % ( 266 part['mountpoint'], 267 gmTools.size2str(part['size_in_bytes']), 268 part['fs_type'], 269 part['partition'], 270 part['device'] 271 ) 272 ]) 273 data.append(part) 274 for key in removable_partitions: 275 part = removable_partitions[key] 276 if part['is_mounted'] is True: 277 continue 278 items.append ([ 279 part['bus'].upper(), 280 '%s (%s %s)' % ( 281 part['fs_label'], 282 part['vendor'], 283 part['model'] 284 ), 285 _('%s on %s, not mounted') % ( 286 part['partition'], 287 part['device'] 288 ) 289 ]) 290 data.append(part) 291 292 # optical drives: CD/DVD/BD 293 optical_writers = gmTools.enumerate_optical_writers() 294 for cdrw in optical_writers: 295 items.append ([ 296 cdrw['type'].upper(), 297 cdrw['model'], 298 cdrw['device'] 299 ]) 300 data.append(cdrw) 301 302 self._LCTRL_removable_media.set_string_items(items) 303 self._LCTRL_removable_media.set_data(data) 304 self._LCTRL_removable_media.set_column_widths() 305 306 self._BTN_save2media.Disable()
307 308 #--------------------------------------------------------
309 - def __update_ui_state(self):
310 311 media = self._LCTRL_removable_media.get_selected_item_data(only_one = True) 312 if media is None: 313 self._BTN_save2media.Disable() 314 self._BTN_open_directory.Disable() 315 self._BTN_clear_directory.Disable() 316 self._CHBOX_encrypt.Disable() 317 self._CHBOX_use_subdirectory.Disable() 318 self._LBL_directory.Label = '' 319 self._LBL_dir_is_empty.Label = '' 320 return 321 322 if media['type'] == 'cd': 323 self._BTN_open_directory.Disable() 324 self._BTN_clear_directory.Disable() 325 self._LBL_directory.Label = '' 326 if self.__burn_script is None: 327 self._BTN_save2media.Disable() 328 self._CHBOX_use_subdirectory.Disable() 329 self._CHBOX_encrypt.Disable() 330 self._LBL_dir_is_empty.Label = _('helper <gm-burn_doc(.bat)> not found') 331 else: 332 self._BTN_save2media.Enable() 333 self._CHBOX_use_subdirectory.Enable() 334 self._CHBOX_encrypt.Enable() 335 self._LBL_dir_is_empty.Label = '' 336 return 337 338 if media['is_mounted'] is False: 339 self._BTN_save2media.Disable() 340 self._BTN_open_directory.Disable() 341 self._BTN_clear_directory.Disable() 342 self._CHBOX_use_subdirectory.Disable() 343 self._CHBOX_encrypt.Disable() 344 self._LBL_directory.Label = '' 345 self._LBL_dir_is_empty.Label = _('media not mounted') 346 return 347 348 self._BTN_save2media.Enable() 349 self._CHBOX_use_subdirectory.Enable() 350 self._CHBOX_encrypt.Enable() 351 352 path = self.__calc_path() 353 self._LBL_directory.Label = path + os.sep 354 is_empty = gmTools.dir_is_empty(directory = path) 355 if is_empty is True: 356 self._LBL_dir_is_empty.Label = '' 357 self._BTN_open_directory.Enable() 358 self._BTN_clear_directory.Disable() 359 elif is_empty is False: 360 self._LBL_dir_is_empty.Label = _('directory contains data') 361 self._BTN_open_directory.Enable() 362 self._BTN_clear_directory.Enable() 363 else: # we don't know, say, use_subdir and subdir does not yet exist 364 self._LBL_dir_is_empty.Label = '' 365 self._BTN_open_directory.Disable() 366 self._BTN_clear_directory.Disable()
367 368 #============================================================ 369 from Gnumed.wxGladeWidgets import wxgExportAreaSaveAsDlg 370
371 -class cExportAreaSaveAsDlg(wxgExportAreaSaveAsDlg.wxgExportAreaSaveAsDlg):
372
373 - def __init__(self, *args, **kwargs):
374 self.__patient = kwargs['patient'] 375 del kwargs['patient'] 376 self.__item_count = kwargs['item_count'] 377 del kwargs['item_count'] 378 super().__init__(*args, **kwargs) 379 380 self.__init_ui()
381 382 #-------------------------------------------------------- 383 # event handlers 384 #--------------------------------------------------------
385 - def _on_use_subdirectory_toggled(self, event):
386 event.Skip() 387 self.__update_ui_state()
388 389 #--------------------------------------------------------
390 - def _on_save_as_encrypted_toggled(self, event):
391 event.Skip() 392 self.__update_ui_state()
393 394 #--------------------------------------------------------
395 - def _on_select_directory_button_pressed(self, event):
396 event.Skip() 397 curr_path = self._LBL_directory.Label.rstrip(os.sep).rstrip('/') 398 if not os.path.isdir(curr_path): 399 curr_path = os.path.join(gmTools.gmPaths().home_dir, 'gnumed') 400 msg = _('Select directory where to save the archive or files.') 401 dlg = wx.DirDialog(self, message = msg, defaultPath = curr_path, style = wx.DD_DEFAULT_STYLE)# | wx.DD_DIR_MUST_EXIST) 402 choice = dlg.ShowModal() 403 selected_path = dlg.GetPath().rstrip(os.sep).rstrip('/') 404 dlg.DestroyLater() 405 if choice != wx.ID_OK: 406 return 407 408 self._LBL_directory.Label = selected_path + os.sep 409 self.__update_ui_state()
410 411 #--------------------------------------------------------
412 - def _on_open_directory_button_pressed(self, event):
413 event.Skip() 414 path = self._LBL_directory.Label.strip().rstrip(os.sep).rstrip('/') 415 if not os.path.isdir(path): 416 return 417 gmMimeLib.call_viewer_on_file(path, block = False)
418 419 #--------------------------------------------------------
420 - def _on_clear_directory_button_pressed(self, event):
421 event.Skip() 422 path = self._LBL_directory.Label.strip().rstrip(os.sep).rstrip('/') 423 if not os.path.isdir(path): 424 return 425 delete_data = gmGuiHelpers.gm_show_question ( 426 title = _('Clearing out a directory'), 427 question = _( 428 'Do you really want to delete all existing data\n' 429 'from the following directory ?\n' 430 '\n' 431 ' %s\n' 432 '\n' 433 'Note, this can NOT be reversed without backups.' 434 ) % path, 435 cancel_button = False 436 ) 437 if delete_data: 438 gmTools.rm_dir_content(path) 439 self.__update_ui_state()
440 441 #--------------------------------------------------------
442 - def _on_save_archive_button_pressed(self, event):
443 event.Skip() 444 self.EndModal(wx.ID_SAVE)
445 446 #-------------------------------------------------------- 447 # internal API 448 #--------------------------------------------------------
449 - def __init_ui(self):
450 msg = ('\n' + _('Number of entries to save: %s') + '\n\n' + _('Patient: %s') + '\n') % ( 451 self.__item_count, 452 self.__patient['description_gender'] 453 ) 454 self._LBL_header.Label = msg 455 self._LBL_directory.Label = os.path.join(gmTools.gmPaths().home_dir, 'gnumed', self.__patient.subdir_name) + os.sep 456 self.__update_ui_state()
457 458 #--------------------------------------------------------
459 - def __update_ui_state(self):
460 subdir_name = self.__patient.subdir_name 461 path = self._LBL_directory.Label.strip().rstrip(os.sep).rstrip('/') 462 if self._CHBOX_use_subdirectory.IsChecked(): 463 # add subdir if needed 464 if not path.endswith(subdir_name): 465 path = os.path.join(path, subdir_name) 466 self._LBL_directory.Label = path + os.sep 467 else: 468 # remove subdir if there 469 if path.endswith(subdir_name): 470 path = path[:-len(subdir_name)].rstrip(os.sep).rstrip('/') 471 self._LBL_directory.Label = path + os.sep 472 473 if self._CHBOX_encrypt.IsChecked(): 474 self._CHBOX_convert2pdf.Enable() 475 else: 476 self._CHBOX_convert2pdf.Disable() 477 478 is_empty = gmTools.dir_is_empty(directory = path) 479 if is_empty is True: 480 self._LBL_dir_is_empty.Label = '' 481 self._BTN_open_directory.Disable() 482 self._BTN_clear_directory.Disable() 483 self._BTN_save_files.Enable() 484 self._BTN_save_archive.Enable() 485 elif is_empty is False: 486 self._LBL_dir_is_empty.Label = _('directory contains data') 487 self._BTN_open_directory.Enable() 488 self._BTN_clear_directory.Enable() 489 self._BTN_save_files.Disable() 490 self._BTN_save_archive.Disable() 491 else: # we don't know, say, use_subdir and subdir does not yet exist 492 self._LBL_dir_is_empty.Label = '' 493 self._BTN_open_directory.Disable() 494 self._BTN_clear_directory.Disable() 495 self._BTN_save_files.Enable() 496 self._BTN_save_archive.Enable() 497 498 self.Layout()
499 500 #============================================================ 501 from Gnumed.wxGladeWidgets import wxgExportAreaPluginPnl 502
503 -class cExportAreaPluginPnl(wxgExportAreaPluginPnl.wxgExportAreaPluginPnl, gmRegetMixin.cRegetOnPaintMixin):
504 """Panel holding a number of items for further processing. 505 506 Acts on the current patient. 507 508 Used as notebook page."""
509 - def __init__(self, *args, **kwargs):
510 wxgExportAreaPluginPnl.wxgExportAreaPluginPnl.__init__(self, *args, **kwargs) 511 gmRegetMixin.cRegetOnPaintMixin.__init__(self) 512 self.__init_ui() 513 self.__register_interests()
514 515 #-------------------------------------------------------- 516 # event handling 517 #--------------------------------------------------------
518 - def __register_interests(self):
519 gmDispatcher.connect(signal = 'pre_patient_unselection', receiver = self._on_pre_patient_unselection) 520 # gmDispatcher.connect(signal = u'post_patient_selection', receiver = self._schedule_data_reget) 521 gmDispatcher.connect(signal = 'gm_table_mod', receiver = self._on_table_mod)
522 523 #--------------------------------------------------------
525 self._LCTRL_items.set_string_items([])
526 527 #--------------------------------------------------------
528 - def _on_table_mod(self, *args, **kwargs):
529 if kwargs['table'] != 'clin.export_item': 530 return 531 pat = gmPerson.gmCurrentPatient() 532 if not pat.connected: 533 return 534 if kwargs['pk_identity'] != pat.ID: 535 return 536 self._schedule_data_reget()
537 538 #--------------------------------------------------------
539 - def _on_list_item_selected(self, event):
540 event.Skip()
541 542 #--------------------------------------------------------
543 - def _on_show_item_button_pressed(self, event):
544 event.Skip() 545 item = self._LCTRL_items.get_selected_item_data(only_one = True) 546 if item is None: 547 return 548 item.display_via_mime(block = False)
549 550 #--------------------------------------------------------
551 - def _on_add_items_button_pressed(self, event):
552 event.Skip() 553 dlg = wx.FileDialog ( 554 parent = self, 555 message = _("Select files to add to the export area"), 556 defaultDir = os.path.expanduser(os.path.join('~', 'gnumed')), 557 style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST | wx.FD_MULTIPLE | wx.FD_PREVIEW 558 ) 559 choice = dlg.ShowModal() 560 fnames = dlg.GetPaths() 561 dlg.DestroyLater() 562 if choice != wx.ID_OK: 563 return 564 if not gmPerson.gmCurrentPatient().export_area.add_files(fnames): 565 gmGuiHelpers.gm_show_error ( 566 title = _('Adding files to export area'), 567 error = _('Cannot add (some of) the following files to the export area:\n%s ') % '\n '.join(fnames) 568 )
569 570 #--------------------------------------------------------
571 - def _on_add_directory_button_pressed(self, event):
572 event.Skip() 573 dlg = wx.DirDialog ( 574 parent = self, 575 message = _("Select directory to add to the export area"), 576 defaultPath = os.path.expanduser(os.path.join('~', 'gnumed')), 577 style = wx.DD_DEFAULT_STYLE | wx.DD_DIR_MUST_EXIST 578 ) 579 choice = dlg.ShowModal() 580 path = dlg.GetPath() 581 dlg.DestroyLater() 582 if choice != wx.ID_OK: 583 return 584 if not gmPerson.gmCurrentPatient().export_area.add_path(path): 585 gmGuiHelpers.gm_show_error ( 586 title = _('Adding path to export area'), 587 error = _('Cannot add the following path to the export area:\n%s ') % path 588 )
589 590 #--------------------------------------------------------
591 - def _on_add_from_archive_button_pressed(self, event):
592 event.Skip() 593 selected_docs = gmDocumentWidgets.manage_documents ( 594 parent = self, 595 msg = _('Select the documents to be put into the export area:'), 596 single_selection = False 597 ) 598 if selected_docs is None: 599 return 600 gmPerson.gmCurrentPatient().export_area.add_documents(documents = selected_docs)
601 602 #--------------------------------------------------------
603 - def _on_clipboard_items_button_pressed(self, event):
604 event.Skip() 605 clip = gmGuiHelpers.clipboard2file(check_for_filename = True) 606 if clip is None: 607 return 608 if clip is False: 609 return 610 if not gmPerson.gmCurrentPatient().export_area.add_file(filename = clip, hint = _('clipboard')): 611 gmGuiHelpers.gm_show_error ( 612 title = _('Loading clipboard item (saved to file) into export area'), 613 error = _('Cannot add the following clip to the export area:\n%s ') % clip 614 )
615 616 #--------------------------------------------------------
617 - def _on_scan_items_button_pressed(self, event):
618 event.Skip() 619 scans = gmDocumentWidgets.acquire_images_from_capture_device(calling_window = self) 620 if scans is None: 621 return 622 623 if not gmPerson.gmCurrentPatient().export_area.add_files(scans, _('scan')): 624 gmGuiHelpers.gm_show_error ( 625 title = _('Scanning files into export area'), 626 error = _('Cannot add (some of) the following scans to the export area:\n%s ') % '\n '.join(fnames) 627 )
628 629 #--------------------------------------------------------
630 - def _on_remove_items_button_pressed(self, event):
631 event.Skip() 632 items = self._LCTRL_items.get_selected_item_data(only_one = False) 633 if len(items) == 0: 634 return 635 really_delete = gmGuiHelpers.gm_show_question ( 636 title = _('Deleting document from export area.'), 637 question = _('Really remove %s selected document(s)\nfrom the patient export area ?') % len(items) 638 ) 639 if not really_delete: 640 return 641 for item in items: 642 gmPerson.gmCurrentPatient().export_area.remove_item(item)
643 644 #--------------------------------------------------------
645 - def _on_print_items_button_pressed(self, event):
646 event.Skip() 647 items = self._LCTRL_items.get_selected_item_data(only_one = False) 648 if len(items) == 0: 649 return 650 651 files2print = [] 652 for item in items: 653 files2print.append(item.save_to_file()) 654 655 if len(files2print) == 0: 656 return 657 658 jobtype = 'export_area' 659 printed = gmPrinting.print_files(filenames = files2print, jobtype = jobtype, verbose = _cfg.get(option = 'debug')) 660 if not printed: 661 gmGuiHelpers.gm_show_error ( 662 aMessage = _('Error printing documents.'), 663 aTitle = _('Printing [%s]') % jobtype 664 ) 665 return False 666 667 self.__save_soap_note(soap = _('Printed:\n - %s') % '\n - '.join([ i['description'] for i in items ])) 668 return True
669 670 #--------------------------------------------------------
671 - def _on_remote_print_button_pressed(self, event):
672 event.Skip() 673 items = self._LCTRL_items.get_selected_item_data(only_one = False) 674 if len(items) == 0: 675 return 676 for item in items: 677 item.is_print_job = True 678 gmDispatcher.send(signal = 'statustext', msg = _('Item(s) moved to Print Center.'))
679 680 #--------------------------------------------------------
681 - def _on_save_items_button_pressed(self, event):
682 event.Skip() 683 684 items = self.__get_items_to_work_on(_('Saving entries')) 685 if items is None: 686 return 687 688 pat = gmPerson.gmCurrentPatient() 689 dlg = cExportAreaSaveAsDlg(self, -1, patient = pat, item_count = len(items)) 690 choice = dlg.ShowModal() 691 path = dlg._LBL_directory.Label 692 generate_metadata = dlg._CHBOX_generate_metadata.IsChecked() 693 use_subdir = dlg._CHBOX_use_subdirectory.IsChecked() 694 encrypt = dlg._CHBOX_encrypt.IsChecked() 695 convert2pdf = dlg._CHBOX_convert2pdf.IsChecked() 696 dlg.DestroyLater() 697 if choice == wx.ID_CANCEL: 698 return 699 700 if choice == wx.ID_SAVE: 701 create_archive = True 702 elif choice == wx.ID_OK: 703 create_archive = False 704 else: 705 raise Exception('invalid return') 706 707 if create_archive: 708 export_dir = path 709 zip_file = self.__export_as_zip ( 710 gmTools.coalesce ( 711 value2test = encrypt, 712 value2return = _('Saving entries as encrypted ZIP archive'), 713 return_instead = _('Saving entries as unencrypted ZIP archive') 714 ), 715 items = items, 716 encrypt = encrypt 717 ) 718 if zip_file is None: 719 gmDispatcher.send(signal = 'statustext', msg = _('Cannot save: aborted or error.')) 720 return 721 gmTools.mkdir(export_dir) 722 final_zip_file = shutil.move(zip_file, export_dir) 723 gmDispatcher.send(signal = 'statustext', msg = _('Saved entries into [%s]') % final_zip_file) 724 target = final_zip_file 725 else: 726 export_dir = self.__export_as_files ( 727 gmTools.coalesce ( 728 value2test = encrypt, 729 value2return = _('Saving entries as encrypted files'), 730 return_instead = _('Saving entries as unencrypted files') 731 ), 732 base_dir = path, 733 items = items, 734 encrypt = encrypt, 735 with_metadata = generate_metadata, 736 convert2pdf = convert2pdf 737 ) 738 if export_dir is None: 739 gmDispatcher.send(signal = 'statustext', msg = _('Cannot save: aborted or error.')) 740 return 741 742 gmDispatcher.send(signal = 'statustext', msg = _('Saved entries into [%s]') % export_dir) 743 target = export_dir 744 745 self.__save_soap_note(soap = _('Saved from export area to [%s]:\n - %s') % ( 746 target, 747 '\n - '.join([ i['description'] for i in items ]) 748 )) 749 self.__browse_patient_data(export_dir) 750 751 # remove_entries ? 752 753 return True
754 755 # cleanup - ask ! 756 # - files corresponding to DIR/DIR CONTENT entries 757 # - entries in export area 758 # remove_items = gmGuiHelpers.gm_show_question ( 759 # title = _('Creating zip archive'), 760 # question = _( 761 # 'Zip archive created as:\n' 762 # '\n' 763 # ' [%s]\n' 764 # '\n' 765 # 'Remove archived entries from export area ?' 766 # ) % zip_file, 767 # cancel_button = False 768 # ) 769 # if remove_items: 770 # exp_area.remove_items(items = items) 771 # return True 772 773 #--------------------------------------------------------
774 - def _on_export_items_button_pressed(self, event):
775 event.Skip() 776 777 items = self.__get_items_to_work_on(_('Exporting entries')) 778 if items is None: 779 return 780 781 # export dialog 782 pat = gmPerson.gmCurrentPatient() 783 dlg = cExportAreaExportToMediaDlg(self, -1, patient = pat, item_count = len(items)) 784 choice = dlg.ShowModal() 785 media = dlg._LCTRL_removable_media.get_selected_item_data(only_one = True) 786 use_subdir = dlg._CHBOX_use_subdirectory.IsChecked() 787 encrypt = dlg._CHBOX_encrypt.IsChecked() 788 dlg.DestroyLater() 789 if choice == wx.ID_CANCEL: 790 return 791 792 # export the files 793 if media['type'] == 'cd': 794 base_dir = gmTools.mk_sandbox_dir(prefix = 'iso-') 795 else: 796 base_dir = media['mountpoint'] 797 if use_subdir: 798 dir2save2 = os.path.join(base_dir, pat.subdir_name) 799 else: 800 dir2save2 = base_dir 801 export_dir = self.__export_as_files ( 802 gmTools.coalesce(encrypt, _('Exporting encrypted entries'), _('Exporting entries')), 803 base_dir = dir2save2, 804 items = items, 805 encrypt = encrypt, 806 with_metadata = True 807 ) 808 if export_dir is None: 809 gmDispatcher.send(signal = 'statustext', msg = _('Cannot export: aborted or error.')) 810 return 811 812 if media['type'] == 'cd': 813 if not self.__burn_dir_to_disk(base_dir = base_dir): 814 return 815 gmDispatcher.send(signal = 'statustext', msg = _('Entries successfully burned to disk.')) 816 self.__save_soap_note(soap = _('Burned onto CD/DVD:\n - %s') % '\n - '.join([ i['description'] for i in items ])) 817 else: 818 gmDispatcher.send(signal = 'statustext', msg = _('Exported entries into [%s]') % export_dir) 819 self.__save_soap_note(soap = _('Exported onto removable media:\n - %s') % '\n - '.join([ i['description'] for i in items ])) 820 821 self.__browse_patient_data(dir2save2, encrypted = encrypt, archive = False, has_metadata = True) 822 823 # remove_entries ? 824 825 return True
826 827 #--------------------------------------------------------
828 - def _on_archive_items_button_pressed(self, event):
829 print("Event handler '_on_archive_items_button_pressed' not implemented!") 830 event.Skip()
831 832 #--------------------------------------------------------
833 - def _on_mail_items_button_pressed(self, event):
834 event.Skip() 835 836 _log.debug('gm-mail_doc(.bat) API: "MAIL-PROGRAM PRAXIS-VCF ZIP-ARCHIVE"') 837 838 found, external_cmd = gmShellAPI.detect_external_binary('gm-mail_doc') 839 if not found: 840 gmDispatcher.send(signal = 'statustext', msg = _('Cannot send e-mail: <gm-mail_doc(.bat)> not found')) 841 return False 842 843 zip_file = self.__export_as_zip ( 844 _('Mailing documents as zip archive'), 845 encrypt = True 846 ) 847 if zip_file is None: 848 gmDispatcher.send(signal = 'statustext', msg = _('Cannot send e-mail: no archive created.')) 849 return False 850 851 prax = gmPraxis.gmCurrentPraxisBranch() 852 args = [external_cmd, prax.vcf, zip_file] 853 success, ret_code, stdout = gmShellAPI.run_process(cmd_line = args, verbose = _cfg.get(option = 'debug')) 854 if not success: 855 gmGuiHelpers.gm_show_error ( 856 aMessage = _('Error mailing documents.'), 857 aTitle = _('Mailing documents') 858 ) 859 return False 860 861 #self.__save_soap_note(soap = _('Mailed:\n - %s') % '\n - '.join([ i['description'] for i in items ])) 862 self.__save_soap_note(soap = _('Mailed export area content.')) 863 return True
864 865 #--------------------------------------------------------
866 - def _on_fax_items_button_pressed(self, event):
867 event.Skip() 868 869 _log.debug('gm-fax_doc(.bat) API: "FAX-PROGRAM FAXNUMBER-OR-<EMPTY> LIST-OF-FILES-TO-FAX" (any file type !)') 870 871 found, external_cmd = gmShellAPI.detect_external_binary('gm-fax_doc') 872 if not found: 873 gmDispatcher.send(signal = 'statustext', msg = _('Cannot send fax: <gm-fax_doc(.bat)> not found')) 874 return False 875 876 items = self._LCTRL_items.get_selected_item_data(only_one = False) 877 if len(items) == 0: 878 items = self._LCTRL_items.get_item_data() 879 if len(items) == 0: 880 gmDispatcher.send(signal = 'statustext', msg = _('Cannot send fax: no items')) 881 return None 882 if len(items) > 1: 883 # ask, might be a lot 884 process_all = gmGuiHelpers.gm_show_question ( 885 title = _('Faxing documents'), 886 question = _('You have not selected any entries.\n\nSend fax with all %s entries ?') % len(items), 887 cancel_button = False 888 ) 889 if not process_all: 890 return None 891 892 return False 893 894 files2fax = [] 895 for item in items: 896 files2fax.append(item.save_to_file()) 897 fax_number = wx.GetTextFromUser ( 898 _('Please enter the fax number here !\n\n' 899 'It can be left empty if the external\n' 900 'fax software knows how to get the number.'), 901 caption = _('Faxing documents'), 902 parent = self, 903 centre = True 904 ) 905 if fax_number == '': 906 fax_number = 'EMPTY' 907 args = [external_cmd, fax_number, ' '.join(files2fax)] 908 success, ret_code, stdout = gmShellAPI.run_process(cmd_line = args, verbose = _cfg.get(option = 'debug')) 909 if not success: 910 gmGuiHelpers.gm_show_error ( 911 aMessage = _('Error faxing documents to\n\n %s') % fax_number, 912 aTitle = _('Faxing documents') 913 ) 914 return False 915 916 self.__save_soap_note(soap = _('Faxed to [%s]:\n - %s') % (fax_number, '\n - '.join([ i['description'] for i in items ]))) 917 return True
918 919 #--------------------------------------------------------
920 - def repopulate_ui(self):
921 self._populate_with_data()
922 923 #-------------------------------------------------------- 924 # internal API 925 #--------------------------------------------------------
926 - def __init_ui(self):
927 self._LCTRL_items.set_columns([_('By'), _('When'), _('Description')]) 928 929 self._BTN_archive_items.Disable() 930 931 # there's no GetToolTipText() in wx2.8 932 self.__mail_script_exists, path = gmShellAPI.detect_external_binary(binary = r'gm-mail_doc') 933 if not self.__mail_script_exists: 934 self._BTN_mail_items.Disable() 935 tt = self._BTN_mail_items.GetToolTipText() + '\n\n' + _('<gm-mail_doc(.bat) not found>') 936 self._BTN_mail_items.SetToolTip(tt) 937 938 self.__fax_script_exists, path = gmShellAPI.detect_external_binary(binary = r'gm-fax_doc') 939 if not self.__fax_script_exists: 940 self._BTN_fax_items.Disable() 941 tt = self._BTN_fax_items.GetToolTipText() + '\n\n' + _('<gm-fax_doc(.bat) not found>') 942 self._BTN_fax_items.SetToolTip(tt) 943 944 self.__burn_script_exists, path = gmShellAPI.detect_external_binary(binary = r'gm-burn_doc') 945 if not self.__burn_script_exists: 946 self._BTN_burn_items.Disable() 947 tt = self._BTN_burn_items.GetToolTipText() + '\n\n' + _('<gm-burn_doc(.bat) not found>') 948 self._BTN_burn_items.SetToolTip(tt) 949 950 # make me and listctrl file drop targets 951 dt = gmGuiHelpers.cFileDropTarget(target = self) 952 self.SetDropTarget(dt) 953 dt = gmGuiHelpers.cFileDropTarget(on_drop_callback = self._drop_target_consume_filenames) 954 self._LCTRL_items.SetDropTarget(dt)
955 956 #--------------------------------------------------------
957 - def __save_soap_note(self, soap=None):
958 if soap.strip() == '': 959 return 960 emr = gmPerson.gmCurrentPatient().emr 961 epi = emr.add_episode(episode_name = 'administrative', is_open = False) 962 emr.add_clin_narrative ( 963 soap_cat = None, 964 note = soap, 965 episode = epi 966 )
967 968 #--------------------------------------------------------
969 - def __export_as_files(self, msg_title, base_dir=None, encrypt=False, with_metadata=False, items=None, convert2pdf=False):
970 data_pwd = None 971 if encrypt: 972 data_pwd = self.__get_password(msg_title) 973 if data_pwd is None: 974 _log.debug('user aborted by not providing the same password twice') 975 gmDispatcher.send(signal = 'statustext', msg = _('Password not provided twice. Aborting.')) 976 return None 977 978 wx.BeginBusyCursor() 979 try: 980 exp_area = gmPerson.gmCurrentPatient().export_area 981 if with_metadata: 982 export_dir = exp_area.export(base_dir = base_dir, items = items, passphrase = data_pwd) 983 else: 984 export_dir = exp_area.dump_items_to_disk(base_dir = base_dir, items = items, passphrase = data_pwd, convert2pdf = convert2pdf) 985 finally: 986 wx.EndBusyCursor() 987 if export_dir is None: 988 gmGuiHelpers.gm_show_error ( 989 aMessage = _('Error exporting entries.'), 990 aTitle = msg_title 991 ) 992 return None 993 994 return export_dir
995 996 #--------------------------------------------------------
997 - def __export_as_zip(self, msg_title, encrypt=True, items=None):
998 # get password 999 zip_pwd = None 1000 if encrypt: 1001 zip_pwd = self.__get_password(msg_title) 1002 if zip_pwd is None: 1003 _log.debug('user aborted by not providing the same password twice') 1004 gmDispatcher.send(signal = 'statustext', msg = _('Password not provided twice. Aborting.')) 1005 return None 1006 # create archive 1007 wx.BeginBusyCursor() 1008 zip_file = None 1009 try: 1010 exp_area = gmPerson.gmCurrentPatient().export_area 1011 zip_file = exp_area.export_as_zip(passphrase = zip_pwd, items = items) 1012 except Exception: 1013 _log.exception('cannot create zip file') 1014 wx.EndBusyCursor() 1015 if zip_file is None: 1016 gmGuiHelpers.gm_show_error ( 1017 aMessage = _('Error creating zip file.'), 1018 aTitle = msg_title 1019 ) 1020 return zip_file
1021 1022 #--------------------------------------------------------
1023 - def __get_password(self, msg_title):
1024 while True: 1025 data_pwd = wx.GetPasswordFromUser ( 1026 message = _( 1027 'Enter passphrase to protect the data with.\n' 1028 '\n' 1029 '(minimum length: 5, trailing blanks will be stripped)' 1030 ), 1031 caption = msg_title 1032 ) 1033 # minimal weakness check 1034 data_pwd = data_pwd.rstrip() 1035 if len(data_pwd) > 4: 1036 break 1037 retry = gmGuiHelpers.gm_show_question ( 1038 title = msg_title, 1039 question = _( 1040 'Insufficient passphrase.\n' 1041 '\n' 1042 '(minimum length: 5, trailing blanks will be stripped)\n' 1043 '\n' 1044 'Enter another passphrase ?' 1045 ) 1046 ) 1047 if not retry: 1048 # user changed her mind 1049 return None 1050 # confidentiality 1051 gmLog2.add_word2hide(data_pwd) 1052 # reget password 1053 while True: 1054 data_pwd4comparison = wx.GetPasswordFromUser ( 1055 message = _( 1056 'Once more enter passphrase to protect the data with.\n' 1057 '\n' 1058 '(this will protect you from typos)\n' 1059 '\n' 1060 'Abort by leaving empty.' 1061 ), 1062 caption = msg_title 1063 ) 1064 data_pwd4comparison = data_pwd4comparison.rstrip() 1065 if data_pwd4comparison == '': 1066 # user changed her mind ... 1067 return None 1068 if data_pwd == data_pwd4comparison: 1069 break 1070 gmGuiHelpers.gm_show_error ( 1071 error = _( 1072 'Passphrases do not match.\n' 1073 '\n' 1074 'Retry, or abort with an empty passphrase.' 1075 ), 1076 title = msg_title 1077 ) 1078 return data_pwd
1079 1080 #--------------------------------------------------------
1081 - def __get_items_to_work_on(self, msg_title):
1082 1083 items = self._LCTRL_items.get_selected_item_data(only_one = False) 1084 if len(items) > 0: 1085 return items 1086 1087 items = self._LCTRL_items.get_item_data() 1088 if len(items) == 0: 1089 gmDispatcher.send(signal = 'statustext', msg = _('Export area empty. Nothing to do.')) 1090 return None 1091 1092 if len(items) == 1: 1093 return items 1094 1095 process_all = gmGuiHelpers.gm_show_question ( 1096 title = msg_title, 1097 question = _('You have not selected any entries.\n\nReally use all %s entries ?') % len(items), 1098 cancel_button = False 1099 ) 1100 if process_all: 1101 return items 1102 1103 return None
1104 1105 #--------------------------------------------------------
1106 - def __burn_dir_to_disk(self, base_dir):
1107 1108 _log.debug('gm-burn_doc(.bat) API: "DIRECTORY-TO-BURN-FROM"') 1109 1110 found, burn_cmd = gmShellAPI.detect_external_binary('gm-burn_doc') 1111 if not found: 1112 gmDispatcher.send(signal = 'statustext', msg = _('Cannot burn to disk: Helper not found.')) # should not happen 1113 return False 1114 1115 args = [burn_cmd, base_dir] 1116 wx.BeginBusyCursor() 1117 try: 1118 success, ret_code, stdout = gmShellAPI.run_process(cmd_line = args, verbose = _cfg.get(option = 'debug')) 1119 finally: 1120 wx.EndBusyCursor() 1121 if success: 1122 return True 1123 1124 gmGuiHelpers.gm_show_error ( 1125 aMessage = _('Error burning documents to CD/DVD.'), 1126 aTitle = _('Burning documents') 1127 ) 1128 return False
1129 1130 #--------------------------------------------------------
1131 - def __browse_patient_data(self, base_dir):
1132 1133 msg = _('Documents saved into:\n\n %s') % base_dir 1134 browse_index = gmGuiHelpers.gm_show_question ( 1135 title = _('Browsing patient data excerpt'), 1136 question = msg + '\n\n' + _('Browse saved entries ?'), 1137 cancel_button = False 1138 ) 1139 if not browse_index: 1140 return 1141 1142 if os.path.isfile(os.path.join(base_dir, 'index.html')): 1143 gmNetworkTools.open_url_in_browser(url = 'file://%s' % os.path.join(base_dir, 'index.html')) 1144 return 1145 1146 gmMimeLib.call_viewer_on_file(base_dir, block = False)
1147 1148 #-------------------------------------------------------- 1149 # file drop target API 1150 #--------------------------------------------------------
1151 - def _drop_target_consume_filenames(self, filenames):
1152 pat = gmPerson.gmCurrentPatient() 1153 if not pat.connected: 1154 gmDispatcher.send(signal = 'statustext', msg = _('Cannot accept new documents. No active patient.')) 1155 return 1156 1157 # dive into folders dropped onto us and extract files (one level deep only) 1158 real_filenames = [] 1159 for pathname in filenames: 1160 try: 1161 files = os.listdir(pathname) 1162 gmDispatcher.send(signal='statustext', msg=_('Extracting files from folder [%s] ...') % pathname) 1163 for file in files: 1164 fullname = os.path.join(pathname, file) 1165 if not os.path.isfile(fullname): 1166 continue 1167 real_filenames.append(fullname) 1168 except OSError: 1169 real_filenames.append(pathname) 1170 1171 if not pat.export_area.add_files(real_filenames, hint = _('Drag&Drop')): 1172 gmGuiHelpers.gm_show_error ( 1173 title = _('Adding files to export area'), 1174 error = _('Cannot add (some of) the following files to the export area:\n%s ') % '\n '.join(real_filenames) 1175 )
1176 #-------------------------------------------------------- 1177 # reget mixin API 1178 # 1179 # remember to call 1180 # self._schedule_data_reget() 1181 # whenever you learn of data changes from database 1182 # listener threads, dispatcher signals etc. 1183 #--------------------------------------------------------
1184 - def _populate_with_data(self):
1185 pat = gmPerson.gmCurrentPatient() 1186 if not pat.connected: 1187 return True 1188 1189 items = pat.export_area.items 1190 self._LCTRL_items.set_string_items ([ 1191 [ i['created_by'], 1192 gmDateTime.pydt_strftime(i['created_when'], '%Y %b %d %H:%M'), 1193 i['description'] 1194 ] for i in items 1195 ]) 1196 self._LCTRL_items.set_column_widths([wx.LIST_AUTOSIZE, wx.LIST_AUTOSIZE, wx.LIST_AUTOSIZE]) 1197 self._LCTRL_items.set_data(items) 1198 1199 self._LCTRL_items.SetFocus() 1200 1201 return True
1202 1203 #============================================================ 1204 from Gnumed.wxGladeWidgets import wxgPrintMgrPluginPnl 1205
1206 -class cPrintMgrPluginPnl(wxgPrintMgrPluginPnl.wxgPrintMgrPluginPnl, gmRegetMixin.cRegetOnPaintMixin):
1207 """Panel holding print jobs. 1208 1209 Used as notebook page.""" 1210
1211 - def __init__(self, *args, **kwargs):
1212 wxgPrintMgrPluginPnl.wxgPrintMgrPluginPnl.__init__(self, *args, **kwargs) 1213 gmRegetMixin.cRegetOnPaintMixin.__init__(self) 1214 self.__init_ui() 1215 self.__register_interests()
1216 #-------------------------------------------------------- 1217 # event handling 1218 #--------------------------------------------------------
1219 - def __register_interests(self):
1220 gmDispatcher.connect(signal = 'pre_patient_unselection', receiver = self._on_pre_patient_unselection) 1221 gmDispatcher.connect(signal = 'post_patient_selection', receiver = self._on_post_patient_selection) 1222 gmDispatcher.connect(signal = 'gm_table_mod', receiver = self._on_table_mod)
1223 #--------------------------------------------------------
1225 self._RBTN_active_patient_only.Enable(False) 1226 self._RBTN_all_patients.Value = True 1227 self._BTN_export_printouts.Enable(False)
1228 #--------------------------------------------------------
1229 - def _on_post_patient_selection(self):
1230 self._RBTN_active_patient_only.Enable(True) 1231 self._BTN_export_printouts.Enable(True)
1232 #--------------------------------------------------------
1233 - def _on_table_mod(self, *args, **kwargs):
1234 if kwargs['table'] != 'clin.export_item': 1235 return 1236 if self._RBTN_all_patients.Value is True: 1237 self._schedule_data_reget() 1238 return 1239 pat = gmPerson.gmCurrentPatient() 1240 if not pat.connected: 1241 return 1242 if kwargs['pk_identity'] != pat.ID: 1243 return 1244 self._schedule_data_reget()
1245 #--------------------------------------------------------
1246 - def _on_all_patients_selected(self, event):
1247 event.Skip() 1248 self._schedule_data_reget()
1249 #--------------------------------------------------------
1250 - def _on_active_patient_only_selected(self, event):
1251 event.Skip() 1252 self._schedule_data_reget()
1253 #--------------------------------------------------------
1254 - def _on_view_button_pressed(self, event):
1255 event.Skip() 1256 printout = self._LCTRL_printouts.get_selected_item_data(only_one = True) 1257 if printout is None: 1258 return 1259 printout.display_via_mime(block = False)
1260 #--------------------------------------------------------
1261 - def _on_print_button_pressed(self, event):
1262 event.Skip() 1263 printouts = self._LCTRL_printouts.get_selected_item_data(only_one = False) 1264 if len(printouts) == 0: 1265 return 1266 1267 files2print = [] 1268 for printout in printouts: 1269 files2print.append(printout.save_to_file()) 1270 1271 if len(files2print) == 0: 1272 return 1273 1274 jobtype = 'print_manager' 1275 printed = gmPrinting.print_files(filenames = files2print, jobtype = jobtype, verbose = _cfg.get(option = 'debug')) 1276 if not printed: 1277 gmGuiHelpers.gm_show_error ( 1278 aMessage = _('Error printing documents.'), 1279 aTitle = _('Printing [%s]') % jobtype 1280 ) 1281 return False 1282 1283 return True
1284 #--------------------------------------------------------
1285 - def _on_export_button_pressed(self, event):
1286 event.Skip() 1287 pat = gmPerson.gmCurrentPatient() 1288 if not pat.connected: 1289 return 1290 printouts = self._LCTRL_printouts.get_selected_item_data(only_one = False) 1291 for printout in printouts: 1292 printout.is_print_job = False
1293 #--------------------------------------------------------
1294 - def _on_delete_button_pressed(self, event):
1295 event.Skip() 1296 printouts = self._LCTRL_printouts.get_selected_item_data(only_one = False) 1297 if len(printouts) == 0: 1298 return 1299 if len(printouts) > 1: 1300 really_delete = gmGuiHelpers.gm_show_question ( 1301 title = _('Deleting document from export area.'), 1302 question = _('Really remove %s selected document(s)\nfrom the patient export area ?') % len(printouts) 1303 ) 1304 if not really_delete: 1305 return 1306 for printout in printouts: 1307 gmExportArea.delete_export_item(pk_export_item = printout['pk_export_item'])
1308 1309 #-------------------------------------------------------- 1310 # internal API 1311 #--------------------------------------------------------
1312 - def __init_ui(self):
1313 self._BTN_export_printouts.Enable(False)
1314 #-------------------------------------------------------- 1315 # reget mixin API 1316 #--------------------------------------------------------
1317 - def _populate_with_data(self):
1318 if self._RBTN_all_patients.Value is True: 1319 columns = [_('Patient'), _('Provider'), _('Description')] 1320 printouts = gmExportArea.get_print_jobs(order_by = 'pk_identity, description') 1321 items = [[ 1322 '%s, %s (%s)' % ( 1323 p['lastnames'], 1324 p['firstnames'], 1325 p['gender'] 1326 ), 1327 p['created_by'], 1328 p['description'] 1329 ] for p in printouts ] 1330 else: 1331 pat = gmPerson.gmCurrentPatient() 1332 if pat.connected: 1333 columns = [_('Provider'), _('Created'), _('Description')] 1334 printouts = pat.export_area.get_printouts(order_by = 'created_when, description') 1335 items = [[ 1336 p['created_by'], 1337 gmDateTime.pydt_strftime(p['created_when'], '%Y %b %d %H:%M'), 1338 p['description'] 1339 ] for p in printouts ] 1340 else: 1341 columns = [_('Patient'), _('Provider'), _('Description')] 1342 printouts = gmExportArea.get_print_jobs(order_by = 'pk_identity, description') 1343 items = [[ 1344 '%s, %s (%s)' % ( 1345 p['lastnames'], 1346 p['firstnames'], 1347 p['gender'] 1348 ), 1349 p['created_by'], 1350 p['description'] 1351 ] for p in printouts ] 1352 self._LCTRL_printouts.set_columns(columns) 1353 self._LCTRL_printouts.set_string_items(items) 1354 self._LCTRL_printouts.set_column_widths([wx.LIST_AUTOSIZE, wx.LIST_AUTOSIZE, wx.LIST_AUTOSIZE]) 1355 self._LCTRL_printouts.set_data(printouts) 1356 self._LCTRL_printouts.SetFocus() 1357 return True
1358