~ubuntu-branches/ubuntu/vivid/frescobaldi/vivid

« back to all changes in this revision

Viewing changes to python/kateshell/fileprinter.py

  • Committer: Package Import Robot
  • Author(s): Ryan Kavanagh
  • Date: 2012-01-03 16:20:11 UTC
  • mfrom: (1.4.1)
  • Revision ID: package-import@ubuntu.com-20120103162011-tsjkwl4sntwmprea
Tags: 2.0.0-1
* New upstream release 
* Drop the following uneeded patches:
  + 01_checkmodules_no_python-kde4_build-dep.diff
  + 02_no_pyc.diff
  + 04_no_binary_lilypond_upgrades.diff
* Needs new dependency python-poppler-qt4
* Update debian/watch for new download path
* Update copyright file with new holders and years

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# This file is part of the Frescobaldi project, http://www.frescobaldi.org/
2
 
#
3
 
# Copyright (c) 2008, 2009, 2010 by Wilbert Berendsen
4
 
#
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.
9
 
#
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.
14
 
#
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.
19
 
 
20
 
from __future__ import unicode_literals
21
 
 
22
 
"""
23
 
Code to print PDF (or PS) files to a QPrinter.
24
 
Based on ideas from Okular's core/fileprinter.cpp.
25
 
"""
26
 
 
27
 
import os
28
 
import shutil
29
 
import subprocess
30
 
from itertools import repeat
31
 
 
32
 
from PyQt4.QtGui import QPrintEngine, QPrinter
33
 
from PyKDE4.kdecore import KShell, KStandardDirs
34
 
 
35
 
 
36
 
# Exceptions:
37
 
class NoPrintCommandFound(Exception):
38
 
    """Raised if no valid print command can be found."""
39
 
    pass
40
 
 
41
 
class CommandNotFound(Exception):
42
 
    """Raised if the command could not be started."""
43
 
    pass
44
 
 
45
 
class CommandFailed(Exception):
46
 
    """Raised if the command could be started but exited with a non-zero
47
 
    return value."""
48
 
 
49
 
def printFiles(fileNames, printer):
50
 
    """Prints a list of files (PS or PDF) via a printer command.
51
 
 
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.
55
 
    
56
 
    """
57
 
    output = printer.outputFileName()
58
 
    if output:
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))
63
 
        if inext == outext:
64
 
            # just copy
65
 
            shutil.copyfile(fileName, output)
66
 
        else:
67
 
            cmd = "pdf2ps" if outext == ".ps" else "ps2pdf"
68
 
            try:
69
 
                ret = subprocess.call([cmd, fileName, output])
70
 
                if ret:
71
 
                    raise CommandFailed(KShell.joinArgs([cmd, fileName, output]), ret)
72
 
            except OSError:
73
 
                raise CommandNotFound(cmd)
74
 
        return
75
 
        
76
 
    # print to a printer
77
 
    
78
 
    cmd = []
79
 
    
80
 
    # Which exe?
81
 
    for exe in "lpr-cups", "lpr.cups", "lpr", "lp":
82
 
        if KStandardDirs.findExe(exe):
83
 
            break
84
 
    else:
85
 
        raise NoPrintCommandFound()
86
 
 
87
 
    cmd.append(exe)
88
 
    
89
 
    # Add the arguments.
90
 
    
91
 
    # printer name
92
 
    if exe == "lp":
93
 
        cmd.append('-d')
94
 
    else:
95
 
        cmd.append('-P')
96
 
    cmd.append(printer.printerName())
97
 
    
98
 
    # helper for adding (Cups) options to the command line
99
 
    def option(s):
100
 
        cmd.append('-o')
101
 
        cmd.append(s)
102
 
    
103
 
    # copies
104
 
    try:
105
 
        copies = printer.actualNumCopies()
106
 
    except AttributeError: # only available in Qt >= 4.6
107
 
        copies = printer.numCopies()
108
 
        
109
 
    if exe == "lp":
110
 
        cmd.append('-n')
111
 
        cmd.append(format(copies))
112
 
    else:
113
 
        cmd.append('-#{0}'.format(copies))
114
 
    
115
 
    # job name
116
 
    if printer.docName():
117
 
        if exe == "lp":
118
 
            cmd.append('-t')
119
 
            cmd.append(printer.docName())
120
 
        elif exe.startswith('lpr'):
121
 
            cmd.append('-J')
122
 
            cmd.append(printer.docName())
123
 
            
124
 
    # page range
125
 
    if printer.printRange() == QPrinter.PageRange:
126
 
        pageRange = "{0}-{1}".format(printer.fromPage(), printer.toPage())
127
 
        if exe == "lp":
128
 
            cmd.append('-P')
129
 
            cmd.append(pageRange)
130
 
        else:
131
 
            option('page-ranges={0}'.format(pageRange))
132
 
    
133
 
    # CUPS-specific options; detect if CUPS is available.
134
 
    test = QPrinter()
135
 
    test.setNumCopies(2)
136
 
    cups = test.numCopies() == 1
137
 
    
138
 
    if cups:
139
 
        
140
 
        # media, size etc.
141
 
        media = []
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])
147
 
        
148
 
        # media source
149
 
        source = printer.paperSource()
150
 
        if source in PAPER_SOURCES:
151
 
            media.append(PAPER_SOURCES[source])
152
 
        
153
 
        if media:
154
 
            option('media={0}'.format(",".join(media)))
155
 
        
156
 
        # orientation
157
 
        orientation = printer.orientation()
158
 
        if orientation in ORIENTATIONS:
159
 
            option(ORIENTATIONS[orientation])
160
 
            
161
 
        # double sided
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")
168
 
            else:
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")
174
 
 
175
 
        # page order
176
 
        if printer.pageOrder() == QPrinter.LastPageFirst:
177
 
            option("outputorder=reverse")
178
 
        else:
179
 
            option("outputorder=normal")
180
 
        
181
 
        # collate copies
182
 
        if printer.collateCopies():
183
 
            option("Collate=True")
184
 
        else:
185
 
            option("Collate=False")
186
 
        
187
 
        # page margins
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))
194
 
            
195
 
        # cups properties
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)
199
 
    
200
 
    # file names
201
 
    cmd.extend(fileNames)
202
 
    try:
203
 
        ret = subprocess.call(cmd)
204
 
        if ret:
205
 
            raise CommandFailed(KShell.joinArgs(cmd), ret)
206
 
    except OSError:
207
 
        raise CommandNotFound(cmd[0])
208
 
    
209
 
 
210
 
PAGE_SIZES = {
211
 
    QPrinter.A0: "A0",
212
 
    QPrinter.A1: "A1",
213
 
    QPrinter.A2: "A2",
214
 
    QPrinter.A3: "A3",
215
 
    QPrinter.A4: "A4",
216
 
    QPrinter.A5: "A5",
217
 
    QPrinter.A6: "A6",
218
 
    QPrinter.A7: "A7",
219
 
    QPrinter.A8: "A8",
220
 
    QPrinter.A9: "A9",
221
 
    QPrinter.B0: "B0",
222
 
    QPrinter.B1: "B1",
223
 
    QPrinter.B10: "B10",
224
 
    QPrinter.B2: "B2",
225
 
    QPrinter.B3: "B3",
226
 
    QPrinter.B4: "B4",
227
 
    QPrinter.B5: "B5",
228
 
    QPrinter.B6: "B6",
229
 
    QPrinter.B7: "B7",
230
 
    QPrinter.B8: "B8",
231
 
    QPrinter.B9: "B9",
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",
241
 
}
242
 
 
243
 
PAPER_SOURCES = {
244
 
    # QPrinter.Auto: "",
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",
258
 
}
259
 
 
260
 
ORIENTATIONS = {
261
 
    QPrinter.Portrait: "portrait",
262
 
    QPrinter.Landscape: "landscape",
263
 
}
264