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