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   
 29  from Gnumed.business import gmPerson 
 30  from Gnumed.business import gmExportArea 
 31   
 32  from Gnumed.wxpython import gmRegetMixin 
 33  from Gnumed.wxpython import gmGuiHelpers 
 34  from Gnumed.wxpython import gmDocumentWidgets 
 35   
 36   
 37  _log = logging.getLogger('gm.ui') 
 38   
 39   
 40  #============================================================ 
 41  from Gnumed.wxGladeWidgets import wxgCreatePatientMediaDlg 
 42   
43 -class cCreatePatientMediaDlg(wxgCreatePatientMediaDlg.wxgCreatePatientMediaDlg):
44
45 - def __init__(self, *args, **kwargs):
46 self.__burn2cd = False 47 try: 48 self.__burn2cd = kwargs['burn2cd'] 49 del kwargs['burn2cd'] 50 except KeyError: 51 pass 52 if self.__burn2cd: 53 _log.debug('planning to burn export area items to CD/DVD') 54 else: 55 _log.debug('planning to save export area items to disk') 56 self.__patient = kwargs['patient'] 57 del kwargs['patient'] 58 self.__item_count = kwargs['item_count'] 59 del kwargs['item_count'] 60 wxgCreatePatientMediaDlg.wxgCreatePatientMediaDlg.__init__(self, *args, **kwargs) 61 62 self.__init_ui()
63 64 #-------------------------------------------------------- 65 # event handling 66 #--------------------------------------------------------
67 - def _on_select_directory_button_pressed(self, event):
68 event.Skip() 69 if self.__burn2cd: 70 msg = _('Select a directory for inclusion into the patient CD / DVD.') 71 else: 72 msg = _('Select a directory in which to create the patient media.') 73 def_path = self._LBL_directory.Label 74 dlg = wx.DirDialog ( 75 self, 76 message = msg, 77 defaultPath = def_path 78 ) 79 choice = dlg.ShowModal() 80 path = dlg.GetPath() 81 dlg.Destroy() 82 if choice != wx.ID_OK: 83 return 84 self._LBL_directory.Label = path 85 self.__refresh_dir_is_empty() 86 self.__refresh_include_or_remove_existing_data()
87 88 #--------------------------------------------------------
89 - def _on_use_subdirectory_changed(self, event):
90 event.Skip() 91 92 self.__refresh_include_or_remove_existing_data() 93 94 if self._CHBOX_use_subdirectory.IsChecked(): 95 self._LBL_subdirectory.Label = '%s/%s-###' % ( 96 self._LBL_directory.Label, 97 self.__patient.subdir_name 98 ) 99 return 100 101 self._LBL_subdirectory.Label = ''
102 103 #--------------------------------------------------------
104 - def _on_save_button_pressed(self, event):
105 event.Skip() 106 107 if self.__burn2cd: 108 self.EndModal(wx.ID_SAVE) 109 return 110 111 if self._CHBOX_use_subdirectory.IsChecked() is True: 112 self.EndModal(wx.ID_SAVE) 113 return 114 115 path = self._LBL_directory.Label 116 117 if gmTools.dir_is_empty(path) is True: 118 self.EndModal(wx.ID_SAVE) 119 return 120 121 if self._RBTN_remove_data.Value is True: 122 really_remove_existing_data = gmGuiHelpers.gm_show_question ( 123 title = _('Creating patient media'), 124 question = _( 125 'Really delete any existing data under\n' 126 '\n' 127 ' [%s]\n' 128 '\n' 129 'from disk ?\n' 130 '\n' 131 '(this operation is generally not reversible)' 132 ) % path 133 ) 134 if really_remove_existing_data is False: 135 return 136 137 self.EndModal(wx.ID_SAVE)
138 139 #--------------------------------------------------------
140 - def _on_browse_directory_button_pressed(self, event):
141 event.Skip() 142 path = self._LBL_directory.Label.strip() 143 if path == '': 144 return 145 gmMimeLib.call_viewer_on_file(path, block = False)
146 147 #-------------------------------------------------------- 148 # internal API 149 #--------------------------------------------------------
150 - def __init_ui(self):
151 152 self._LBL_dir_is_empty.Label = '' 153 self._LBL_subdirectory.Label = '' 154 155 if self.__burn2cd: 156 self._LBL_existing_data.Hide() 157 self._BTN_browse_directory.Disable() 158 self._RBTN_include_data.Hide() 159 self._RBTN_remove_data.Hide() 160 self._CHBOX_include_directory.Show() 161 self._CHBOX_use_subdirectory.Hide() 162 self._LBL_subdirectory.Hide() 163 self._CHBOX_generate_metadata.Hide() 164 lines = [ 165 _('Preparing patient media for burning onto CD / DVD'), 166 '' 167 ] 168 found, external_cmd = gmShellAPI.detect_external_binary('gm-burn_doc') 169 if not found: 170 lines.append(_('Script <gm-burn_doc(.bat)> not found.')) 171 lines.append('') 172 lines.append(_('Cannot attempt to burn patient media onto CD/DVD.')) 173 self._BTN_save.Disable() 174 else: 175 lines.append(_('Patient: %s') % self.__patient['description_gender']) 176 lines.append('') 177 lines.append(_('Number of items to export onto CD/DVD: %s\n') % self.__item_count) 178 self._LBL_header.Label = '\n'.join(lines) 179 return 180 181 lines = [ 182 _('Preparing patient media for saving to disk (USB, harddrive).'), 183 '', 184 _('Patient: %s') % self.__patient['description_gender'], 185 '', 186 _('Number of items to export to disk: %s\n') % self.__item_count 187 ] 188 self._LBL_header.Label = '\n'.join(lines) 189 self._LBL_directory.Label = os.path.join(gmTools.gmPaths().home_dir, 'gnumed') 190 self.__refresh_dir_is_empty()
191 192 #--------------------------------------------------------
193 - def __refresh_dir_is_empty(self):
194 path = self._LBL_directory.Label.strip() 195 if path == '': 196 self._LBL_dir_is_empty.Label = '' 197 self._BTN_browse_directory.Disable() 198 self._CHBOX_include_directory.Disable() 199 return 200 is_empty = gmTools.dir_is_empty(directory = path) 201 if is_empty is None: 202 self._LBL_dir_is_empty.Label = _('(cannot check directory)') 203 self._BTN_browse_directory.Disable() 204 self._CHBOX_include_directory.Disable() 205 return 206 if is_empty is True: 207 self._LBL_dir_is_empty.Label = _('(directory appears empty)') 208 self._BTN_browse_directory.Disable() 209 self._CHBOX_include_directory.Disable() 210 return 211 212 msg = _('directory already contains data') 213 self._BTN_browse_directory.Enable() 214 self._CHBOX_include_directory.Enable() 215 216 if os.path.isfile(os.path.join(path, 'DICOMDIR')): 217 msg = _('%s\n- DICOM data') % msg 218 219 if os.path.isdir(os.path.join(path, 'documents')): 220 if len(os.listdir(os.path.join(path, 'documents'))) > 0: 221 msg = _('%s\n- additional documents') % msg 222 223 self._LBL_dir_is_empty.Label = msg 224 self.Layout()
225 226 #--------------------------------------------------------
228 if self._CHBOX_use_subdirectory.IsChecked(): 229 self._RBTN_include_data.Disable() 230 self._RBTN_remove_data.Disable() 231 return 232 233 path = self._LBL_directory.Label.strip() 234 if path == '': 235 self._RBTN_include_data.Disable() 236 self._RBTN_remove_data.Disable() 237 return 238 239 is_empty = gmTools.dir_is_empty(directory = path) 240 if is_empty is None: 241 self._RBTN_include_data.Disable() 242 self._RBTN_remove_data.Disable() 243 return 244 245 if is_empty is True: 246 self._RBTN_include_data.Disable() 247 self._RBTN_remove_data.Disable() 248 return 249 250 self._RBTN_include_data.Enable() 251 self._RBTN_remove_data.Enable()
252 253 #============================================================ 254 from Gnumed.wxGladeWidgets import wxgExportAreaPluginPnl 255
256 -class cExportAreaPluginPnl(wxgExportAreaPluginPnl.wxgExportAreaPluginPnl, gmRegetMixin.cRegetOnPaintMixin):
257 """Panel holding a number of items for further processing. 258 259 Acts on the current patient. 260 261 Used as notebook page."""
262 - def __init__(self, *args, **kwargs):
263 wxgExportAreaPluginPnl.wxgExportAreaPluginPnl.__init__(self, *args, **kwargs) 264 gmRegetMixin.cRegetOnPaintMixin.__init__(self) 265 self.__init_ui() 266 self.__register_interests()
267 268 #-------------------------------------------------------- 269 # event handling 270 #--------------------------------------------------------
271 - def __register_interests(self):
272 gmDispatcher.connect(signal = 'pre_patient_unselection', receiver = self._on_pre_patient_unselection) 273 # gmDispatcher.connect(signal = u'post_patient_selection', receiver = self._schedule_data_reget) 274 gmDispatcher.connect(signal = 'gm_table_mod', receiver = self._on_table_mod)
275 276 #--------------------------------------------------------
278 self._LCTRL_items.set_string_items([])
279 280 #--------------------------------------------------------
281 - def _on_table_mod(self, *args, **kwargs):
282 if kwargs['table'] != 'clin.export_item': 283 return 284 pat = gmPerson.gmCurrentPatient() 285 if not pat.connected: 286 return 287 if kwargs['pk_identity'] != pat.ID: 288 return 289 self._schedule_data_reget()
290 291 #--------------------------------------------------------
292 - def _on_list_item_selected(self, event):
293 event.Skip()
294 295 #--------------------------------------------------------
296 - def _on_show_item_button_pressed(self, event):
297 event.Skip() 298 item = self._LCTRL_items.get_selected_item_data(only_one = True) 299 if item is None: 300 return 301 item.display_via_mime(block = False)
302 303 #--------------------------------------------------------
304 - def _on_add_items_button_pressed(self, event):
305 event.Skip() 306 dlg = wx.FileDialog ( 307 parent = self, 308 message = _("Select files to add to the export area"), 309 defaultDir = os.path.expanduser(os.path.join('~', 'gnumed')), 310 style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST | wx.FD_MULTIPLE | wx.FD_PREVIEW 311 ) 312 choice = dlg.ShowModal() 313 fnames = dlg.GetPaths() 314 dlg.Destroy() 315 if choice != wx.ID_OK: 316 return 317 if not gmPerson.gmCurrentPatient().export_area.add_files(fnames): 318 gmGuiHelpers.gm_show_error ( 319 title = _('Adding files to export area'), 320 error = _('Cannot add (some of) the following files to the export area:\n%s ') % '\n '.join(fnames) 321 )
322 323 #--------------------------------------------------------
324 - def _on_add_from_archive_button_pressed(self, event):
325 event.Skip() 326 selected_docs = gmDocumentWidgets.manage_documents ( 327 parent = self, 328 msg = _('Select the documents to be put into the export area:'), 329 single_selection = False 330 ) 331 if selected_docs is None: 332 return 333 gmPerson.gmCurrentPatient().export_area.add_documents(documents = selected_docs)
334 335 #--------------------------------------------------------
336 - def _on_clipboard_items_button_pressed(self, event):
337 event.Skip() 338 clip = gmGuiHelpers.clipboard2file(check_for_filename = True) 339 if clip is None: 340 return 341 if clip is False: 342 return 343 if not gmPerson.gmCurrentPatient().export_area.add_file(filename = clip, hint = _('clipboard')): 344 gmGuiHelpers.gm_show_error ( 345 title = _('Loading clipboard item (saved to file) into export area'), 346 error = _('Cannot add the following clip to the export area:\n%s ') % clip 347 )
348 349 #--------------------------------------------------------
350 - def _on_scan_items_button_pressed(self, event):
351 event.Skip() 352 scans = gmDocumentWidgets.acquire_images_from_capture_device(calling_window = self) 353 if scans is None: 354 return 355 356 if not gmPerson.gmCurrentPatient().export_area.add_files(scans, _('scan')): 357 gmGuiHelpers.gm_show_error ( 358 title = _('Scanning files into export area'), 359 error = _('Cannot add (some of) the following scans to the export area:\n%s ') % '\n '.join(fnames) 360 )
361 362 #--------------------------------------------------------
363 - def _on_remove_items_button_pressed(self, event):
364 event.Skip() 365 items = self._LCTRL_items.get_selected_item_data(only_one = False) 366 if len(items) == 0: 367 return 368 really_delete = gmGuiHelpers.gm_show_question ( 369 title = _('Deleting document from export area.'), 370 question = _('Really remove %s selected document(s)\nfrom the patient export area ?') % len(items) 371 ) 372 if not really_delete: 373 return 374 for item in items: 375 gmExportArea.delete_export_item(pk_export_item = item['pk_export_item'])
376 377 #--------------------------------------------------------
378 - def _on_print_items_button_pressed(self, event):
379 event.Skip() 380 items = self._LCTRL_items.get_selected_item_data(only_one = False) 381 if len(items) == 0: 382 return 383 384 files2print = [] 385 for item in items: 386 files2print.append(item.save_to_file()) 387 388 if len(files2print) == 0: 389 return 390 391 jobtype = 'export_area' 392 printed = gmPrinting.print_files(filenames = files2print, jobtype = jobtype) 393 if not printed: 394 gmGuiHelpers.gm_show_error ( 395 aMessage = _('Error printing documents.'), 396 aTitle = _('Printing [%s]') % jobtype 397 ) 398 return False 399 400 self.save_soap_note(soap = _('Printed:\n - %s') % '\n - '.join([ i['description'] for i in items ])) 401 return True
402 403 #--------------------------------------------------------
404 - def _on_remote_print_button_pressed(self, event):
405 event.Skip() 406 items = self._LCTRL_items.get_selected_item_data(only_one = False) 407 for item in items: 408 item.is_print_job = True
409 410 #--------------------------------------------------------
411 - def _on_save_items_button_pressed(self, event):
412 event.Skip() 413 414 items = self._LCTRL_items.get_selected_item_data(only_one = False) 415 if len(items) == 0: 416 items = self._LCTRL_items.get_item_data() 417 418 if len(items) == 0: 419 return 420 421 pat = gmPerson.gmCurrentPatient() 422 dlg = cCreatePatientMediaDlg (self, -1, burn2cd = False, patient = pat, item_count = len(items)) 423 _log.debug("calling dlg.ShowModal()") 424 choice = dlg.ShowModal() 425 _log.debug("after returning from dlg.ShowModal()") 426 if choice != wx.ID_SAVE: 427 dlg.Destroy() 428 return 429 430 use_subdir = dlg._CHBOX_use_subdirectory.IsChecked() 431 path = dlg._LBL_directory.Label.strip() 432 remove_existing_data = dlg._RBTN_remove_data.Value is True 433 generate_metadata = dlg._CHBOX_generate_metadata.IsChecked() 434 dlg.Destroy() 435 if use_subdir: 436 path = gmTools.mk_sandbox_dir ( 437 prefix = '%s-' % pat.subdir_name, 438 base_dir = path 439 ) 440 else: 441 if remove_existing_data is True: 442 if gmTools.rm_dir_content(path) is False: 443 gmGuiHelpers.gm_show_error ( 444 title = _('Creating patient media'), 445 error = _('Cannot remove content from\n [%s]') % path 446 ) 447 return False 448 449 exp_area = pat.export_area 450 if generate_metadata: 451 export_dir = exp_area.export(base_dir = path, items = items) 452 else: 453 export_dir = exp_area.dump_items_to_disk(base_dir = path, items = items) 454 455 self.save_soap_note(soap = _('Saved to [%s]:\n - %s') % ( 456 export_dir, 457 '\n - '.join([ i['description'] for i in items ]) 458 )) 459 460 msg = _('Saved documents into directory:\n\n %s') % export_dir 461 browse_index = gmGuiHelpers.gm_show_question ( 462 title = _('Creating patient media'), 463 question = msg + '\n\n' + _('Browse patient data pack ?'), 464 cancel_button = False 465 ) 466 if browse_index: 467 if generate_metadata: 468 gmNetworkTools.open_url_in_browser(url = 'file://%s' % os.path.join(export_dir, 'index.html')) 469 else: 470 gmMimeLib.call_viewer_on_file(export_dir, block = False) 471 472 return True
473 474 #--------------------------------------------------------
475 - def _on_burn_items_button_pressed(self, event):
476 event.Skip() 477 478 # anything to do ? 479 found, external_cmd = gmShellAPI.detect_external_binary('gm-burn_doc') 480 if not found: 481 return 482 items = self._LCTRL_items.get_selected_item_data(only_one = False) 483 if len(items) == 0: 484 items = self._LCTRL_items.get_item_data() 485 if len(items) == 0: 486 return 487 488 pat = gmPerson.gmCurrentPatient() 489 dlg = cCreatePatientMediaDlg(self, -1, burn2cd = True, patient = pat, item_count = len(items)) 490 choice = dlg.ShowModal() 491 if choice != wx.ID_SAVE: 492 return 493 path2include = dlg._LBL_directory.Label.strip() 494 include_selected_dir = dlg._CHBOX_include_directory.IsChecked() 495 dlg.Destroy() 496 497 # do the export 498 base_dir = None 499 if include_selected_dir: 500 if gmTools.dir_is_empty(path2include) is False: 501 base_dir = gmTools.get_unique_filename(suffix = '.iso') 502 try: 503 shutil.copytree(path2include, base_dir) 504 except shutil.Error: 505 _log.exception('cannot copy include directory [%s] -> [%s]', path2include, base_dir) 506 return 507 508 export_dir = gmPerson.gmCurrentPatient().export_area.export(base_dir = base_dir, items = items, with_metadata = True) 509 if export_dir is None: 510 return 511 512 # burn onto media 513 cmd = '%s %s' % (external_cmd, export_dir) 514 if os.name == 'nt': 515 blocking = True 516 else: 517 blocking = False 518 success = gmShellAPI.run_command_in_shell ( 519 command = cmd, 520 blocking = blocking 521 ) 522 if not success: 523 gmGuiHelpers.gm_show_error ( 524 aMessage = _('Error burning documents to CD/DVD.'), 525 aTitle = _('Burning documents') 526 ) 527 return 528 529 self.save_soap_note(soap = _('Burned onto CD/DVD:\n - %s') % '\n - '.join([ i['description'] for i in items ])) 530 531 browse_index = gmGuiHelpers.gm_show_question ( 532 title = _('Creating patient media'), 533 question = _('Browse patient data pack ?'), 534 cancel_button = False 535 ) 536 if browse_index: 537 gmNetworkTools.open_url_in_browser(url = 'file://%s' % os.path.join(export_dir, 'index.html')) 538 539 return True
540 541 #--------------------------------------------------------
542 - def _on_archive_items_button_pressed(self, event):
543 print("Event handler '_on_archive_items_button_pressed' not implemented!") 544 event.Skip()
545 546 #--------------------------------------------------------
547 - def _on_mail_items_button_pressed(self, event):
548 event.Skip() 549 550 items = self._LCTRL_items.get_selected_item_data(only_one = False) 551 if len(items) == 0: 552 return True 553 554 found, external_cmd = gmShellAPI.detect_external_binary('gm-mail_doc') 555 if not found: 556 return False 557 558 files2mail = [] 559 for item in items: 560 files2mail.append(item.save_to_file()) 561 562 cmd = '%s %s' % (external_cmd, ' '.join(files2mail)) 563 if os.name == 'nt': 564 blocking = True 565 else: 566 blocking = False 567 success = gmShellAPI.run_command_in_shell ( 568 command = cmd, 569 blocking = blocking 570 ) 571 if not success: 572 gmGuiHelpers.gm_show_error ( 573 aMessage = _('Error mailing documents.'), 574 aTitle = _('Mailing documents') 575 ) 576 return False 577 578 self.save_soap_note(soap = _('Mailed:\n - %s') % '\n - '.join([ i['description'] for i in items ])) 579 return True
580 581 #--------------------------------------------------------
582 - def _on_fax_items_button_pressed(self, event):
583 event.Skip() 584 585 items = self._LCTRL_items.get_selected_item_data(only_one = False) 586 if len(items) == 0: 587 return 588 589 found, external_cmd = gmShellAPI.detect_external_binary('gm-fax_doc') 590 if not found: 591 return False 592 593 files2fax = [] 594 for item in items: 595 files2fax.append(item.save_to_file()) 596 597 fax_number = wx.GetTextFromUser ( 598 _('Please enter the fax number here !\n\n' 599 'It can be left empty if the external\n' 600 'fax software knows how to get the number.'), 601 caption = _('Faxing documents'), 602 parent = self, 603 centre = True 604 ) 605 606 cmd = '%s "%s" %s' % (external_cmd, fax_number, ' '.join(files2fax)) 607 if os.name == 'nt': 608 blocking = True 609 else: 610 blocking = False 611 success = gmShellAPI.run_command_in_shell ( 612 command = cmd, 613 blocking = blocking 614 ) 615 if not success: 616 gmGuiHelpers.gm_show_error ( 617 aMessage = _('Error faxing documents to\n\n %s') % fax_number, 618 aTitle = _('Faxing documents') 619 ) 620 return False 621 622 self.save_soap_note(soap = _('Faxed to [%s]:\n - %s') % ( 623 fax_number, 624 '\n - '.join([ i['description'] for i in items ]) 625 )) 626 return True
627 628 #--------------------------------------------------------
629 - def repopulate_ui(self):
630 self._populate_with_data()
631 632 #-------------------------------------------------------- 633 # internal API 634 #--------------------------------------------------------
635 - def __init_ui(self):
636 self._LCTRL_items.set_columns([_('By'), _('When'), _('Description')]) 637 638 self._BTN_archive_items.Disable() 639 640 # there's no GetToolTipText() in wx2.8 641 self.__mail_script_exists, path = gmShellAPI.detect_external_binary(binary = r'gm-mail_doc') 642 if not self.__mail_script_exists: 643 self._BTN_mail_items.Disable() 644 tt = self._BTN_mail_items.GetToolTipText() + '\n\n' + _('<gm-mail_doc(.bat) not found>') 645 self._BTN_mail_items.SetToolTip(tt) 646 647 self.__fax_script_exists, path = gmShellAPI.detect_external_binary(binary = r'gm-fax_doc') 648 if not self.__fax_script_exists: 649 self._BTN_fax_items.Disable() 650 tt = self._BTN_fax_items.GetToolTipText() + '\n\n' + _('<gm-fax_doc(.bat) not found>') 651 self._BTN_fax_items.SetToolTip(tt) 652 653 self.__burn_script_exists, path = gmShellAPI.detect_external_binary(binary = r'gm-burn_doc') 654 if not self.__burn_script_exists: 655 self._BTN_burn_items.Disable() 656 tt = self._BTN_burn_items.GetToolTipText() + '\n\n' + _('<gm-burn_doc(.bat) not found>') 657 self._BTN_burn_items.SetToolTip(tt) 658 659 # make me and listctrl file drop targets 660 dt = gmGuiHelpers.cFileDropTarget(target = self) 661 self.SetDropTarget(dt) 662 dt = gmGuiHelpers.cFileDropTarget(on_drop_callback = self._drop_target_consume_filenames) 663 self._LCTRL_items.SetDropTarget(dt)
664 665 #--------------------------------------------------------
666 - def save_soap_note(self, soap=None):
667 if soap.strip() == '': 668 return 669 emr = gmPerson.gmCurrentPatient().emr 670 epi = emr.add_episode(episode_name = 'administrative', is_open = False) 671 emr.add_clin_narrative ( 672 soap_cat = None, 673 note = soap, 674 episode = epi 675 )
676 677 #-------------------------------------------------------- 678 # file drop target API 679 #--------------------------------------------------------
680 - def _drop_target_consume_filenames(self, filenames):
681 pat = gmPerson.gmCurrentPatient() 682 if not pat.connected: 683 gmDispatcher.send(signal = 'statustext', msg = _('Cannot accept new documents. No active patient.')) 684 return 685 686 # dive into folders dropped onto us and extract files (one level deep only) 687 real_filenames = [] 688 for pathname in filenames: 689 try: 690 files = os.listdir(pathname) 691 gmDispatcher.send(signal='statustext', msg=_('Extracting files from folder [%s] ...') % pathname) 692 for file in files: 693 fullname = os.path.join(pathname, file) 694 if not os.path.isfile(fullname): 695 continue 696 real_filenames.append(fullname) 697 except OSError: 698 real_filenames.append(pathname) 699 700 if not pat.export_area.add_files(real_filenames, hint = _('Drag&Drop')): 701 gmGuiHelpers.gm_show_error ( 702 title = _('Adding files to export area'), 703 error = _('Cannot add (some of) the following files to the export area:\n%s ') % '\n '.join(real_filenames) 704 )
705 #-------------------------------------------------------- 706 # reget mixin API 707 # 708 # remember to call 709 # self._schedule_data_reget() 710 # whenever you learn of data changes from database 711 # listener threads, dispatcher signals etc. 712 #--------------------------------------------------------
713 - def _populate_with_data(self):
714 pat = gmPerson.gmCurrentPatient() 715 if not pat.connected: 716 return True 717 718 items = pat.export_area.items 719 self._LCTRL_items.set_string_items ([ 720 [ i['created_by'], 721 gmDateTime.pydt_strftime(i['created_when'], '%Y %b %d %H:%M'), 722 i['description'] 723 ] for i in items 724 ]) 725 self._LCTRL_items.set_column_widths([wx.LIST_AUTOSIZE, wx.LIST_AUTOSIZE, wx.LIST_AUTOSIZE]) 726 self._LCTRL_items.set_data(items) 727 728 self._LCTRL_items.SetFocus() 729 730 return True
731 732 #============================================================ 733 from Gnumed.wxGladeWidgets import wxgPrintMgrPluginPnl 734
735 -class cPrintMgrPluginPnl(wxgPrintMgrPluginPnl.wxgPrintMgrPluginPnl, gmRegetMixin.cRegetOnPaintMixin):
736 """Panel holding print jobs. 737 738 Used as notebook page.""" 739
740 - def __init__(self, *args, **kwargs):
741 wxgPrintMgrPluginPnl.wxgPrintMgrPluginPnl.__init__(self, *args, **kwargs) 742 gmRegetMixin.cRegetOnPaintMixin.__init__(self) 743 self.__init_ui() 744 self.__register_interests()
745 #-------------------------------------------------------- 746 # event handling 747 #--------------------------------------------------------
748 - def __register_interests(self):
749 gmDispatcher.connect(signal = 'pre_patient_unselection', receiver = self._on_pre_patient_unselection) 750 gmDispatcher.connect(signal = 'post_patient_selection', receiver = self._on_post_patient_selection) 751 gmDispatcher.connect(signal = 'gm_table_mod', receiver = self._on_table_mod)
752 #--------------------------------------------------------
754 self._RBTN_active_patient_only.Enable(False) 755 self._RBTN_all_patients.Value = True 756 self._BTN_export_printouts.Enable(False)
757 #--------------------------------------------------------
758 - def _on_post_patient_selection(self):
759 self._RBTN_active_patient_only.Enable(True) 760 self._BTN_export_printouts.Enable(True)
761 #--------------------------------------------------------
762 - def _on_table_mod(self, *args, **kwargs):
763 if kwargs['table'] != 'clin.export_item': 764 return 765 if self._RBTN_all_patients.Value is True: 766 self._schedule_data_reget() 767 return 768 pat = gmPerson.gmCurrentPatient() 769 if not pat.connected: 770 return 771 if kwargs['pk_identity'] != pat.ID: 772 return 773 self._schedule_data_reget()
774 #--------------------------------------------------------
775 - def _on_all_patients_selected(self, event):
776 event.Skip() 777 self._schedule_data_reget()
778 #--------------------------------------------------------
779 - def _on_active_patient_only_selected(self, event):
780 event.Skip() 781 self._schedule_data_reget()
782 #--------------------------------------------------------
783 - def _on_view_button_pressed(self, event):
784 event.Skip() 785 printout = self._LCTRL_printouts.get_selected_item_data(only_one = True) 786 if printout is None: 787 return 788 printout.display_via_mime(block = False)
789 #--------------------------------------------------------
790 - def _on_print_button_pressed(self, event):
791 event.Skip() 792 printouts = self._LCTRL_printouts.get_selected_item_data(only_one = False) 793 if len(printouts) == 0: 794 return 795 796 files2print = [] 797 for printout in printouts: 798 files2print.append(printout.save_to_file()) 799 800 if len(files2print) == 0: 801 return 802 803 jobtype = 'print_manager' 804 printed = gmPrinting.print_files(filenames = files2print, jobtype = jobtype) 805 if not printed: 806 gmGuiHelpers.gm_show_error ( 807 aMessage = _('Error printing documents.'), 808 aTitle = _('Printing [%s]') % jobtype 809 ) 810 return False 811 812 return True
813 #--------------------------------------------------------
814 - def _on_export_button_pressed(self, event):
815 event.Skip() 816 pat = gmPerson.gmCurrentPatient() 817 if not pat.connected: 818 return 819 printouts = self._LCTRL_printouts.get_selected_item_data(only_one = False) 820 for printout in printouts: 821 printout.is_print_job = False
822 #--------------------------------------------------------
823 - def _on_delete_button_pressed(self, event):
824 event.Skip() 825 printouts = self._LCTRL_printouts.get_selected_item_data(only_one = False) 826 if len(printouts) == 0: 827 return 828 if len(printouts) > 1: 829 really_delete = gmGuiHelpers.gm_show_question ( 830 title = _('Deleting document from export area.'), 831 question = _('Really remove %s selected document(s)\nfrom the patient export area ?') % len(printouts) 832 ) 833 if not really_delete: 834 return 835 for printout in printouts: 836 gmExportArea.delete_export_item(pk_export_item = printout['pk_export_item'])
837 #-------------------------------------------------------- 838 # internal API 839 #--------------------------------------------------------
840 - def __init_ui(self):
841 self._BTN_export_printouts.Enable(False)
842 #-------------------------------------------------------- 843 # reget mixin API 844 #--------------------------------------------------------
845 - def _populate_with_data(self):
846 if self._RBTN_all_patients.Value is True: 847 columns = [_('Patient'), _('Provider'), _('Description')] 848 printouts = gmExportArea.get_print_jobs(order_by = 'pk_identity, description') 849 items = [[ 850 '%s, %s (%s)' % ( 851 p['lastnames'], 852 p['firstnames'], 853 p['gender'] 854 ), 855 p['created_by'], 856 p['description'] 857 ] for p in printouts ] 858 else: 859 pat = gmPerson.gmCurrentPatient() 860 if pat.connected: 861 columns = [_('Provider'), _('Created'), _('Description')] 862 printouts = pat.export_area.get_printouts(order_by = 'created_when, description') 863 items = [[ 864 p['created_by'], 865 gmDateTime.pydt_strftime(p['created_when'], '%Y %b %d %H:%M'), 866 p['description'] 867 ] for p in printouts ] 868 else: 869 columns = [_('Patient'), _('Provider'), _('Description')] 870 printouts = gmExportArea.get_print_jobs(order_by = 'pk_identity, description') 871 items = [[ 872 '%s, %s (%s)' % ( 873 p['lastnames'], 874 p['firstnames'], 875 p['gender'] 876 ), 877 p['created_by'], 878 p['description'] 879 ] for p in printouts ] 880 self._LCTRL_printouts.set_columns(columns) 881 self._LCTRL_printouts.set_string_items(items) 882 self._LCTRL_printouts.set_column_widths([wx.LIST_AUTOSIZE, wx.LIST_AUTOSIZE, wx.LIST_AUTOSIZE]) 883 self._LCTRL_printouts.set_data(printouts) 884 self._LCTRL_printouts.SetFocus() 885 return True
886