]> git.saurik.com Git - wxWidgets.git/blame - wxPython/samples/wxPIA_book/Chapter-17/printing.py
Added the sample code from wxPython In Action to the samples dir
[wxWidgets.git] / wxPython / samples / wxPIA_book / Chapter-17 / printing.py
CommitLineData
be05b434
RD
1import wx
2import os
3
4FONTSIZE = 10
5
6class TextDocPrintout(wx.Printout):
7 """
8 A printout class that is able to print simple text documents.
9 Does not handle page numbers or titles, and it assumes that no
10 lines are longer than what will fit within the page width. Those
11 features are left as an exercise for the reader. ;-)
12 """
13 def __init__(self, text, title, margins):
14 wx.Printout.__init__(self, title)
15 self.lines = text.split('\n')
16 self.margins = margins
17
18
19 def HasPage(self, page):
20 return page <= self.numPages
21
22 def GetPageInfo(self):
23 return (1, self.numPages, 1, self.numPages)
24
25
26 def CalculateScale(self, dc):
27 # Scale the DC such that the printout is roughly the same as
28 # the screen scaling.
29 ppiPrinterX, ppiPrinterY = self.GetPPIPrinter()
30 ppiScreenX, ppiScreenY = self.GetPPIScreen()
31 logScale = float(ppiPrinterX)/float(ppiScreenX)
32
33 # Now adjust if the real page size is reduced (such as when
34 # drawing on a scaled wx.MemoryDC in the Print Preview.) If
35 # page width == DC width then nothing changes, otherwise we
36 # scale down for the DC.
37 pw, ph = self.GetPageSizePixels()
38 dw, dh = dc.GetSize()
39 scale = logScale * float(dw)/float(pw)
40
41 # Set the DC's scale.
42 dc.SetUserScale(scale, scale)
43
44 # Find the logical units per millimeter (for calculating the
45 # margins)
46 self.logUnitsMM = float(ppiPrinterX)/(logScale*25.4)
47
48
49 def CalculateLayout(self, dc):
50 # Determine the position of the margins and the
51 # page/line height
52 topLeft, bottomRight = self.margins
53 dw, dh = dc.GetSize()
54 self.x1 = topLeft.x * self.logUnitsMM
55 self.y1 = topLeft.y * self.logUnitsMM
56 self.x2 = dc.DeviceToLogicalXRel(dw) - bottomRight.x * self.logUnitsMM
57 self.y2 = dc.DeviceToLogicalYRel(dh) - bottomRight.y * self.logUnitsMM
58
59 # use a 1mm buffer around the inside of the box, and a few
60 # pixels between each line
61 self.pageHeight = self.y2 - self.y1 - 2*self.logUnitsMM
62 font = wx.Font(FONTSIZE, wx.TELETYPE, wx.NORMAL, wx.NORMAL)
63 dc.SetFont(font)
64 self.lineHeight = dc.GetCharHeight()
65 self.linesPerPage = int(self.pageHeight/self.lineHeight)
66
67
68 def OnPreparePrinting(self):
69 # calculate the number of pages
70 dc = self.GetDC()
71 self.CalculateScale(dc)
72 self.CalculateLayout(dc)
73 self.numPages = len(self.lines) / self.linesPerPage
74 if len(self.lines) % self.linesPerPage != 0:
75 self.numPages += 1
76
77
78 def OnPrintPage(self, page):
79 dc = self.GetDC()
80 self.CalculateScale(dc)
81 self.CalculateLayout(dc)
82
83 # draw a page outline at the margin points
84 dc.SetPen(wx.Pen("black", 0))
85 dc.SetBrush(wx.TRANSPARENT_BRUSH)
86 r = wx.RectPP((self.x1, self.y1),
87 (self.x2, self.y2))
88 dc.DrawRectangleRect(r)
89 dc.SetClippingRect(r)
90
91 # Draw the text lines for this page
92 line = (page-1) * self.linesPerPage
93 x = self.x1 + self.logUnitsMM
94 y = self.y1 + self.logUnitsMM
95 while line < (page * self.linesPerPage):
96 dc.DrawText(self.lines[line], x, y)
97 y += self.lineHeight
98 line += 1
99 if line >= len(self.lines):
100 break
101 return True
102
103
104class PrintFrameworkSample(wx.Frame):
105 def __init__(self):
106 wx.Frame.__init__(self, None, size=(640, 480),
107 title="Print Framework Sample")
108 self.CreateStatusBar()
109
110 # A text widget to display the doc and let it be edited
111 self.tc = wx.TextCtrl(self, -1, "",
112 style=wx.TE_MULTILINE|wx.TE_DONTWRAP)
113 self.tc.SetFont(wx.Font(FONTSIZE, wx.TELETYPE, wx.NORMAL, wx.NORMAL))
114 filename = os.path.join(os.path.dirname(__file__), "sample-text.txt")
115 self.tc.SetValue(open(filename).read())
116 self.tc.Bind(wx.EVT_SET_FOCUS, self.OnClearSelection)
117 wx.CallAfter(self.tc.SetInsertionPoint, 0)
118
119 # Create the menu and menubar
120 menu = wx.Menu()
121 item = menu.Append(-1, "Page Setup...\tF5",
122 "Set up page margins and etc.")
123 self.Bind(wx.EVT_MENU, self.OnPageSetup, item)
124 item = menu.Append(-1, "Print Preview...\tF6",
125 "View the printout on-screen")
126 self.Bind(wx.EVT_MENU, self.OnPrintPreview, item)
127 item = menu.Append(-1, "Print...\tF7", "Print the document")
128 self.Bind(wx.EVT_MENU, self.OnPrint, item)
129 menu.AppendSeparator()
130## item = menu.Append(-1, "Test other stuff...\tF9", "")
131## self.Bind(wx.EVT_MENU, self.OnPrintTest, item)
132## menu.AppendSeparator()
133 item = menu.Append(wx.ID_EXIT, "E&xit\tCtrl-Q", "Close this application")
134 self.Bind(wx.EVT_MENU, self.OnExit, item)
135
136 menubar = wx.MenuBar()
137 menubar.Append(menu, "&File")
138 self.SetMenuBar(menubar)
139
140 # initialize the print data and set some default values
141 self.pdata = wx.PrintData()
142 self.pdata.SetPaperId(wx.PAPER_LETTER)
143 self.pdata.SetOrientation(wx.PORTRAIT)
144 self.margins = (wx.Point(15,15), wx.Point(15,15))
145
146
147 def OnExit(self, evt):
148 self.Close()
149
150
151 def OnClearSelection(self, evt):
152 evt.Skip()
153 wx.CallAfter(self.tc.SetInsertionPoint,
154 self.tc.GetInsertionPoint())
155
156
157 def OnPageSetup(self, evt):
158 data = wx.PageSetupDialogData()
159 data.SetPrintData(self.pdata)
160
161 data.SetDefaultMinMargins(True)
162 data.SetMarginTopLeft(self.margins[0])
163 data.SetMarginBottomRight(self.margins[1])
164
165 dlg = wx.PageSetupDialog(self, data)
166 if dlg.ShowModal() == wx.ID_OK:
167 data = dlg.GetPageSetupData()
168 self.pdata = wx.PrintData(data.GetPrintData()) # force a copy
169 self.pdata.SetPaperId(data.GetPaperId())
170 self.margins = (data.GetMarginTopLeft(),
171 data.GetMarginBottomRight())
172 dlg.Destroy()
173
174
175 def OnPrintPreview(self, evt):
176 data = wx.PrintDialogData(self.pdata)
177 text = self.tc.GetValue()
178 printout1 = TextDocPrintout(text, "title", self.margins)
179 printout2 = None #TextDocPrintout(text, "title", self.margins)
180 preview = wx.PrintPreview(printout1, printout2, data)
181 if not preview.Ok():
182 wx.MessageBox("Unable to create PrintPreview!", "Error")
183 else:
184 # create the preview frame such that it overlays the app frame
185 frame = wx.PreviewFrame(preview, self, "Print Preview",
186 pos=self.GetPosition(),
187 size=self.GetSize())
188 frame.Initialize()
189 frame.Show()
190
191
192 def OnPrint(self, evt):
193 data = wx.PrintDialogData(self.pdata)
194 printer = wx.Printer(data)
195 text = self.tc.GetValue()
196 printout = TextDocPrintout(text, "title", self.margins)
197 useSetupDialog = True
198 if not printer.Print(self, printout, useSetupDialog) \
199 and printer.GetLastError() == wx.PRINTER_ERROR:
200 wx.MessageBox(
201 "There was a problem printing.\n"
202 "Perhaps your current printer is not set correctly?",
203 "Printing Error", wx.OK)
204 else:
205 data = printer.GetPrintDialogData()
206 self.pdata = wx.PrintData(data.GetPrintData()) # force a copy
207 printout.Destroy()
208
209
210 def OnPrintTest(self, evt):
211 data = wx.PrintDialogData(self.pdata)
212 dlg = wx.PrintDialog(self, data)
213 if dlg.ShowModal() == wx.ID_OK:
214 data = dlg.GetPrintDialogData()
215 print
216 print "GetFromPage:", data.GetFromPage()
217 print "GetToPage:", data.GetToPage()
218 print "GetMinPage:", data.GetMinPage()
219 print "GetMaxPage:", data.GetMaxPage()
220 print "GetNoCopies:", data.GetNoCopies()
221 print "GetAllPages:", data.GetAllPages()
222 print "GetSelection:", data.GetSelection()
223 print "GetCollate:", data.GetCollate()
224 print "GetPrintToFile:", data.GetPrintToFile()
225
226 self.pdata = wx.PrintData(data.GetPrintData())
227 print
228 print "GetPrinterName:", self.pdata.GetPrinterName()
229
230 dlg.Destroy()
231
232
233app = wx.PySimpleApp()
234frm = PrintFrameworkSample()
235frm.Show()
236app.MainLoop()