1
# This file is part of the Frescobaldi project, http://www.frescobaldi.org/
3
# Copyright (c) 2008, 2009, 2010 by Wilbert Berendsen
5
# This program is free software; you can redistribute it and/or
6
# modify it under the terms of the GNU General Public License
7
# as published by the Free Software Foundation; either version 2
8
# of the License, or (at your option) any later version.
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
15
# You should have received a copy of the GNU General Public License
16
# along with this program; if not, write to the Free Software
17
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
# See http://www.gnu.org/licenses/ for more information.
20
from __future__ import unicode_literals
23
Code to print PDF (or PS) files to a QPrinter.
24
Based on ideas from Okular's core/fileprinter.cpp.
30
from itertools import repeat
32
from PyQt4.QtGui import QPrintEngine, QPrinter
33
from PyKDE4.kdecore import KShell, KStandardDirs
37
class NoPrintCommandFound(Exception):
38
"""Raised if no valid print command can be found."""
41
class CommandNotFound(Exception):
42
"""Raised if the command could not be started."""
45
class CommandFailed(Exception):
46
"""Raised if the command could be started but exited with a non-zero
49
def printFiles(fileNames, printer):
50
"""Prints a list of files (PS or PDF) via a printer command.
52
The printer command is constructed by quering the QPrinter object.
53
If there is more than one PDF file, print to file should have been disabled
54
in the QPrintDialog that configured the printer.
57
output = printer.outputFileName()
59
# Print to File, determine suffixes, assume one file
60
fileName = fileNames[0]
61
inext, outext = (os.path.splitext(name)[1].lower()
62
for name in (fileName, output))
65
shutil.copyfile(fileName, output)
67
cmd = "pdf2ps" if outext == ".ps" else "ps2pdf"
69
ret = subprocess.call([cmd, fileName, output])
71
raise CommandFailed(KShell.joinArgs([cmd, fileName, output]), ret)
73
raise CommandNotFound(cmd)
81
for exe in "lpr-cups", "lpr.cups", "lpr", "lp":
82
if KStandardDirs.findExe(exe):
85
raise NoPrintCommandFound()
96
cmd.append(printer.printerName())
98
# helper for adding (Cups) options to the command line
105
copies = printer.actualNumCopies()
106
except AttributeError: # only available in Qt >= 4.6
107
copies = printer.numCopies()
111
cmd.append(format(copies))
113
cmd.append('-#{0}'.format(copies))
116
if printer.docName():
119
cmd.append(printer.docName())
120
elif exe.startswith('lpr'):
122
cmd.append(printer.docName())
125
if printer.printRange() == QPrinter.PageRange:
126
pageRange = "{0}-{1}".format(printer.fromPage(), printer.toPage())
129
cmd.append(pageRange)
131
option('page-ranges={0}'.format(pageRange))
133
# CUPS-specific options; detect if CUPS is available.
136
cups = test.numCopies() == 1
142
size = printer.paperSize()
143
if size == QPrinter.Custom:
144
media.append("Custom.{0}x{1}mm".format(printer.heightMM(), printer.widthMM()))
145
elif size in PAGE_SIZES:
146
media.append(PAGE_SIZES[size])
149
source = printer.paperSource()
150
if source in PAPER_SOURCES:
151
media.append(PAPER_SOURCES[source])
154
option('media={0}'.format(",".join(media)))
157
orientation = printer.orientation()
158
if orientation in ORIENTATIONS:
159
option(ORIENTATIONS[orientation])
162
duplex = printer.duplex()
163
if duplex == QPrinter.DuplexNone:
164
option("sides=one-sided")
165
elif duplex == QPrinter.DuplexAuto:
166
if orientation == QPrinter.Landscape:
167
option("sides=two-sided-short-edge")
169
option("sides=two-sided-long-edge")
170
elif duplex == QPrinter.DuplexLongSide:
171
option("sides=two-sided-long-edge")
172
elif duplex == QPrinter.DuplexShortSide:
173
option("sides=two-sided-short-edge")
176
if printer.pageOrder() == QPrinter.LastPageFirst:
177
option("outputorder=reverse")
179
option("outputorder=normal")
182
if printer.collateCopies():
183
option("Collate=True")
185
option("Collate=False")
188
if printer.printEngine().property(QPrintEngine.PPK_PageMargins):
189
left, top, right, bottom = printer.getPageMargins(QPrinter.Point)
190
option("page-left={0}".format(left))
191
option("page-top={0}".format(top))
192
option("page-right={0}".format(right))
193
option("page-bottom={0}".format(bottom))
196
properties = printer.printEngine().property(QPrintEngine.PrintEnginePropertyKey(0xfe00))
197
for name, value in zip(*repeat(iter(properties), 2)):
198
option("{0}={1}".format(name, value) if value else name)
201
cmd.extend(fileNames)
203
ret = subprocess.call(cmd)
205
raise CommandFailed(KShell.joinArgs(cmd), ret)
207
raise CommandNotFound(cmd[0])
232
QPrinter.C5E: "C5", # Correct Translation?
233
QPrinter.Comm10E: "Comm10", # Correct Translation?
234
QPrinter.DLE: "DL", # Correct Translation?
235
QPrinter.Executive: "Executive",
236
QPrinter.Folio: "Folio",
237
QPrinter.Ledger: "Ledger",
238
QPrinter.Legal: "Legal",
239
QPrinter.Letter: "Letter",
240
QPrinter.Tabloid: "Tabloid",
245
QPrinter.Cassette: "Cassette",
246
QPrinter.Envelope: "Envelope",
247
QPrinter.EnvelopeManual: "EnvelopeManual",
248
QPrinter.FormSource: "FormSource",
249
QPrinter.LargeCapacity: "LargeCapacity",
250
QPrinter.LargeFormat: "LargeFormat",
251
QPrinter.Lower: "Lower",
252
QPrinter.MaxPageSource: "MaxPageSource",
253
QPrinter.Middle: "Middle",
254
QPrinter.Manual: "Manual",
255
QPrinter.OnlyOne: "OnlyOne",
256
QPrinter.Tractor: "Tractor",
257
QPrinter.SmallFormat: "SmallFormat",
261
QPrinter.Portrait: "portrait",
262
QPrinter.Landscape: "landscape",