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 # this is now handled one level down in the UI 945 # self.__burn_script_exists, path = gmShellAPI.detect_external_binary(binary = r'gm-burn_doc') 946 # if not self.__burn_script_exists: 947 # self._BTN_burn_items.Disable() 948 # tt = self._BTN_burn_items.GetToolTipText() + '\n\n' + _('<gm-burn_doc(.bat) not found>') 949 # self._BTN_burn_items.SetToolTip(tt) 950 951 # make me and listctrl file drop targets 952 dt = gmGuiHelpers.cFileDropTarget(target = self) 953 self.SetDropTarget(dt) 954 dt = gmGuiHelpers.cFileDropTarget(on_drop_callback = self._drop_target_consume_filenames) 955 self._LCTRL_items.SetDropTarget(dt)
956 957 #--------------------------------------------------------
958 - def __save_soap_note(self, soap=None):
959 if soap.strip() == '': 960 return 961 emr = gmPerson.gmCurrentPatient().emr 962 epi = emr.add_episode(episode_name = 'administrative', is_open = False) 963 emr.add_clin_narrative ( 964 soap_cat = None, 965 note = soap, 966 episode = epi 967 )
968 969 #--------------------------------------------------------
970 - def __export_as_files(self, msg_title, base_dir=None, encrypt=False, with_metadata=False, items=None, convert2pdf=False):
971 data_pwd = None 972 if encrypt: 973 data_pwd = self.__get_password(msg_title) 974 if data_pwd is None: 975 _log.debug('user aborted by not providing the same password twice') 976 gmDispatcher.send(signal = 'statustext', msg = _('Password not provided twice. Aborting.')) 977 return None 978 979 wx.BeginBusyCursor() 980 try: 981 exp_area = gmPerson.gmCurrentPatient().export_area 982 if with_metadata: 983 export_dir = exp_area.export(base_dir = base_dir, items = items, passphrase = data_pwd) 984 else: 985 export_dir = exp_area.dump_items_to_disk(base_dir = base_dir, items = items, passphrase = data_pwd, convert2pdf = convert2pdf) 986 finally: 987 wx.EndBusyCursor() 988 if export_dir is None: 989 gmGuiHelpers.gm_show_error ( 990 aMessage = _('Error exporting entries.'), 991 aTitle = msg_title 992 ) 993 return None 994 995 return export_dir
996 997 #--------------------------------------------------------
998 - def __export_as_zip(self, msg_title, encrypt=True, items=None):
999 # get password 1000 zip_pwd = None 1001 if encrypt: 1002 zip_pwd = self.__get_password(msg_title) 1003 if zip_pwd is None: 1004 _log.debug('user aborted by not providing the same password twice') 1005 gmDispatcher.send(signal = 'statustext', msg = _('Password not provided twice. Aborting.')) 1006 return None 1007 # create archive 1008 wx.BeginBusyCursor() 1009 zip_file = None 1010 try: 1011 exp_area = gmPerson.gmCurrentPatient().export_area 1012 zip_file = exp_area.export_as_zip(passphrase = zip_pwd, items = items) 1013 except Exception: 1014 _log.exception('cannot create zip file') 1015 wx.EndBusyCursor() 1016 if zip_file is None: 1017 gmGuiHelpers.gm_show_error ( 1018 aMessage = _('Error creating zip file.'), 1019 aTitle = msg_title 1020 ) 1021 return zip_file
1022 1023 #--------------------------------------------------------
1024 - def __get_password(self, msg_title):
1025 while True: 1026 data_pwd = wx.GetPasswordFromUser ( 1027 message = _( 1028 'Enter passphrase to protect the data with.\n' 1029 '\n' 1030 '(minimum length: 5, trailing blanks will be stripped)' 1031 ), 1032 caption = msg_title 1033 ) 1034 # minimal weakness check 1035 data_pwd = data_pwd.rstrip() 1036 if len(data_pwd) > 4: 1037 break 1038 retry = gmGuiHelpers.gm_show_question ( 1039 title = msg_title, 1040 question = _( 1041 'Insufficient passphrase.\n' 1042 '\n' 1043 '(minimum length: 5, trailing blanks will be stripped)\n' 1044 '\n' 1045 'Enter another passphrase ?' 1046 ) 1047 ) 1048 if not retry: 1049 # user changed her mind 1050 return None 1051 # confidentiality 1052 gmLog2.add_word2hide(data_pwd) 1053 # reget password 1054 while True: 1055 data_pwd4comparison = wx.GetPasswordFromUser ( 1056 message = _( 1057 'Once more enter passphrase to protect the data with.\n' 1058 '\n' 1059 '(this will protect you from typos)\n' 1060 '\n' 1061 'Abort by leaving empty.' 1062 ), 1063 caption = msg_title 1064 ) 1065 data_pwd4comparison = data_pwd4comparison.rstrip() 1066 if data_pwd4comparison == '': 1067 # user changed her mind ... 1068 return None 1069 if data_pwd == data_pwd4comparison: 1070 break 1071 gmGuiHelpers.gm_show_error ( 1072 error = _( 1073 'Passphrases do not match.\n' 1074 '\n' 1075 'Retry, or abort with an empty passphrase.' 1076 ), 1077 title = msg_title 1078 ) 1079 return data_pwd
1080 1081 #--------------------------------------------------------
1082 - def __get_items_to_work_on(self, msg_title):
1083 1084 items = self._LCTRL_items.get_selected_item_data(only_one = False) 1085 if len(items) > 0: 1086 return items 1087 1088 items = self._LCTRL_items.get_item_data() 1089 if len(items) == 0: 1090 gmDispatcher.send(signal = 'statustext', msg = _('Export area empty. Nothing to do.')) 1091 return None 1092 1093 if len(items) == 1: 1094 return items 1095 1096 process_all = gmGuiHelpers.gm_show_question ( 1097 title = msg_title, 1098 question = _('You have not selected any entries.\n\nReally use all %s entries ?') % len(items), 1099 cancel_button = False 1100 ) 1101 if process_all: 1102 return items 1103 1104 return None
1105 1106 #--------------------------------------------------------
1107 - def __burn_dir_to_disk(self, base_dir):
1108 1109 _log.debug('gm-burn_doc(.bat) API: "DIRECTORY-TO-BURN-FROM"') 1110 1111 found, burn_cmd = gmShellAPI.detect_external_binary('gm-burn_doc') 1112 if not found: 1113 gmDispatcher.send(signal = 'statustext', msg = _('Cannot burn to disk: Helper not found.')) # should not happen 1114 return False 1115 1116 args = [burn_cmd, base_dir] 1117 wx.BeginBusyCursor() 1118 try: 1119 success, ret_code, stdout = gmShellAPI.run_process(cmd_line = args, verbose = _cfg.get(option = 'debug')) 1120 finally: 1121 wx.EndBusyCursor() 1122 if success: 1123 return True 1124 1125 gmGuiHelpers.gm_show_error ( 1126 aMessage = _('Error burning documents to CD/DVD.'), 1127 aTitle = _('Burning documents') 1128 ) 1129 return False
1130 1131 #--------------------------------------------------------
1132 - def __browse_patient_data(self, base_dir):
1133 1134 msg = _('Documents saved into:\n\n %s') % base_dir 1135 browse_index = gmGuiHelpers.gm_show_question ( 1136 title = _('Browsing patient data excerpt'), 1137 question = msg + '\n\n' + _('Browse saved entries ?'), 1138 cancel_button = False 1139 ) 1140 if not browse_index: 1141 return 1142 1143 if os.path.isfile(os.path.join(base_dir, 'index.html')): 1144 gmNetworkTools.open_url_in_browser(url = 'file://%s' % os.path.join(base_dir, 'index.html')) 1145 return 1146 1147 gmMimeLib.call_viewer_on_file(base_dir, block = False)
1148 1149 #-------------------------------------------------------- 1150 # file drop target API 1151 #--------------------------------------------------------
1152 - def _drop_target_consume_filenames(self, filenames):
1153 pat = gmPerson.gmCurrentPatient() 1154 if not pat.connected: 1155 gmDispatcher.send(signal = 'statustext', msg = _('Cannot accept new documents. No active patient.')) 1156 return 1157 1158 # dive into folders dropped onto us and extract files (one level deep only) 1159 real_filenames = [] 1160 for pathname in filenames: 1161 try: 1162 files = os.listdir(pathname) 1163 gmDispatcher.send(signal='statustext', msg=_('Extracting files from folder [%s] ...') % pathname) 1164 for file in files: 1165 fullname = os.path.join(pathname, file) 1166 if not os.path.isfile(fullname): 1167 continue 1168 real_filenames.append(fullname) 1169 except OSError: 1170 real_filenames.append(pathname) 1171 1172 if not pat.export_area.add_files(real_filenames, hint = _('Drag&Drop')): 1173 gmGuiHelpers.gm_show_error ( 1174 title = _('Adding files to export area'), 1175 error = _('Cannot add (some of) the following files to the export area:\n%s ') % '\n '.join(real_filenames) 1176 )
1177 #-------------------------------------------------------- 1178 # reget mixin API 1179 # 1180 # remember to call 1181 # self._schedule_data_reget() 1182 # whenever you learn of data changes from database 1183 # listener threads, dispatcher signals etc. 1184 #--------------------------------------------------------
1185 - def _populate_with_data(self):
1186 pat = gmPerson.gmCurrentPatient() 1187 if not pat.connected: 1188 return True 1189 1190 items = pat.export_area.items 1191 self._LCTRL_items.set_string_items ([ 1192 [ i['created_by'], 1193 gmDateTime.pydt_strftime(i['created_when'], '%Y %b %d %H:%M'), 1194 i['description'] 1195 ] for i in items 1196 ]) 1197 self._LCTRL_items.set_column_widths([wx.LIST_AUTOSIZE, wx.LIST_AUTOSIZE, wx.LIST_AUTOSIZE]) 1198 self._LCTRL_items.set_data(items) 1199 1200 self._LCTRL_items.SetFocus() 1201 1202 return True
1203 1204 #============================================================ 1205 from Gnumed.wxGladeWidgets import wxgPrintMgrPluginPnl 1206
1207 -class cPrintMgrPluginPnl(wxgPrintMgrPluginPnl.wxgPrintMgrPluginPnl, gmRegetMixin.cRegetOnPaintMixin):
1208 """Panel holding print jobs. 1209 1210 Used as notebook page.""" 1211
1212 - def __init__(self, *args, **kwargs):
1213 wxgPrintMgrPluginPnl.wxgPrintMgrPluginPnl.__init__(self, *args, **kwargs) 1214 gmRegetMixin.cRegetOnPaintMixin.__init__(self) 1215 self.__init_ui() 1216 self.__register_interests()
1217 #-------------------------------------------------------- 1218 # event handling 1219 #--------------------------------------------------------
1220 - def __register_interests(self):
1221 gmDispatcher.connect(signal = 'pre_patient_unselection', receiver = self._on_pre_patient_unselection) 1222 gmDispatcher.connect(signal = 'post_patient_selection', receiver = self._on_post_patient_selection) 1223 gmDispatcher.connect(signal = 'gm_table_mod', receiver = self._on_table_mod)
1224 #--------------------------------------------------------
1226 self._RBTN_active_patient_only.Enable(False) 1227 self._RBTN_all_patients.Value = True 1228 self._BTN_export_printouts.Enable(False)
1229 #--------------------------------------------------------
1230 - def _on_post_patient_selection(self):
1231 self._RBTN_active_patient_only.Enable(True) 1232 self._BTN_export_printouts.Enable(True)
1233 #--------------------------------------------------------
1234 - def _on_table_mod(self, *args, **kwargs):
1235 if kwargs['table'] != 'clin.export_item': 1236 return 1237 if self._RBTN_all_patients.Value is True: 1238 self._schedule_data_reget() 1239 return 1240 pat = gmPerson.gmCurrentPatient() 1241 if not pat.connected: 1242 return 1243 if kwargs['pk_identity'] != pat.ID: 1244 return 1245 self._schedule_data_reget()
1246 #--------------------------------------------------------
1247 - def _on_all_patients_selected(self, event):
1248 event.Skip() 1249 self._schedule_data_reget()
1250 #--------------------------------------------------------
1251 - def _on_active_patient_only_selected(self, event):
1252 event.Skip() 1253 self._schedule_data_reget()
1254 #--------------------------------------------------------
1255 - def _on_view_button_pressed(self, event):
1256 event.Skip() 1257 printout = self._LCTRL_printouts.get_selected_item_data(only_one = True) 1258 if printout is None: 1259 return 1260 printout.display_via_mime(block = False)
1261 #--------------------------------------------------------
1262 - def _on_print_button_pressed(self, event):
1263 event.Skip() 1264 printouts = self._LCTRL_printouts.get_selected_item_data(only_one = False) 1265 if len(printouts) == 0: 1266 return 1267 1268 files2print = [] 1269 for printout in printouts: 1270 files2print.append(printout.save_to_file()) 1271 1272 if len(files2print) == 0: 1273 return 1274 1275 jobtype = 'print_manager' 1276 printed = gmPrinting.print_files(filenames = files2print, jobtype = jobtype, verbose = _cfg.get(option = 'debug')) 1277 if not printed: 1278 gmGuiHelpers.gm_show_error ( 1279 aMessage = _('Error printing documents.'), 1280 aTitle = _('Printing [%s]') % jobtype 1281 ) 1282 return False 1283 1284 return True
1285 #--------------------------------------------------------
1286 - def _on_export_button_pressed(self, event):
1287 event.Skip() 1288 pat = gmPerson.gmCurrentPatient() 1289 if not pat.connected: 1290 return 1291 printouts = self._LCTRL_printouts.get_selected_item_data(only_one = False) 1292 for printout in printouts: 1293 printout.is_print_job = False
1294 #--------------------------------------------------------
1295 - def _on_delete_button_pressed(self, event):
1296 event.Skip() 1297 printouts = self._LCTRL_printouts.get_selected_item_data(only_one = False) 1298 if len(printouts) == 0: 1299 return 1300 if len(printouts) > 1: 1301 really_delete = gmGuiHelpers.gm_show_question ( 1302 title = _('Deleting document from export area.'), 1303 question = _('Really remove %s selected document(s)\nfrom the patient export area ?') % len(printouts) 1304 ) 1305 if not really_delete: 1306 return 1307 for printout in printouts: 1308 gmExportArea.delete_export_item(pk_export_item = printout['pk_export_item'])
1309 1310 #-------------------------------------------------------- 1311 # internal API 1312 #--------------------------------------------------------
1313 - def __init_ui(self):
1314 self._BTN_export_printouts.Enable(False)
1315 #-------------------------------------------------------- 1316 # reget mixin API 1317 #--------------------------------------------------------
1318 - def _populate_with_data(self):
1319 if self._RBTN_all_patients.Value is True: 1320 columns = [_('Patient'), _('Provider'), _('Description')] 1321 printouts = gmExportArea.get_print_jobs(order_by = 'pk_identity, description') 1322 items = [[ 1323 '%s, %s (%s)' % ( 1324 p['lastnames'], 1325 p['firstnames'], 1326 p['gender'] 1327 ), 1328 p['created_by'], 1329 p['description'] 1330 ] for p in printouts ] 1331 else: 1332 pat = gmPerson.gmCurrentPatient() 1333 if pat.connected: 1334 columns = [_('Provider'), _('Created'), _('Description')] 1335 printouts = pat.export_area.get_printouts(order_by = 'created_when, description') 1336 items = [[ 1337 p['created_by'], 1338 gmDateTime.pydt_strftime(p['created_when'], '%Y %b %d %H:%M'), 1339 p['description'] 1340 ] for p in printouts ] 1341 else: 1342 columns = [_('Patient'), _('Provider'), _('Description')] 1343 printouts = gmExportArea.get_print_jobs(order_by = 'pk_identity, description') 1344 items = [[ 1345 '%s, %s (%s)' % ( 1346 p['lastnames'], 1347 p['firstnames'], 1348 p['gender'] 1349 ), 1350 p['created_by'], 1351 p['description'] 1352 ] for p in printouts ] 1353 self._LCTRL_printouts.set_columns(columns) 1354 self._LCTRL_printouts.set_string_items(items) 1355 self._LCTRL_printouts.set_column_widths([wx.LIST_AUTOSIZE, wx.LIST_AUTOSIZE, wx.LIST_AUTOSIZE]) 1356 self._LCTRL_printouts.set_data(printouts) 1357 self._LCTRL_printouts.SetFocus() 1358 return True
1359