256 lines
9.0 KiB
Python
256 lines
9.0 KiB
Python
#------------------------------------------------------------------------------
|
|
#
|
|
# PyGUI - Printing - Win32
|
|
#
|
|
#------------------------------------------------------------------------------
|
|
|
|
import WinPageSetup as wps, WinPrint as wp
|
|
import win32print as wp2
|
|
from GUI.GPrinting import PageSetup as GPageSetup, Printable as GPrintable, \
|
|
Paginator
|
|
from GUI import Canvas
|
|
|
|
#------------------------------------------------------------------------------
|
|
|
|
win_paper_names = {
|
|
1: "Letter", # Letter 8 1/2 x 11 in
|
|
2: "Letter Small", # Letter Small 8 1/2 x 11 in
|
|
3: "Tabloid", # Tabloid 11 x 17 in
|
|
4: "Ledger", # Ledger 17 x 11 in
|
|
5: "Legal", # Legal 8 1/2 x 14 in
|
|
6: "Statement", # Statement 5 1/2 x 8 1/2 in
|
|
7: "Executive", # Executive 7 1/4 x 10 1/2 in
|
|
8: "A3", # A3 297 x 420 mm
|
|
9: "A4", # A4 210 x 297 mm
|
|
10: "A4 Small", # A4 Small 210 x 297 mm
|
|
11: "A5", # A5 148 x 210 mm
|
|
12: "B4 (JIS)", # B4 (JIS) 250 x 354
|
|
13: "B5 (JIS)", # B5 (JIS) 182 x 257 mm
|
|
14: "Folio", # Folio 8 1/2 x 13 in
|
|
15: "Quarto", # Quarto 215 x 275 mm
|
|
16: "10x14", # 10x14 in
|
|
17: "11x17", # 11x17 in
|
|
18: "Note", # Note 8 1/2 x 11 in
|
|
19: "Envelope #9", # Envelope #9 3 7/8 x 8 7/8
|
|
20: "Envelope #10", # Envelope #10 4 1/8 x 9 1/2
|
|
21: "Envelope #11", # Envelope #11 4 1/2 x 10 3/8
|
|
22: "Envelope #12", # Envelope #12 4 \276 x 11
|
|
23: "Envelope #14", # Envelope #14 5 x 11 1/2
|
|
24: "C Sheet", # C size sheet
|
|
25: "D Sheet", # D size sheet
|
|
26: "E Sheet", # E size sheet
|
|
27: "Envelope DL", # Envelope DL 110 x 220mm
|
|
28: "Envelope C5", # Envelope C5 162 x 229 mm
|
|
29: "Envelope C3", # Envelope C3 324 x 458 mm
|
|
30: "Envelope C4", # Envelope C4 229 x 324 mm
|
|
31: "Envelope C6", # Envelope C6 114 x 162 mm
|
|
32: "Envelope C65", # Envelope C65 114 x 229 mm
|
|
33: "Envelope B4", # Envelope B4 250 x 353 mm
|
|
34: "Envelope B5", # Envelope B5 176 x 250 mm
|
|
35: "Envelope B6", # Envelope B6 176 x 125 mm
|
|
36: "Envelope", # Envelope 110 x 230 mm
|
|
37: "Envelope Monarch", # Envelope Monarch 3.875 x 7.5 in
|
|
38: "6 3/4 Envelope", # 6 3/4 Envelope 3 5/8 x 6 1/2 in
|
|
39: "US Std Fanfold", # US Std Fanfold 14 7/8 x 11 in
|
|
40: "German Std Fanfold", # German Std Fanfold 8 1/2 x 12 in
|
|
41: "German Legal Fanfold", # German Legal Fanfold 8 1/2 x 13 in
|
|
42: "B4", # B4 (ISO) 250 x 353 mm
|
|
43: "Japanese Postcard", # Japanese Postcard 100 x 148 mm
|
|
44: "9x11", # 9 x 11 in
|
|
45: "10x11", # 10 x 11 in
|
|
46: "15x11", # 15 x 11 in
|
|
47: "Envelope Invite", # Envelope Invite 220 x 220 mm
|
|
#48: "", # RESERVED--DO NOT USE
|
|
#49: "", # RESERVED--DO NOT USE
|
|
50: "Letter Extra", # Letter Extra 9 \275 x 12 in
|
|
51: "Legal Extra", # Legal Extra 9 \275 x 15 in
|
|
52: "Tabloid Extra", # Tabloid Extra 11.69 x 18 in
|
|
53: "A4 Extra", # A4 Extra 9.27 x 12.69 in
|
|
54: "Letter Transverse", # Letter Transverse 8 \275 x 11 in
|
|
55: "A4 Transverse", # A4 Transverse 210 x 297 mm
|
|
56: "Letter Extra Transverse", # Letter Extra Transverse 9\275 x 12 in
|
|
57: "SuperA", # SuperA/SuperA/A4 227 x 356 mm
|
|
58: "SuperB", # SuperB/SuperB/A3 305 x 487 mm
|
|
59: "Letter Plus", # Letter Plus 8.5 x 12.69 in
|
|
60: "A4 Plus", # A4 Plus 210 x 330 mm
|
|
61: "A5 Transverse", # A5 Transverse 148 x 210 mm
|
|
62: "B5 (JIS) Transverse", # B5 (JIS) Transverse 182 x 257 mm
|
|
63: "A3 Extra", # A3 Extra 322 x 445 mm
|
|
64: "A5 Extra", # A5 Extra 174 x 235 mm
|
|
65: "B5 (ISO) Extra", # B5 (ISO) Extra 201 x 276 mm
|
|
66: "A2", # A2 420 x 594 mm
|
|
67: "A3 Transverse", # A3 Transverse 297 x 420 mm
|
|
68: "A3 Extra Transverse", # A3 Extra Transverse 322 x 445 mm
|
|
}
|
|
|
|
win_paper_codes = dict([(name, code)
|
|
for (code, name) in win_paper_names.iteritems()])
|
|
|
|
def ti_to_pts(x):
|
|
return x * 0.072
|
|
|
|
def pts_to_ti(x):
|
|
return int(round(x / 0.072))
|
|
|
|
#------------------------------------------------------------------------------
|
|
|
|
class PageSetup(GPageSetup):
|
|
|
|
def __new__(cls):
|
|
self = GPageSetup.__new__(cls)
|
|
self._win_psd = wps.get_defaults()
|
|
return self
|
|
|
|
def __init__(self):
|
|
self.margins = (36, 36, 36, 36)
|
|
|
|
def __getstate__(self):
|
|
psd = self._win_psd
|
|
state = GPageSetup.__getstate__(self)
|
|
state['_win_devmode'] = wps.get_handle_contents(psd.hDevMode)
|
|
state['_win_devnames'] = wps.get_handle_contents(psd.hDevNames)
|
|
return state
|
|
|
|
def __setstate__(self, state):
|
|
psd = self._win_psd
|
|
dm = state.pop('_win_devmode', None)
|
|
dn = state.pop('_win_devnames', None)
|
|
GPageSetup.__setstate__(self, state)
|
|
if dm:
|
|
wps.GlobalFree(psd.hDevMode)
|
|
psd.hDevMode = handle_with_contents(dm)
|
|
if dn:
|
|
wps.GlobalFree(psd.hDevNames)
|
|
psd.hDevNames = handle_with_contents(dn)
|
|
|
|
def _win_lock_devmode(self):
|
|
return wps.lock_devmode_handle(self._win_psd.hDevMode)
|
|
|
|
def _win_unlock_devmode(self):
|
|
wps.GlobalUnlock(self._win_psd.hDevMode)
|
|
|
|
def get_printable_rect(self):
|
|
psd = self._win_psd
|
|
pw, ph = self.paper_size
|
|
mm = psd.rtMinMargin
|
|
ml = ti_to_pts(mm.left)
|
|
mt = ti_to_pts(mm.top)
|
|
mr = ti_to_pts(mm.right)
|
|
mb = ti_to_pts(mm.bottom)
|
|
return (ml, mt, pw - mr, ph - mb)
|
|
|
|
def get_paper_name(self):
|
|
dm = self._win_lock_devmode()
|
|
result = win_paper_names.get(dm.dmPaperSize, "Custom")
|
|
self._win_unlock_devmode()
|
|
return result
|
|
|
|
def set_paper_name(self, name):
|
|
dm = self._win_lock_devmode()
|
|
dm.dmPaperSize = win_paper_codes.get(name, 0)
|
|
self._win_unlock_devmode()
|
|
|
|
def get_paper_width(self):
|
|
return ti_to_pts(self._win_psd.ptPaperSize.x)
|
|
|
|
def get_paper_height(self):
|
|
return ti_to_pts(self._win_psd.ptPaperSize.y)
|
|
|
|
def set_paper_width(self, v):
|
|
self._win_psd.ptPaperSize.x = pts_to_ti(v)
|
|
|
|
def set_paper_height(self, v):
|
|
self._win_psd.ptPaperSize.y = pts_to_ti(v)
|
|
|
|
def get_left_margin(self):
|
|
return ti_to_pts(self._win_psd.rtMargin.left)
|
|
|
|
def get_top_margin(self):
|
|
return ti_to_pts(self._win_psd.rtMargin.top)
|
|
|
|
def get_right_margin(self):
|
|
return ti_to_pts(self._win_psd.rtMargin.right)
|
|
|
|
def get_bottom_margin(self):
|
|
return ti_to_pts(self._win_psd.rtMargin.bottom)
|
|
|
|
def set_left_margin(self, v):
|
|
self._win_psd.rtMargin.left = pts_to_ti(v)
|
|
|
|
def set_top_margin(self, v):
|
|
self._win_psd.rtMargin.top = pts_to_ti(v)
|
|
|
|
def set_right_margin(self, v):
|
|
self._win_psd.rtMargin.right = pts_to_ti(v)
|
|
|
|
def set_bottom_margin(self, v):
|
|
self._win_psd.rtMargin.bottom = pts_to_ti(v)
|
|
|
|
def get_orientation(self):
|
|
dm = self._win_lock_devmode()
|
|
result = win_orientation_names.get(dm.dmOrientation, 'portrait')
|
|
self._win_unlock_devmode()
|
|
return result
|
|
|
|
def set_orientation(self, v):
|
|
dm = self._win_lock_devmode()
|
|
dm.dmOrientation = win_orientation_codes.get(v, 1)
|
|
self._win_unlock_devmode()
|
|
|
|
def get_printer_name(self):
|
|
dm = self._win_lock_devmode()
|
|
result = dm.dmDeviceName
|
|
self._win_unlock_devmode()
|
|
return result
|
|
|
|
def set_printer_name(self, v):
|
|
dm = self._win_lock_devmode()
|
|
dm.dmDeviceName = v
|
|
self._win_unlock_devmode()
|
|
|
|
#------------------------------------------------------------------------------
|
|
|
|
class Printable(GPrintable):
|
|
|
|
def print_view(self, page_setup, prompt = True):
|
|
paginator = Paginator(self, page_setup)
|
|
psd = page_setup._win_psd
|
|
pd = wp.PRINTDLG()
|
|
pd.hDevMode = psd.hDevMode
|
|
pd.hDevNames = psd.hDevNames
|
|
pd.nMinPage = 1
|
|
pd.nMaxPage = paginator.num_pages
|
|
pd.nCopies = 1
|
|
if wp.PrintDlg(pd):
|
|
title = self.print_title
|
|
di = wp.DOCINFO()
|
|
di.lpszDocName = title
|
|
devnames = wps.DevNames(psd.hDevNames)
|
|
if devnames.output == "FILE:":
|
|
from FileDialogs import request_new_file
|
|
f = request_new_file("Print '%s' to file:" % title)
|
|
if not f:
|
|
return
|
|
output_path = f.path
|
|
di.lpszOutput = output_path
|
|
try:
|
|
hdc = pd.hDC
|
|
dx, dy = wp.GetPrintingOffset(hdc)
|
|
print "TODO: Printable: Implement a Cancel dialog" ###
|
|
#wp.install_abort_proc(hdc)
|
|
wp.StartDoc(hdc, di)
|
|
for page_num in xrange(pd.nFromPage - 1, pd.nToPage):
|
|
wp.StartPage(hdc)
|
|
canvas = Canvas._from_win_hdc(hdc, for_printing = True)
|
|
canvas.translate(-dx, -dy)
|
|
paginator.draw_page(canvas, page_num)
|
|
wp.EndPage(hdc)
|
|
wp.EndDoc(hdc)
|
|
finally:
|
|
wp.DeleteDC(hdc)
|
|
|
|
#------------------------------------------------------------------------------
|
|
|
|
def present_page_setup_dialog(page_setup):
|
|
return wps.PageSetupDlg(page_setup._win_psd)
|