1"""
2@package mapdisp.gprint
3
4@brief Print context and utility functions for printing
5contents of map display window.
6
7Classes:
8 - gprint::MapPrint
9 - gprint::PrintOptions
10
11(C) 2007-2011 by the GRASS Development Team
12
13This program is free software under the GNU General Public License
14(>=v2). Read the file COPYING that comes with GRASS for details.
15
16@author Michael Barton (Arizona State University)
17"""
18
19import wx
20
21from core.gcmd import GMessage
22
23
24class MapPrint(wx.Printout):
25
26    def __init__(self, canvas):
27        wx.Printout.__init__(self)
28        self.canvas = canvas
29
30    def OnBeginDocument(self, start, end):
31        return super(MapPrint, self).OnBeginDocument(start, end)
32
33    def OnEndDocument(self):
34        super(MapPrint, self).OnEndDocument()
35
36    def OnBeginPrinting(self):
37        super(MapPrint, self).OnBeginPrinting()
38
39    def OnEndPrinting(self):
40        super(MapPrint, self).OnEndPrinting()
41
42    def OnPreparePrinting(self):
43        super(MapPrint, self).OnPreparePrinting()
44
45    def HasPage(self, page):
46        if page <= 2:
47            return True
48        else:
49            return False
50
51    def GetPageInfo(self):
52        return (1, 2, 1, 2)
53
54    def OnPrintPage(self, page):
55        dc = self.GetDC()
56
57        #-------------------------------------------
58        # One possible method of setting scaling factors...
59        maxX, maxY = self.canvas.GetSize()
60
61        # Let's have at least 50 device units margin
62        marginX = 10
63        marginY = 10
64
65        # Add the margin to the graphic size
66        maxX = maxX + (2 * marginX)
67        maxY = maxY + (2 * marginY)
68
69        # Get the size of the DC in pixels
70        (w, h) = dc.GetSizeTuple()
71
72        # Calculate a suitable scaling factor
73        scaleX = float(w) / maxX
74        scaleY = float(h) / maxY
75
76        # Use x or y scaling factor, whichever fits on the DC
77        actualScale = min(scaleX, scaleY)
78
79        # Calculate the position on the DC for centering the graphic
80        posX = (w - (self.canvas.GetSize()[0] * actualScale)) / 2.0
81        posY = (h - (self.canvas.GetSize()[1] * actualScale)) / 2.0
82
83        # Set the scale and origin
84        dc.SetUserScale(actualScale, actualScale)
85        dc.SetDeviceOrigin(int(posX), int(posY))
86
87        #-------------------------------------------
88
89        self.canvas.pdc.DrawToDC(dc)
90
91        # prints a page number on the page
92        # dc.DrawText("Page: %d" % page, marginX/2, maxY-marginY)
93
94        return True
95
96
97class PrintOptions(wx.Object):
98
99    def __init__(self, parent, mapwin):
100        self.mapframe = parent
101        self.mapwin = mapwin
102
103        self.printData = None
104
105    def setup(self):
106        if self.printData:
107            return
108        self.printData = wx.PrintData()
109        self.printData.SetPaperId(wx.PAPER_LETTER)
110        self.printData.SetPrintMode(wx.PRINT_MODE_PRINTER)
111
112    def OnPageSetup(self, event):
113        self.setup()
114        psdd = wx.PageSetupDialogData(self.printData)
115        psdd.CalculatePaperSizeFromId()
116        dlg = wx.PageSetupDialog(self.mapwin, psdd)
117        dlg.ShowModal()
118
119        # this makes a copy of the wx.PrintData instead of just saving
120        # a reference to the one inside the PrintDialogData that will
121        # be destroyed when the dialog is destroyed
122        self.printData = wx.PrintData(dlg.GetPageSetupData().GetPrintData())
123
124        dlg.Destroy()
125
126    def OnPrintPreview(self, event):
127        self.setup()
128        data = wx.PrintDialogData(self.printData)
129        printout = MapPrint(self.mapwin)
130        printout2 = MapPrint(self.mapwin)
131        self.preview = wx.PrintPreview(printout, printout2, data)
132
133        if not self.preview.Ok():
134            wx.MessageBox("There was a problem printing this display\n", wx.OK)
135            return
136
137        pfrm = wx.PreviewFrame(self.preview, self.mapframe, "Print preview")
138
139        pfrm.Initialize()
140        pfrm.SetPosition(self.mapframe.GetPosition())
141        pfrm.SetSize(self.mapframe.GetClientSize())
142        pfrm.Show(True)
143
144    def OnDoPrint(self, event):
145        self.setup()
146        pdd = wx.PrintDialogData(self.printData)
147        # set number of pages/copies
148        pdd.SetToPage(1)
149        printer = wx.Printer(pdd)
150        printout = MapPrint(self.mapwin)
151
152        if not printer.Print(self.mapframe, printout, True):
153            GMessage(_("There was a problem printing.\n"
154                       "Perhaps your current printer is not set correctly?"))
155        else:
156            self.printData = wx.PrintData(
157                printer.GetPrintDialogData().GetPrintData())
158        printout.Destroy()
159