1#!/usr/bin/env python 2 3import wx 4import ScrolledWindow 5 6#---------------------------------------------------------------------- 7 8 9class MyPrintout(wx.Printout): 10 def __init__(self, canvas, log): 11 wx.Printout.__init__(self) 12 self.canvas = canvas 13 self.log = log 14 15 def OnBeginDocument(self, start, end): 16 self.log.WriteText("MyPrintout.OnBeginDocument\n") 17 return super(MyPrintout, self).OnBeginDocument(start, end) 18 19 def OnEndDocument(self): 20 self.log.WriteText("MyPrintout.OnEndDocument\n") 21 super(MyPrintout, self).OnEndDocument() 22 23 def OnBeginPrinting(self): 24 self.log.WriteText("MyPrintout.OnBeginPrinting\n") 25 super(MyPrintout, self).OnBeginPrinting() 26 27 def OnEndPrinting(self): 28 self.log.WriteText("MyPrintout.OnEndPrinting\n") 29 super(MyPrintout, self).OnEndPrinting() 30 31 def OnPreparePrinting(self): 32 self.log.WriteText("MyPrintout.OnPreparePrinting\n") 33 super(MyPrintout, self).OnPreparePrinting() 34 35 def HasPage(self, page): 36 self.log.WriteText("MyPrintout.HasPage: %d\n" % page) 37 if page <= 2: # we only have 2 pages in this document 38 return True 39 else: 40 return False 41 42 def GetPageInfo(self): 43 self.log.WriteText("MyPrintout.GetPageInfo\n") 44 return (1, 2, 1, 2) 45 46 def OnPrintPage(self, page): 47 self.log.WriteText("MyPrintout.OnPrintPage: %d\n" % page) 48 dc = self.GetDC() 49 50 #------------------------------------------- 51 # One possible method of setting scaling factors... 52 53 maxX = self.canvas.getWidth() 54 maxY = self.canvas.getHeight() 55 56 # Let's have at least 50 device units margin 57 marginX = 50 58 marginY = 50 59 60 # Add the margin to the graphic size 61 maxX = maxX + (2 * marginX) 62 maxY = maxY + (2 * marginY) 63 64 # Get the size of the DC in pixels 65 (w, h) = dc.GetSize() 66 67 # Calculate a suitable scaling factor 68 scaleX = float(w) / maxX 69 scaleY = float(h) / maxY 70 71 # Use x or y scaling factor, whichever fits on the DC 72 actualScale = min(scaleX, scaleY) 73 74 # Calculate the position on the DC for centering the graphic 75 posX = (w - (self.canvas.getWidth() * actualScale)) / 2.0 76 posY = (h - (self.canvas.getHeight() * actualScale)) / 2.0 77 78 # Set the scale and origin 79 dc.SetUserScale(actualScale, actualScale) 80 dc.SetDeviceOrigin(int(posX), int(posY)) 81 82 #------------------------------------------- 83 self.canvas.DoDrawing(dc, True) 84 dc.DrawText("Page: %d" % page, marginX/2, maxY-marginY) 85 86 return True 87 88 89#---------------------------------------------------------------------- 90 91 92class TestPrintPanel(wx.Panel): 93 def __init__(self, parent, frame, log): 94 wx.Panel.__init__(self, parent, -1) 95 self.log = log 96 self.frame = frame 97 98 self.printData = wx.PrintData() 99 self.printData.SetPaperId(wx.PAPER_LETTER) 100 self.printData.SetPrintMode(wx.PRINT_MODE_PRINTER) 101 102 self.box = wx.BoxSizer(wx.VERTICAL) 103 self.canvas = ScrolledWindow.MyCanvas(self) 104 self.box.Add(self.canvas, 1, wx.GROW) 105 106 subbox = wx.BoxSizer(wx.HORIZONTAL) 107 btn = wx.Button(self, -1, "Page Setup") 108 self.Bind(wx.EVT_BUTTON, self.OnPageSetup, btn) 109 subbox.Add(btn, 1, wx.GROW | wx.ALL, 2) 110 111 btn = wx.Button(self, -1, "Print Preview") 112 self.Bind(wx.EVT_BUTTON, self.OnPrintPreview, btn) 113 subbox.Add(btn, 1, wx.GROW | wx.ALL, 2) 114 115 btn = wx.Button(self, -1, "Print") 116 self.Bind(wx.EVT_BUTTON, self.OnDoPrint, btn) 117 subbox.Add(btn, 1, wx.GROW | wx.ALL, 2) 118 119 self.box.Add(subbox, 0, wx.GROW) 120 121 self.SetAutoLayout(True) 122 self.SetSizer(self.box) 123 124 125 def OnPageSetup(self, evt): 126 psdd = wx.PageSetupDialogData(self.printData) 127 psdd.EnablePrinter(True) 128 # psdd.CalculatePaperSizeFromId() 129 dlg = wx.PageSetupDialog(self, psdd) 130 dlg.ShowModal() 131 132 # this makes a copy of the wx.PrintData instead of just saving 133 # a reference to the one inside the PrintDialogData that will 134 # be destroyed when the dialog is destroyed 135 self.printData = wx.PrintData( dlg.GetPageSetupData().GetPrintData() ) 136 137 dlg.Destroy() 138 139 def OnPrintPreview(self, event): 140 data = wx.PrintDialogData(self.printData) 141 printout = MyPrintout(self.canvas, self.log) 142 printout2 = MyPrintout(self.canvas, self.log) 143 self.preview = wx.PrintPreview(printout, printout2, data) 144 145 if not self.preview.IsOk(): 146 self.log.WriteText("Houston, we have a problem...\n") 147 return 148 149 pfrm = wx.PreviewFrame(self.preview, self.frame, "This is a print preview") 150 151 pfrm.Initialize() 152 pfrm.SetPosition(self.frame.GetPosition()) 153 pfrm.SetSize(self.frame.GetSize()) 154 pfrm.Show(True) 155 156 def OnDoPrint(self, event): 157 pdd = wx.PrintDialogData(self.printData) 158 pdd.SetToPage(2) 159 printer = wx.Printer(pdd) 160 printout = MyPrintout(self.canvas, self.log) 161 162 if not printer.Print(self.frame, printout, True): 163 wx.MessageBox("There was a problem printing.\nPerhaps your current printer is not set correctly?", "Printing", wx.OK) 164 else: 165 self.printData = wx.PrintData( printer.GetPrintDialogData().GetPrintData() ) 166 printout.Destroy() 167 168 169#---------------------------------------------------------------------- 170 171def runTest(frame, nb, log): 172 win = TestPrintPanel(nb, frame, log) 173 return win 174 175 176#---------------------------------------------------------------------- 177 178 179 180overview = """\ 181<html> 182<body> 183<h1>PrintFramework</h1> 184 185This is an overview of the classes and methods used to print documents. 186It also demonstrates how to do print previews and invoke the printer 187setup dialog. 188 189<p>Classes demonstrated here:<P> 190<ul> 191 <li><b>wx.Printout()</b> - This class encapsulates the functionality of printing out 192 an application document. A new class must be derived and members overridden 193 to respond to calls such as OnPrintPage and HasPage. Instances of this class 194 are passed to wx.Printer.Print() or a wx.PrintPreview object to initiate 195 printing or previewing.<P><p> 196 197 <li><b>wx.PrintData()</b> - This class holds a variety of information related to 198 printers and printer device contexts. This class is used to create a 199 wx.PrinterDC and a wx.PostScriptDC. It is also used as a data member of 200 wx.PrintDialogData and wx.PageSetupDialogData, as part of the mechanism for 201 transferring data between the print dialogs and the application.<p><p> 202 203 <li><b>wx.PrintDialog()</b> - This class represents the print and print setup 204 common dialogs. You may obtain a wx.PrinterDC device context from a 205 successfully dismissed print dialog.<p><p> 206 207 <li><b>wx.PrintPreview()</b> - Objects of this class manage the print preview 208 process. The object is passed a wx.Printout object, and the wx.PrintPreview 209 object itself is passed to a wx.PreviewFrame object. Previewing is started by 210 initializing and showing the preview frame. Unlike wxPrinter.Print, flow of 211 control returns to the application immediately after the frame is shown.<p><p> 212</ul> 213 214<p>Other classes are also demonstrated, but this is the gist of the printer interface 215framework in wxPython. 216 217</body> 218</html> 219 220""" 221 222 223if __name__ == '__main__': 224 import sys,os 225 import run 226 run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:]) 227 228