X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/8b9a4190f70909de9568f45389e7aa3ecbc66b8a..eb3efe0d4b8a0964cd0504a69c0e9540c18e390c:/wxPython/wx/lib/printout.py?ds=sidebyside diff --git a/wxPython/wx/lib/printout.py b/wxPython/wx/lib/printout.py index 1e2825a1da..0ced233037 100644 --- a/wxPython/wx/lib/printout.py +++ b/wxPython/wx/lib/printout.py @@ -1,8 +1,1149 @@ +#---------------------------------------------------------------------------- +# Name: printout.py +# Purpose: preview and printing class -> table/grid printing +# +# Author: Lorne White (email: lorne.white@telusplanet.net) +# +# Created: +# Version 0.75 +# Date: May 15, 2002 +# Licence: wxWindows license +#---------------------------------------------------------------------------- +# Release Notes -"""Renamer stub: provides a way to drop the wx prefix from wxPython objects.""" +# fixed bug for string wider than print region +# add index to data list after parsing total pages for paging +#---------------------------------------------------------------------------- +# 12/10/2003 - Jeff Grimmett (grimmtooth@softhome.net) +# o 2.5 compatability update. +#---------------------------------------------------------------------------- +# 11/23/2004 - Vernon Cole (wnvcole@peppermillcas.com) +# o Generalize for non-2-dimensional sequences and non-text data +# (can use as a simple text printer by supplying a list of strings.) +# o Add a small _main_ for self test + +import copy +import types +import wx -from wx import _rename -from wxPython.lib import printout -_rename(globals(), printout.__dict__, modulename='lib.printout') -del printout -del _rename +class PrintBase: + def SetPrintFont(self, font): # set the DC font parameters + fattr = font["Attr"] + if fattr[0] == 1: + weight = wx.BOLD + else: + weight = wx.NORMAL + + if fattr[1] == 1: + set_style = wx.ITALIC + else: + set_style = wx.NORMAL + + underline = fattr[2] + fcolour = self.GetFontColour(font) + self.DC.SetTextForeground(fcolour) + + setfont = wx.Font(font["Size"], wx.SWISS, set_style, weight, underline) + setfont.SetFaceName(font["Name"]) + self.DC.SetFont(setfont) + + def GetFontColour(self, font): + fcolour = font["Colour"] + return wx.Colour(fcolour[0], fcolour[1], fcolour[2]) + + def OutTextRegion(self, textout, txtdraw = True): + textlines = textout.split('\n') + y = copy.copy(self.y) + self.pt_space_before + for text in textlines: + remain = 'X' + while remain != "": + vout, remain = self.SetFlow(text, self.region) + if self.draw == True and txtdraw == True: + test_out = self.TestFull(vout) + if self.align == wx.ALIGN_LEFT: + self.DC.DrawText(test_out, self.indent+self.pcell_left_margin, y) + + elif self.align == wx.ALIGN_CENTRE: + diff = self.GetCellDiff(test_out, self.region) + self.DC.DrawText(test_out, self.indent+diff/2, y) + + elif self.align == wx.ALIGN_RIGHT: + diff = self.GetCellDiff(test_out, self.region) + self.DC.DrawText(test_out, self.indent+diff, y) + + else: + self.DC.DrawText(test_out, self.indent+self.pcell_left_margin, y) + text = remain + y = y + self.space + return y - self.space + self.pt_space_after + + def GetCellDiff(self, text, width): # get the remaining cell size for adjustment + w, h = self.DC.GetTextExtent(text) + diff = width - w + if diff < 0: + diff = 0 + return diff + + def TestFull(self, text_test): + w, h = self.DC.GetTextExtent(text_test) + if w > self.region: # trouble fitting into cell + return self.SetChar(text_test, self.region) # fit the text to the cell size + else: + return text_test + + def SetFlow(self, ln_text, width): + width = width - self.pcell_right_margin + text = "" + split = ln_text.split() + if len(split) == 1: + return ln_text, "" + + try: + w, h = self.DC.GetTextExtent(" " + split[0]) + if w >= width: + return ln_text, "" + except: + pass + + cnt = 0 + for word in split: + bword = " " + word # blank + word + length = len(bword) + + w, h = self.DC.GetTextExtent(text + bword) + if w < width: + text = text + bword + cnt = cnt + 1 + else: + remain = ' '.join(split[cnt:]) + text = text.strip() + return text, remain + + remain = ' '.join(split[cnt:]) + vout = text.strip() + return vout, remain + + def SetChar(self, ln_text, width): # truncate string to fit into width + width = width - self.pcell_right_margin - self.pcell_left_margin + text = "" + for val in ln_text: + w, h = self.DC.GetTextExtent(text + val) + if w > width: + text = text + ".." + return text # fitted text value + text = text + val + return text + + def OutTextPageWidth(self, textout, y_out, align, indent, txtdraw = True): + textlines = textout.split('\n') + y = copy.copy(y_out) + + pagew = self.parent.page_width * self.pwidth # full page width + w, h = self.DC.GetTextExtent(textout) + y_line = h + + for text in textlines: + remain = 'X' + while remain != "": + vout, remain = self.SetFlow(text, pagew) + if self.draw == True and txtdraw == True: + test_out = vout + if align == wx.ALIGN_LEFT: + self.DC.DrawText(test_out, indent, y) + + elif align == wx.ALIGN_CENTRE: + diff = self.GetCellDiff(test_out, pagew) + self.DC.DrawText(test_out, indent+diff/2, y) + + elif align == wx.ALIGN_RIGHT: + diff = self.GetCellDiff(test_out, pagew) + self.DC.DrawText(test_out, indent+diff, y) + + else: + self.DC.DrawText(test_out, indent, y_out) + text = remain + y = y + y_line + return y - y_line + + def GetDate(self): + date, time = self.GetNow() + return date + + def GetDateTime(self): + date, time = self.GetNow() + return date + ' ' + time + + def GetNow(self): + now = wx.DateTime.Now() + date = now.FormatDate() + time = now.FormatTime() + return date, time + + def SetPreview(self, preview): + self.preview = preview + + def SetPSize(self, width, height): + self.pwidth = width/self.scale + self.pheight = height/self.scale + + def SetScale(self, scale): + self.scale = scale + + def SetPTSize(self, width, height): + self.ptwidth = width + self.ptheight = height + + def getWidth(self): + return self.sizew + + def getHeight(self): + return self.sizeh + + +class PrintTableDraw(wx.ScrolledWindow, PrintBase): + def __init__(self, parent, DC, size): + self.parent = parent + self.DC = DC + self.scale = parent.scale + self.width = size[0] + self.height = size[1] + self.SetDefaults() + + def SetDefaults(self): + self.page = 1 + self.total_pages = None + + self.page_width = self.parent.page_width + self.page_height = self.parent.page_height + + self.left_margin = self.parent.left_margin + self.right_margin = self.parent.right_margin + + self.top_margin = self.parent.top_margin + self.bottom_margin = self.parent.bottom_margin + self.cell_left_margin = self.parent.cell_left_margin + self.cell_right_margin = self.parent.cell_right_margin + + self.label_colour = self.parent.label_colour + + self.row_line_colour = self.parent.row_line_colour + self.row_line_size = self.parent.row_line_size + + self.row_def_line_colour = self.parent.row_def_line_colour + self.row_def_line_size = self.parent.row_def_line_size + + self.column_line_colour = self.parent.column_line_colour + self.column_line_size = self.parent.column_line_size + + self.column_def_line_size = self.parent.column_def_line_size + self.column_def_line_colour = self.parent.column_def_line_colour + + self.text_font = self.parent.text_font + + self.label_font = self.parent.label_font + + def AdjustValues(self): + self.vertical_offset = self.pheight * self.parent.vertical_offset + self.horizontal_offset = self.pheight * self.parent.horizontal_offset + + self.pcell_left_margin = self.pwidth * self.cell_left_margin + self.pcell_right_margin = self.pwidth * self.cell_right_margin + self.ptop_margin = self.pheight * self.top_margin + self.pbottom_margin = self.pheight * self.bottom_margin + + self.pheader_margin = self.pheight * self.parent.header_margin + self.pfooter_margin = self.pheight * self.parent.footer_margin + + self.cell_colour = self.parent.set_cell_colour + self.cell_text = self.parent.set_cell_text + + self.column = [] + self.column_align = [] + self.column_bgcolour = [] + self.column_txtcolour = [] + + set_column_align = self.parent.set_column_align + set_column_bgcolour = self.parent.set_column_bgcolour + set_column_txtcolour = self.parent.set_column_txtcolour + + pos_x = self.left_margin * self.pwidth + self.horizontal_offset # left margin + self.column.append(pos_x) + + #module logic expects two dimensional data -- fix input if needed + if isinstance(self.data,types.StringTypes): + self.data = [[copy.copy(self.data)]] # a string becomes a single cell + try: + rows = len(self.data) + except TypeError: + self.data = [[str(self.data)]] # a non-iterable becomes a single cell + rows = 1 + first_value = self.data[0] + + if isinstance(first_value, types.StringTypes): # a sequence of strings + if self.label == [] and self.set_column == []: + data = [] + for x in self.data: #becomes one column + data.append([x]) + else: + data = [self.data] #becames one row + self.data = data + first_value = data[0] + try: + column_total = len(first_value) + except TypeError: # a sequence of non-iterables + if self.label == [] and self.set_column == []: + data = [] #becomes one column + for x in self.data: + data.append([str(x)]) + column_total = 1 + else: + data = [self.data] #becomes one row + column_total = len(self.data) + self.data = data + first_value = data[0] + + if self.set_column == []: + table_width = self.page_width - self.left_margin - self.right_margin + if self.label == []: + temp = first_value + else: + temp = self.label + width = table_width/(len(temp)) + for val in temp: + column_width = width * self.pwidth + pos_x = pos_x + column_width + self.column.append(pos_x) # position of each column + else: + for val in self.set_column: + column_width = val * self.pwidth + pos_x = pos_x + column_width + self.column.append(pos_x) # position of each column + + if pos_x > self.page_width * self.pwidth: # check if it fits in page + print "Warning, Too Wide for Page" + return + + if self.label != []: + if len(self.column) -1 != len(self.label): + print "Column Settings Incorrect", "\nColumn Value: " + str(self.column), "\nLabel Value: " + str(self.label) + return + + if column_total != len(self.column) -1: + print "Cannot fit", first_value, 'in', len(self.column)-1, 'columns.' + return + + for col in range(column_total): + try: + align = set_column_align[col] # check if custom column alignment + except: + align = wx.ALIGN_LEFT + self.column_align.append(align) + + try: + colour = set_column_bgcolour[col] # check if custom column background colour + except: + colour = self.parent.column_colour + self.column_bgcolour.append(colour) + + try: + colour = set_column_txtcolour[col] # check if custom column text colour + except: + colour = self.GetFontColour(self.parent.text_font) + self.column_txtcolour.append(colour) + + + def SetPointAdjust(self): + f = wx.Font(10, wx.SWISS, wx.NORMAL, wx.NORMAL) # setup using 10 point + self.DC.SetFont(f) + f.SetFaceName(self.text_font["Name"]) + x, y = self.DC.GetTextExtent("W") + + self.label_pt_space_before = self.parent.label_pt_adj_before * y/10 # extra spacing for label per point value + self.label_pt_space_after = self.parent.label_pt_adj_after * y/10 + + self.text_pt_space_before = self.parent.text_pt_adj_before * y/10 # extra spacing for row text per point value + self.text_pt_space_after = self.parent.text_pt_adj_after * y/10 + + def SetPage(self, page): + self.page = page + + def SetColumns(self, col): + self.column = col + + def OutCanvas(self): + self.AdjustValues() + self.SetPointAdjust() + + self.y_start = self.ptop_margin + self.vertical_offset + self.y_end = self.parent.page_height * self.pheight - self.pbottom_margin + self.vertical_offset + + self.SetPrintFont(self.label_font) + + x, y = self.DC.GetTextExtent("W") + self.label_space = y + + self.SetPrintFont(self.text_font) + + x, y = self.DC.GetTextExtent("W") + self.space = y + + if self.total_pages is None: + self.GetTotalPages() # total pages for display/printing + + self.data_cnt = self.page_index[self.page-1] + + self.draw = True + self.PrintHeader() + self.PrintFooter() + self.OutPage() + + def GetTotalPages(self): + self.data_cnt = 0 + self.draw = False + self.page_index = [0] + + cnt = 0 + while 1: + test = self.OutPage() + self.page_index.append(self.data_cnt) + if test == False: + break + cnt = cnt + 1 + + self.total_pages = cnt + 1 + + def OutPage(self): + self.y = self.y_start + self.end_x = self.column[-1] + + if self.data_cnt < len(self.data): # if there data for display on the page + if self.label != []: # check if header defined + self.PrintLabel() + else: + return False + + for val in self.data: + try: + row_val = self.data[self.data_cnt] + except: + self.FinishDraw() + return False + + max_y = self.PrintRow(row_val, False) # test to see if row will fit in remaining space + test = max_y + self.space + + if test > self.y_end: + break + + self.ColourRowCells(max_y-self.y+self.space) # colour the row/column + max_y = self.PrintRow(row_val, True) # row fits - print text + self.DrawGridLine() # top line of cell + self.y = max_y + self.space + + if self.y > self.y_end: + break + + self.data_cnt = self.data_cnt + 1 + + self.FinishDraw() + + if self.data_cnt == len(self.data): # last value in list + return False + + return True + + + def PrintLabel(self): + self.pt_space_before = self.label_pt_space_before # set the point spacing + self.pt_space_after = self.label_pt_space_after + + self.LabelColorRow(self.label_colour) + self.SetPrintFont(self.label_font) + + self.col = 0 + max_y = 0 + for vtxt in self.label: + self.region = self.column[self.col+1] - self.column[self.col] + self.indent = self.column[self.col] + + self.align = wx.ALIGN_LEFT + + max_out = self.OutTextRegion(vtxt, True) + if max_out > max_y: + max_y = max_out + self.col = self.col + 1 + + self.DrawGridLine() # top line of label + self.y = max_y + self.label_space + + def PrintHeader(self): # print the header array + if self.draw == False: + return + + for val in self.parent.header: + self.SetPrintFont(val["Font"]) + + header_indent = val["Indent"] * self.pwidth + text = val["Text"] + + htype = val["Type"] + if htype == "Date": + addtext = self.GetDate() + elif htype == "Date & Time": + addtext = self.GetDateTime() + else: + addtext = "" + + self.OutTextPageWidth(text+addtext, self.pheader_margin, val["Align"], header_indent, True) + + def PrintFooter(self): # print the header array + if self.draw == False: + return + + footer_pos = self.parent.page_height * self.pheight - self.pfooter_margin + self.vertical_offset + for val in self.parent.footer: + self.SetPrintFont(val["Font"]) + + footer_indent = val["Indent"] * self.pwidth + text = val["Text"] + + ftype = val["Type"] + if ftype == "Pageof": + addtext = "Page " + str(self.page) + " of " + str(self.total_pages) + elif ftype == "Page": + addtext = "Page " + str(self.page) + elif ftype == "Num": + addtext = str(self.page) + elif ftype == "Date": + addtext = self.GetDate() + elif ftype == "Date & Time": + addtext = self.GetDateTime() + else: + addtext = "" + + self.OutTextPageWidth(text+addtext, footer_pos, val["Align"], footer_indent, True) + + + def LabelColorRow(self, colour): + brush = wx.Brush(colour, wx.SOLID) + self.DC.SetBrush(brush) + height = self.label_space + self.label_pt_space_before + self.label_pt_space_after + self.DC.DrawRectangle(self.column[0], self.y, + self.end_x-self.column[0]+1, height) + + def ColourRowCells(self, height): + if self.draw == False: + return + + col = 0 + for colour in self.column_bgcolour: + cellcolour = self.GetCellColour(self.data_cnt, col) + if cellcolour is not None: + colour = cellcolour + + brush = wx.Brush(colour, wx.SOLID) + self.DC.SetBrush(brush) + self.DC.SetPen(wx.Pen(wx.NamedColour('WHITE'), 0)) + + start_x = self.column[col] + width = self.column[col+1] - start_x + 2 + self.DC.DrawRectangle(start_x, self.y, width, height) + col = col + 1 + + def PrintRow(self, row_val, draw = True, align = wx.ALIGN_LEFT): + self.SetPrintFont(self.text_font) + + self.pt_space_before = self.text_pt_space_before # set the point spacing + self.pt_space_after = self.text_pt_space_after + + self.col = 0 + max_y = 0 + for vtxt in row_val: + if not isinstance(vtxt,types.StringTypes): + vtxt = str(vtxt) + self.region = self.column[self.col+1] - self.column[self.col] + self.indent = self.column[self.col] + self.align = self.column_align[self.col] + + fcolour = self.column_txtcolour[self.col] # set font colour + celltext = self.GetCellTextColour(self.data_cnt, self.col) + if celltext is not None: + fcolour = celltext # override the column colour + + self.DC.SetTextForeground(fcolour) + + max_out = self.OutTextRegion(vtxt, draw) + if max_out > max_y: + max_y = max_out + self.col = self.col + 1 + return max_y + + def GetCellColour(self, row, col): # check if custom colour defined for the cell background + try: + set = self.cell_colour[row] + except: + return None + try: + colour = set[col] + return colour + except: + return None + + def GetCellTextColour(self, row, col): # check if custom colour defined for the cell text + try: + set = self.cell_text[row] + except: + return None + try: + colour = set[col] + return colour + except: + return None + + def FinishDraw(self): + self.DrawGridLine() # draw last row line + self.DrawColumns() # draw all vertical lines + + def DrawGridLine(self): + if self.draw == True \ + and len(self.column) > 2: #supress grid lines if only one column + try: + size = self.row_line_size[self.data_cnt] + except: + size = self.row_def_line_size + + try: + colour = self.row_line_colour[self.data_cnt] + except: + colour = self.row_def_line_colour + + self.DC.SetPen(wx.Pen(colour, size)) + + y_out = self.y +# y_out = self.y + self.pt_space_before + self.pt_space_after # adjust for extra spacing + self.DC.DrawLine(self.column[0], y_out, self.end_x, y_out) + + def DrawColumns(self): + if self.draw == True \ + and len(self.column) > 2: #surpress grid line if only one column + col = 0 + for val in self.column: + try: + size = self.column_line_size[col] + except: + size = self.column_def_line_size + + try: + colour = self.column_line_colour[col] + except: + colour = self.column_def_line_colour + + indent = val + + self.DC.SetPen(wx.Pen(colour, size)) + self.DC.DrawLine(indent, self.y_start, indent, self.y) + col = col + 1 + + def DrawText(self): + self.DoRefresh() + + def DoDrawing(self, DC): + size = DC.GetSize() + self.DC = DC + + DC.BeginDrawing() + self.DrawText() + DC.EndDrawing() + + self.sizew = DC.MaxY() + self.sizeh = DC.MaxX() + + +class PrintTable: + def __init__(self, parentFrame=None): + self.data = [] + self.set_column = [] + self.label = [] + self.header = [] + self.footer = [] + + self.set_column_align = {} + self.set_column_bgcolour = {} + self.set_column_txtcolour = {} + self.set_cell_colour = {} + self.set_cell_text = {} + self.column_line_size = {} + self.column_line_colour = {} + self.row_line_size = {} + self.row_line_colour = {} + + self.parentFrame = parentFrame + self.SetPreviewSize() + + self.printData = wx.PrintData() + self.scale = 1.0 + + self.SetParms() + self.SetColors() + self.SetFonts() + self.TextSpacing() + + self.SetPrinterOffset() + self.SetHeaderValue() + self.SetFooterValue() + self.SetMargins() + self.SetPortrait() + + def SetPreviewSize(self, position = wx.Point(0, 0), size="Full"): + if size == "Full": + r = wx.GetClientDisplayRect() + self.preview_frame_size = r.GetSize() + self.preview_frame_pos = r.GetPosition() + else: + self.preview_frame_size = size + self.preview_frame_pos = position + + def SetPaperId(self, paper): + self.printData.SetPaperId(paper) + + def SetOrientation(self, orient): + self.printData.SetOrientation(orient) + + def SetColors(self): + self.row_def_line_colour = wx.NamedColour('BLACK') + self.row_def_line_size = 1 + + self.column_def_line_colour = wx.NamedColour('BLACK') + self.column_def_line_size = 1 + self.column_colour = wx.NamedColour('WHITE') + + self.label_colour = wx.NamedColour('LIGHT GREY') + + def SetFonts(self): + self.label_font = { "Name": self.default_font_name, "Size": 12, "Colour": [0, 0, 0], "Attr": [0, 0, 0] } + self.text_font = { "Name": self.default_font_name, "Size": 10, "Colour": [0, 0, 0], "Attr": [0, 0, 0] } + + def TextSpacing(self): + self.label_pt_adj_before = 0 # point adjustment before and after the label text + self.label_pt_adj_after = 0 + + self.text_pt_adj_before = 0 # point adjustment before and after the row text + self.text_pt_adj_after = 0 + + def SetLabelSpacing(self, before, after): # method to set the label space adjustment + self.label_pt_adj_before = before + self.label_pt_adj_after = after + + def SetRowSpacing(self, before, after): # method to set the row space adjustment + self.text_pt_adj_before = before + self.text_pt_adj_after = after + + def SetPrinterOffset(self): # offset to adjust for printer + self.vertical_offset = -0.1 + self.horizontal_offset = -0.1 + + def SetHeaderValue(self): + self.header_margin = 0.25 + self.header_font = { "Name": self.default_font_name, "Size": 11, "Colour": [0, 0, 0], "Attr": [0, 0, 0] } + self.header_align = wx.ALIGN_CENTRE + self.header_indent = 0 + self.header_type = "Text" + + def SetFooterValue(self): + self.footer_margin = 0.7 + self.footer_font = { "Name": self.default_font_name, "Size": 11, "Colour": [0, 0, 0], "Attr": [0, 0, 0] } + self.footer_align = wx.ALIGN_CENTRE + self.footer_indent = 0 + self.footer_type = "Pageof" + + def SetMargins(self): + self.left_margin = 0.5 + self.right_margin = 0.5 # only used if no column sizes + + self.top_margin = 0.8 + self.bottom_margin = 1.0 + self.cell_left_margin = 0.1 + self.cell_right_margin = 0.1 + + def SetPortrait(self): + self.printData.SetPaperId(wx.PAPER_LETTER) + self.printData.SetOrientation(wx.PORTRAIT) + self.page_width = 8.5 + self.page_height = 11.0 + + def SetLandscape(self): + self.printData.SetOrientation(wx.LANDSCAPE) + self.page_width = 11.0 + self.page_height = 8.5 + + def SetParms(self): + self.ymax = 1 + self.xmax = 1 + self.page = 1 + self.total_pg = 100 + + self.preview = None + self.page = 0 + + self.default_font_name = "Arial" + self.default_font = { "Name": self.default_font_name, "Size": 10, "Colour": [0, 0, 0], "Attr": [0, 0, 0] } + + def SetColAlignment(self, col, align=wx.ALIGN_LEFT): + self.set_column_align[col] = align + + def SetColBackgroundColour(self, col, colour): + self.set_column_bgcolour[col] = colour + + def SetColTextColour(self, col, colour): + self.set_column_txtcolour[col] = colour + + def SetCellColour(self, row, col, colour): # cell background colour + try: + set = self.set_cell_colour[row] # test if row already exists + try: + set[col] = colour # test if column already exists + except: + set = { col: colour } # create the column value + except: + set = { col: colour } # create the column value + + self.set_cell_colour[row] = set # create dictionary item for colour settings + + def SetCellText(self, row, col, colour): # font colour for custom cells + try: + set = self.set_cell_text[row] # test if row already exists + try: + set[col] = colour # test if column already exists + except: + set = { col: colour } # create the column value + except: + set = { col: colour } # create the column value + + self.set_cell_text[row] = set # create dictionary item for colour settings + + def SetColumnLineSize(self, col, size): # column line size + self.column_line_size[col] = size # create dictionary item for column line settings + + def SetColumnLineColour(self, col, colour): + self.column_line_colour[col] = colour + + def SetRowLineSize(self, row, size): + self.row_line_size[row] = size + + def SetRowLineColour(self, row, colour): + self.row_line_colour[row] = colour + + def GetColour(self, colour): # returns colours based from wxColour value + red = colour.Red() + blue = colour.Blue() + green = colour.Green() + return [red, green, blue ] + + def SetHeader(self, text = "", type = "Text", font=None, align = None, indent = None, colour = None, size = None): + set = { "Text": text } + + if font is None: + set["Font"] = copy.copy(self.default_font) + else: + set["Font"] = font + + if colour is not None: + setfont = set["Font"] + setfont["Colour"] = self.GetColour(colour) + + if size is not None: + setfont = set["Font"] + setfont["Size"] = size + + if align is None: + set["Align"] = self.header_align + else: + set["Align"] = align + + if indent is None: + set["Indent"] = self.header_indent + else: + set["Indent"] = indent + + if type is None: + set["Type"] = self.header_type + else: + set["Type"] = type + + self.header.append(set) + + def SetFooter(self, text = "", type = None, font=None, align = None, indent = None, colour = None, size = None): + set = { "Text": text } + + if font is None: + set["Font"] = copy.copy(self.default_font) + else: + set["Font"] = font + + if colour is not None: + setfont = set["Font"] + setfont["Colour"] = self.GetColour(colour) + + if size is not None: + setfont = set["Font"] + setfont["Size"] = size + + if align is None: + set["Align"] = self.footer_align + else: + set["Align"] = align + + if indent is None: + set["Indent"] = self.footer_indent + else: + set["Indent"] = indent + + if type is None: + set["Type"] = self.footer_type + else: + set["Type"] = type + + self.footer.append(set) + + def Preview(self): + data = wx.PrintDialogData(self.printData) + printout = SetPrintout(self) + printout2 = SetPrintout(self) + self.preview = wx.PrintPreview(printout, printout2, data) + if not self.preview.Ok(): + wxMessageBox("There was a problem printing!", "Printing", wx.OK) + return + + self.preview.SetZoom(60) # initial zoom value + frame = wx.PreviewFrame(self.preview, self.parentFrame, "Print preview") + + frame.Initialize() + if self.parentFrame: + frame.SetPosition(self.preview_frame_pos) + frame.SetSize(self.preview_frame_size) + frame.Show(True) + + def Print(self): + pdd = wx.PrintDialogData(self.printData) + printer = wx.Printer(pdd) + printout = SetPrintout(self) + if not printer.Print(self.parentFrame, printout): + wx.MessageBox("There was a problem printing.\nPerhaps your current printer is not set correctly?", "Printing", wx.OK) + else: + self.printData = wx.PrintData( printer.GetPrintDialogData().GetPrintData() ) + printout.Destroy() + + def DoDrawing(self, DC): + size = DC.GetSize() + DC.BeginDrawing() + + table = PrintTableDraw(self, DC, size) + table.data = self.data + table.set_column = self.set_column + table.label = self.label + table.SetPage(self.page) + + if self.preview is None: + table.SetPSize(size[0]/self.page_width, size[1]/self.page_height) + table.SetPTSize(size[0], size[1]) + table.SetPreview(False) + else: + if self.preview == 1: + table.scale = self.scale + table.SetPSize(size[0]/self.page_width, size[1]/self.page_height) + else: + table.SetPSize(self.pwidth, self.pheight) + + table.SetPTSize(self.ptwidth, self.ptheight) + table.SetPreview(self.preview) + + table.OutCanvas() + self.page_total = table.total_pages # total display pages + + DC.EndDrawing() + + self.ymax = DC.MaxY() + self.xmax = DC.MaxX() + + self.sizeh = size[0] + self.sizew = size[1] + + def GetTotalPages(self): + self.page_total = 100 + return self.page_total + + def HasPage(self, page): + if page <= self.page_total: + return True + else: + return False + + def SetPage(self, page): + self.page = page + + def SetPageSize(self, width, height): + self.pwidth, self.pheight = width, height + + def SetTotalSize(self, width, height): + self.ptwidth, self.ptheight = width, height + + def SetPreview(self, preview, scale): + self.preview = preview + self.scale = scale + + def SetTotalSize(self, width, height): + self.ptwidth = width + self.ptheight = height + +class PrintGrid: + def __init__(self, parent, grid, format = [], total_col = None, total_row = None): + if total_row is None: + total_row = grid.GetNumberRows() + if total_col is None: + total_col = grid.GetNumberCols() + + self.total_row = total_row + self.total_col = total_col + self.grid = grid + + data = [] + for row in range(total_row): + row_val = [] + value = grid.GetRowLabelValue(row) + row_val.append(value) + + for col in range(total_col): + value = grid.GetCellValue(row, col) + row_val.append(value) + data.append(row_val) + + label = [""] + for col in range(total_col): + value = grid.GetColLabelValue(col) + label.append(value) + + self.table = PrintTable(parent) + self.table.cell_left_margin = 0.0 + self.table.cell_right_margin = 0.0 + + self.table.label = label + self.table.set_column = format + self.table.data = data + + def GetTable(self): + return self.table + + def SetAttributes(self): + for row in range(self.total_row): + for col in range(self.total_col): + colour = self.grid.GetCellTextColour(row, col-1) + self.table.SetCellText(row, col, colour) + + colour = self.grid.GetCellBackgroundColour(row, col-1) + self.table.SetCellColour(row, col, colour) + + def Preview(self): + self.table.Preview() + + def Print(self): + self.table.Print() + + +class SetPrintout(wx.Printout): + def __init__(self, canvas): + wx.Printout.__init__(self) + self.canvas = canvas + self.end_pg = 1000 + + def OnBeginDocument(self, start, end): + return super(SetPrintout, self).OnBeginDocument(start, end) + + def OnEndDocument(self): + super(SetPrintout, self).OnEndDocument() + + def HasPage(self, page): + try: + end = self.canvas.HasPage(page) + return end + except: + return True + + def GetPageInfo(self): + try: + self.end_pg = self.canvas.GetTotalPages() + except: + pass + + end_pg = self.end_pg + str_pg = 1 + return (str_pg, end_pg, str_pg, end_pg) + + def OnPreparePrinting(self): + super(SetPrintout, self).OnPreparePrinting() + + def OnBeginPrinting(self): + dc = self.GetDC() + + self.preview = self.IsPreview() + if (self.preview): + self.pixelsPerInch = self.GetPPIScreen() + else: + self.pixelsPerInch = self.GetPPIPrinter() + + (w, h) = dc.GetSize() + scaleX = float(w) / 1000 + scaleY = float(h) / 1000 + self.printUserScale = min(scaleX, scaleY) + + super(SetPrintout, self).OnBeginPrinting() + + def GetSize(self): + self.psizew, self.psizeh = self.GetPPIPrinter() + return self.psizew, self.psizeh + + def GetTotalSize(self): + self.ptsizew, self.ptsizeh = self.GetPageSizePixels() + return self.ptsizew, self.ptsizeh + + def OnPrintPage(self, page): + dc = self.GetDC() + (w, h) = dc.GetSize() + scaleX = float(w) / 1000 + scaleY = float(h) / 1000 + self.printUserScale = min(scaleX, scaleY) + dc.SetUserScale(self.printUserScale, self.printUserScale) + + self.preview = self.IsPreview() + + self.canvas.SetPreview(self.preview, self.printUserScale) + self.canvas.SetPage(page) + + self.ptsizew, self.ptsizeh = self.GetPageSizePixels() + self.canvas.SetTotalSize(self.ptsizew, self.ptsizeh) + + self.psizew, self.psizeh = self.GetPPIPrinter() + self.canvas.SetPageSize(self.psizew, self.psizeh) + + self.canvas.DoDrawing(dc) + return True + +if __name__ == '__main__': + app = wx.PySimpleApp() + frame = wx.Frame(None, -1, "Dummy wx frame for testing printout.py") + frame.Show(True) + ptbl = PrintTable(frame) + ptbl.SetHeader('This is the test HEADER') + # a single sequence will print out as a single column with no borders ... + ptbl.data = ( + 'This is the first line of text.', + 'This is the second line\nand the third. The fourth will be the number "4.0".', + 04.00, + 'This is the fifth line, but by design it is too long to fit in the width of a standard'\ + ' page, so it will be forced to wrap around in order to fit without having '\ + 'some of its verbose verbage truncated.', + 'Here we have the final line.' + ) + #... but, if labels or columns are defined, a single sequence will print out as a single row + ##ptbl.label = ('One','Two','Three','Four','5') + ptbl.Preview() + app.MainLoop()