import os
import sys
import re
import logging
import traceback
from xhtml2pdf import pisa
from PyQt5 import QtWidgets, QtCore
from PyQt5 import QtPrintSupport
import sas.qtgui.Utilities.GuiUtils as GuiUtils
import sas.qtgui.Utilities.ObjectLibrary as ObjectLibrary
from sas.qtgui.Utilities.UI.ReportDialogUI import Ui_ReportDialogUI
class ReportDialog(QtWidgets.QDialog, Ui_ReportDialogUI):
"""
Class for stateless grid-like printout of model parameters for mutiple models
"""
def __init__(self, parent=None, report_list=None):
super(ReportDialog, self).__init__(parent._parent)
self.setupUi(self)
# disable the context help icon
self.setWindowFlags(self.windowFlags() & ~QtCore.Qt.WindowContextHelpButtonHint)
assert isinstance(report_list, list)
assert len(report_list) == 3
self.data_html, self.data_txt, self.data_images = report_list
#self.save_location = None
#if 'ReportDialog_directory' in ObjectLibrary.listObjects():
self.save_location = ObjectLibrary.getObject('ReportDialog_directory')
# Fill in the table from input data
self.setupDialog(self.data_html)
# Command buttons
self.cmdPrint.clicked.connect(self.onPrint)
self.cmdSave.clicked.connect(self.onSave)
def setupDialog(self, output=None):
"""
Display the HTML content in the browser.
"""
if output is not None:
self.txtBrowser.setHtml(output)
def onPrint(self):
"""
Display the print dialog and send the report to printer
"""
# Define the printer
printer = QtPrintSupport.QPrinter()
# Display the print dialog
dialog = QtPrintSupport.QPrintDialog(printer)
dialog.setModal(True)
dialog.setWindowTitle("Print")
if dialog.exec_() != QtWidgets.QDialog.Accepted:
return
document = self.txtBrowser.document()
try:
# pylint chokes on this line with syntax-error
# pylint: disable=syntax-error doesn't seem to help
document.print(printer)
except Exception as ex:
# Printing can return various exceptions, let's catch them all
logging.error("Print report failed with: " + str(ex))
def onSave(self):
"""
Display the Save As... prompt and save the report if instructed so
"""
# Choose user's home directory
if self.save_location is None:
location = os.path.expanduser('~')
else:
location = self.save_location
# Use a sensible filename default
default_name = os.path.join(location, 'fit_report.pdf')
kwargs = {
'parent' : self,
'caption' : 'Save Report',
# don't use 'directory' in order to remember the previous user choice
'directory': default_name,
'filter' : 'PDF file (*.pdf);;HTML file (*.html);;Text file (*.txt)',
'options' : QtWidgets.QFileDialog.DontUseNativeDialog}
# Query user for filename.
filename_tuple = QtWidgets.QFileDialog.getSaveFileName(**kwargs)
filename = filename_tuple[0]
if not filename:
return
extension = filename_tuple[1]
self.save_location = os.path.dirname(filename)
# lifetime of this widget is short - keep the reference elsewhere
ObjectLibrary.addObject('ReportDialog_directory', self.save_location)
try:
# extract extension from filter
# e.g. "PDF file (*.pdf)" -> ".pdf"
ext = extension[extension.find("(")+2:extension.find(")")]
except IndexError as ex:
# (ext) not found...
logging.error("Error while saving report. " + str(ex))
return
basename, extension = os.path.splitext(filename)
if not extension:
filename = '.'.join((filename, ext))
# Create files with charts
pictures = []
if self.data_images is not None:
pictures = self.getPictures(basename)
# self.data_html contains all images at the end of the report, in base64 form;
# replace them all with their saved on-disk filenames
cleanr = re.compile('