Initial commit
BIN
book-g19ab6d77a_640.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
pdfbooklet.xcf
Normal file
BIN
pdfbooklet_3.1.2-3_all.deb
Normal file
10
pdfbooklet_3.1.2-3_all/DEBIAN/control
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Package: pdfbooklet
|
||||||
|
Version: 3.1.2-3
|
||||||
|
Architecture: all
|
||||||
|
Maintainer: Travis CI User <travis@travis-job-15a6ca42-09e1-42ff-b563-bc763a340a91>
|
||||||
|
Installed-Size: 5214
|
||||||
|
Depends: python3 (>= 3.4), python3-gi, python3-gi-cairo, python3-cairo, gir1.2-gtk-3.0, gir1.2-poppler-0.18
|
||||||
|
Section: alien
|
||||||
|
Priority: extra
|
||||||
|
Description: Make booklets from pdfs.
|
||||||
|
Converted by ken (https://git.kjodle.net)
|
56
pdfbooklet_3.1.2-3_all/md5sums
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
ba56c5487eb08c12bb4a9b3e6a473ad5 postinst
|
||||||
|
52eff264dbe1c88e4cdae0e226a01f18 usr/bin/pdfbooklet
|
||||||
|
906b5b82769c2aa6670ad40ecde27913 usr/lib/python3/dist-packages/pdfbooklet-3.1.2-py3.5.egg-info
|
||||||
|
7c08f7a7b39e2ff0b9ec7ad59ab1b722 usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/__init__.py
|
||||||
|
bee924498685db3fa219dfc099933039 usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/__pycache__/__init__.cpython-35.pyc
|
||||||
|
daec93ab0b71a886408c2271f569d69b usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/__pycache__/_version.cpython-35.pyc
|
||||||
|
399edd643a7ebe5705761d266f89a39e usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/__pycache__/filters.cpython-35.pyc
|
||||||
|
c341762928903c2ea146bab0a98222bc usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/__pycache__/generic.cpython-35.pyc
|
||||||
|
7bcd7e5070ea7cfb0b1a1fcbd2ba4a0c usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/__pycache__/merger.cpython-35.pyc
|
||||||
|
2ff2f3bbfe9960d891ee5297d99bc18f usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/__pycache__/pagerange.cpython-35.pyc
|
||||||
|
10eeae6883876bf6d1e494fb48480d78 usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/__pycache__/pdf.cpython-35.pyc
|
||||||
|
60f85ad15bc9787fe4d9cd20dd9fcaab usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/__pycache__/utils.cpython-35.pyc
|
||||||
|
362b7ed03b0f0f02bb241cc3a5cab13e usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/__pycache__/xmp.cpython-35.pyc
|
||||||
|
7d0617c19300e959eced5ea961d7b603 usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/_version.py
|
||||||
|
3d42cf9a67139de17946475432e93a34 usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/filters.py
|
||||||
|
503d65931c283b5d3ccd52f88a365476 usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/generic.py
|
||||||
|
38408394fbf7442d4ece6d17ff6433cf usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/merger.py
|
||||||
|
a74524899783ee4b56529d0287c3d5f6 usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/pagerange.py
|
||||||
|
e6998315652813e37c44627569cd15b2 usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/pdf.py
|
||||||
|
383614f6ba70f7d5cf9ed5496c201907 usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/utils.py
|
||||||
|
e6379c525ae88b173e7b3a757e2c3063 usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/xmp.py
|
||||||
|
d41d8cd98f00b204e9800998ecf8427e usr/lib/python3/dist-packages/pdfbooklet/__init__.py
|
||||||
|
3b3d4b3ad68d0b42baa9405ffab42e37 usr/lib/python3/dist-packages/pdfbooklet/__pycache__/__init__.cpython-35.pyc
|
||||||
|
a427643aa93316c1407cbfd1327d146e usr/lib/python3/dist-packages/pdfbooklet/__pycache__/elib_intl3.cpython-35.pyc
|
||||||
|
b2a93dc73d6f8e522c9ef5aa410846ed usr/lib/python3/dist-packages/pdfbooklet/__pycache__/files_chooser.cpython-35.pyc
|
||||||
|
856537a63a5a9fd96af18dece31c782e usr/lib/python3/dist-packages/pdfbooklet/__pycache__/pdfbooklet.cpython-35.pyc
|
||||||
|
7bdc8cd69d4848eb87801f4cd1c6d53d usr/lib/python3/dist-packages/pdfbooklet/__pycache__/pdfshuffler_g3.cpython-35.pyc
|
||||||
|
f65a8a722149a8f678c3ef49a48444b3 usr/lib/python3/dist-packages/pdfbooklet/__pycache__/pdfshuffler_iconview3.cpython-35.pyc
|
||||||
|
16d5f3a8ea1c233c81ef7b30127bc310 usr/lib/python3/dist-packages/pdfbooklet/elib_intl3.py
|
||||||
|
7262bce50b0bd5db96c298743f519b6f usr/lib/python3/dist-packages/pdfbooklet/files_chooser.py
|
||||||
|
4560e948c3a9c0ba561156c89222afe9 usr/lib/python3/dist-packages/pdfbooklet/pdfbooklet.py
|
||||||
|
85ff4690d95bcf0bc5dc88dc4518edee usr/lib/python3/dist-packages/pdfbooklet/pdfshuffler_g3.py
|
||||||
|
b18a190a171e1ae57118620f27773a26 usr/lib/python3/dist-packages/pdfbooklet/pdfshuffler_iconview3.py
|
||||||
|
f2a9808fe8ae4e932d6c471cf6326cb6 usr/share/applications/pdfbooklet.desktop
|
||||||
|
1e65a1a059a7ba375e144e57bafe0e03 usr/share/doc/pdfbooklet/changelog.Debian.gz
|
||||||
|
8c836ce2f8e3261dbabc7592a7cc9b6f usr/share/doc/pdfbooklet/copyright
|
||||||
|
5495e0fdf28e395bf3229069a7c5e1af usr/share/locale/fr/LC_MESSAGES/pdfbooklet.mo
|
||||||
|
b67b9bb1ea5b769203c3e73d9ecc4771 usr/share/locale/fr/LC_MESSAGES/pdfbooklet.po
|
||||||
|
97fc5e114afab69b2dda1d9ed27732d5 usr/share/locale/fr/LC_MESSAGES/pdfshuffler.mo
|
||||||
|
0bcfbf4a7a4e98c1dbd520fcc04ad342 usr/share/locale/fr/LC_MESSAGES/pdfshuffler.po
|
||||||
|
c3bc3ac07fa1d1c6f6c95e3e9d039908 usr/share/pdfbooklet/data/chooser_dialog.glade
|
||||||
|
84ff01d09458dc41a43edbc175896dd5 usr/share/pdfbooklet/data/nofile.pdf
|
||||||
|
f2a9808fe8ae4e932d6c471cf6326cb6 usr/share/pdfbooklet/data/pdfbooklet.desktop
|
||||||
|
7ba7a6336c65f32291fa2f4f1780dd44 usr/share/pdfbooklet/data/pdfbooklet.ico
|
||||||
|
ff8b8bd0473cff3b5f2e67f087674a95 usr/share/pdfbooklet/data/pdfbooklet.png
|
||||||
|
36aaf7de5c575a414bad40039dffbd5d usr/share/pdfbooklet/data/pdfbooklet.svg
|
||||||
|
7206b41ae6a12a3e60a66255f309d3a0 usr/share/pdfbooklet/data/pdfbooklet3.glade
|
||||||
|
22cc082abf6cc863fe0575fc574bac0f usr/share/pdfbooklet/data/pdfshuffler.ico
|
||||||
|
c101a33982b86a5e4deb7b49bd6a2252 usr/share/pdfbooklet/data/pdfshuffler64.ico
|
||||||
|
e08557a923bdc9dc3cb374ee36110a5d usr/share/pdfbooklet/data/pdfshuffler64.png
|
||||||
|
1d1da34644d20ead9325f6bbf6f2d9dd usr/share/pdfbooklet/data/pdfshuffler_g.glade
|
||||||
|
3242edc53175c4d9930b8f96529514c1 usr/share/pdfbooklet/documentation/Manuel_de_Pdf-Booklet.pdf
|
||||||
|
7c1c11d075a5ac583700a173ca40f589 usr/share/pdfbooklet/documentation/Note_for_Linux_users_3.0.6.html
|
||||||
|
09a1b8a9c361be1c84b5863d63344e3b usr/share/pdfbooklet/documentation/Pdf-Booklet_User's_Guide.pdf
|
||||||
|
36aaf7de5c575a414bad40039dffbd5d usr/share/pdfbooklet/icons/hicolor/scalable/pdfbooklet.svg
|
||||||
|
ff8b8bd0473cff3b5f2e67f087674a95 usr/share/pixmaps/pdfbooklet.png
|
1
pdfbooklet_3.1.2-3_all/postinst
Executable file
@ -0,0 +1 @@
|
|||||||
|
chmod 777 ./usr/share/pdfbooklet/
|
33
pdfbooklet_3.1.2-3_all/usr/bin/pdfbooklet
Executable file
@ -0,0 +1,33 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
PdfBooklet 2.2.2 - GTK+ based utility for creating booklets
|
||||||
|
and other layouts from PDF documents.
|
||||||
|
<https://sourceforge.net/projects/pdfbooklet>
|
||||||
|
|
||||||
|
This file is part of PdfBooklet.
|
||||||
|
|
||||||
|
PdfBooklet is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
from pdfbooklet.pdfbooklet import main
|
||||||
|
main()
|
||||||
|
except ImportError as e:
|
||||||
|
print('Error: Could not import pdfbooklet')
|
||||||
|
print('Cause: %s' % e)
|
@ -0,0 +1,10 @@
|
|||||||
|
Metadata-Version: 1.0
|
||||||
|
Name: pdfbooklet
|
||||||
|
Version: 3.1.2
|
||||||
|
Summary: A simple application for creating booklets and other layouts from PDF files
|
||||||
|
Home-page: https://sourceforge.net/projects/pdfbooklet
|
||||||
|
Author: GAF Software
|
||||||
|
Author-email: Averell7 at sourceforge dot net
|
||||||
|
License: GNU GPL-3
|
||||||
|
Description: UNKNOWN
|
||||||
|
Platform: UNKNOWN
|
@ -0,0 +1,5 @@
|
|||||||
|
from .pdf import PdfFileReader, PdfFileWriter
|
||||||
|
from .merger import PdfFileMerger
|
||||||
|
from .pagerange import PageRange, parse_filename_page_ranges
|
||||||
|
from ._version import __version__
|
||||||
|
__all__ = ["pdf", "PdfFileMerger"]
|
@ -0,0 +1 @@
|
|||||||
|
__version__ = '1.25.1'
|
@ -0,0 +1,362 @@
|
|||||||
|
# vim: sw=4:expandtab:foldmethod=marker
|
||||||
|
#
|
||||||
|
# Copyright (c) 2006, Mathieu Fenniak
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are
|
||||||
|
# met:
|
||||||
|
#
|
||||||
|
# * Redistributions of source code must retain the above copyright notice,
|
||||||
|
# this list of conditions and the following disclaimer.
|
||||||
|
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
# this list of conditions and the following disclaimer in the documentation
|
||||||
|
# and/or other materials provided with the distribution.
|
||||||
|
# * The name of the author may not be used to endorse or promote products
|
||||||
|
# derived from this software without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
Implementation of stream filters for PDF.
|
||||||
|
"""
|
||||||
|
__author__ = "Mathieu Fenniak"
|
||||||
|
__author_email__ = "biziqe@mathieu.fenniak.net"
|
||||||
|
|
||||||
|
from .utils import PdfReadError, ord_, chr_
|
||||||
|
from sys import version_info
|
||||||
|
if version_info < ( 3, 0 ):
|
||||||
|
from cStringIO import StringIO
|
||||||
|
else:
|
||||||
|
from io import StringIO
|
||||||
|
import struct
|
||||||
|
|
||||||
|
try:
|
||||||
|
import zlib
|
||||||
|
|
||||||
|
def decompress(data):
|
||||||
|
return zlib.decompress(data)
|
||||||
|
|
||||||
|
def compress(data):
|
||||||
|
return zlib.compress(data)
|
||||||
|
|
||||||
|
except ImportError:
|
||||||
|
# Unable to import zlib. Attempt to use the System.IO.Compression
|
||||||
|
# library from the .NET framework. (IronPython only)
|
||||||
|
import System
|
||||||
|
from System import IO, Collections, Array
|
||||||
|
|
||||||
|
def _string_to_bytearr(buf):
|
||||||
|
retval = Array.CreateInstance(System.Byte, len(buf))
|
||||||
|
for i in range(len(buf)):
|
||||||
|
retval[i] = ord(buf[i])
|
||||||
|
return retval
|
||||||
|
|
||||||
|
def _bytearr_to_string(bytes):
|
||||||
|
retval = ""
|
||||||
|
for i in range(bytes.Length):
|
||||||
|
retval += chr(bytes[i])
|
||||||
|
return retval
|
||||||
|
|
||||||
|
def _read_bytes(stream):
|
||||||
|
ms = IO.MemoryStream()
|
||||||
|
buf = Array.CreateInstance(System.Byte, 2048)
|
||||||
|
while True:
|
||||||
|
bytes = stream.Read(buf, 0, buf.Length)
|
||||||
|
if bytes == 0:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
ms.Write(buf, 0, bytes)
|
||||||
|
retval = ms.ToArray()
|
||||||
|
ms.Close()
|
||||||
|
return retval
|
||||||
|
|
||||||
|
def decompress(data):
|
||||||
|
bytes = _string_to_bytearr(data)
|
||||||
|
ms = IO.MemoryStream()
|
||||||
|
ms.Write(bytes, 0, bytes.Length)
|
||||||
|
ms.Position = 0 # fseek 0
|
||||||
|
gz = IO.Compression.DeflateStream(ms, IO.Compression.CompressionMode.Decompress)
|
||||||
|
bytes = _read_bytes(gz)
|
||||||
|
retval = _bytearr_to_string(bytes)
|
||||||
|
gz.Close()
|
||||||
|
return retval
|
||||||
|
|
||||||
|
def compress(data):
|
||||||
|
bytes = _string_to_bytearr(data)
|
||||||
|
ms = IO.MemoryStream()
|
||||||
|
gz = IO.Compression.DeflateStream(ms, IO.Compression.CompressionMode.Compress, True)
|
||||||
|
gz.Write(bytes, 0, bytes.Length)
|
||||||
|
gz.Close()
|
||||||
|
ms.Position = 0 # fseek 0
|
||||||
|
bytes = ms.ToArray()
|
||||||
|
retval = _bytearr_to_string(bytes)
|
||||||
|
ms.Close()
|
||||||
|
return retval
|
||||||
|
|
||||||
|
|
||||||
|
class FlateDecode(object):
|
||||||
|
def decode(data, decodeParms):
|
||||||
|
data = decompress(data)
|
||||||
|
predictor = 1
|
||||||
|
if decodeParms:
|
||||||
|
try:
|
||||||
|
predictor = decodeParms.get("/Predictor", 1)
|
||||||
|
except AttributeError:
|
||||||
|
pass # usually an array with a null object was read
|
||||||
|
|
||||||
|
# predictor 1 == no predictor
|
||||||
|
if predictor != 1:
|
||||||
|
columns = decodeParms["/Columns"]
|
||||||
|
# PNG prediction:
|
||||||
|
if predictor >= 10 and predictor <= 15:
|
||||||
|
output = StringIO()
|
||||||
|
# PNG prediction can vary from row to row
|
||||||
|
rowlength = columns + 1
|
||||||
|
assert len(data) % rowlength == 0
|
||||||
|
prev_rowdata = (0,) * rowlength
|
||||||
|
for row in range(len(data) // rowlength):
|
||||||
|
rowdata = [ord_(x) for x in data[(row*rowlength):((row+1)*rowlength)]]
|
||||||
|
filterByte = rowdata[0]
|
||||||
|
if filterByte == 0:
|
||||||
|
pass
|
||||||
|
elif filterByte == 1:
|
||||||
|
for i in range(2, rowlength):
|
||||||
|
rowdata[i] = (rowdata[i] + rowdata[i-1]) % 256
|
||||||
|
elif filterByte == 2:
|
||||||
|
for i in range(1, rowlength):
|
||||||
|
rowdata[i] = (rowdata[i] + prev_rowdata[i]) % 256
|
||||||
|
else:
|
||||||
|
# unsupported PNG filter
|
||||||
|
raise PdfReadError("Unsupported PNG filter %r" % filterByte)
|
||||||
|
prev_rowdata = rowdata
|
||||||
|
output.write(''.join([chr(x) for x in rowdata[1:]]))
|
||||||
|
data = output.getvalue()
|
||||||
|
else:
|
||||||
|
# unsupported predictor
|
||||||
|
raise PdfReadError("Unsupported flatedecode predictor %r" % predictor)
|
||||||
|
return data
|
||||||
|
decode = staticmethod(decode)
|
||||||
|
|
||||||
|
def encode(data):
|
||||||
|
return compress(data)
|
||||||
|
encode = staticmethod(encode)
|
||||||
|
|
||||||
|
|
||||||
|
class ASCIIHexDecode(object):
|
||||||
|
def decode(data, decodeParms=None):
|
||||||
|
retval = ""
|
||||||
|
char = ""
|
||||||
|
x = 0
|
||||||
|
while True:
|
||||||
|
c = data[x]
|
||||||
|
if c == ">":
|
||||||
|
break
|
||||||
|
elif c.isspace():
|
||||||
|
x += 1
|
||||||
|
continue
|
||||||
|
char += c
|
||||||
|
if len(char) == 2:
|
||||||
|
retval += chr(int(char, base=16))
|
||||||
|
char = ""
|
||||||
|
x += 1
|
||||||
|
assert char == ""
|
||||||
|
return retval
|
||||||
|
decode = staticmethod(decode)
|
||||||
|
|
||||||
|
|
||||||
|
class LZWDecode(object):
|
||||||
|
"""Taken from:
|
||||||
|
http://www.java2s.com/Open-Source/Java-Document/PDF/PDF-Renderer/com/sun/pdfview/decode/LZWDecode.java.htm
|
||||||
|
"""
|
||||||
|
class decoder(object):
|
||||||
|
def __init__(self, data):
|
||||||
|
self.STOP=257
|
||||||
|
self.CLEARDICT=256
|
||||||
|
self.data=data
|
||||||
|
self.bytepos=0
|
||||||
|
self.bitpos=0
|
||||||
|
self.dict=[""]*4096
|
||||||
|
for i in range(256):
|
||||||
|
self.dict[i]=chr(i)
|
||||||
|
self.resetDict()
|
||||||
|
|
||||||
|
def resetDict(self):
|
||||||
|
self.dictlen=258
|
||||||
|
self.bitspercode=9
|
||||||
|
|
||||||
|
def nextCode(self):
|
||||||
|
fillbits=self.bitspercode
|
||||||
|
value=0
|
||||||
|
while fillbits>0 :
|
||||||
|
if self.bytepos >= len(self.data):
|
||||||
|
return -1
|
||||||
|
nextbits=ord(self.data[self.bytepos])
|
||||||
|
bitsfromhere=8-self.bitpos
|
||||||
|
if bitsfromhere>fillbits:
|
||||||
|
bitsfromhere=fillbits
|
||||||
|
value |= (((nextbits >> (8-self.bitpos-bitsfromhere)) &
|
||||||
|
(0xff >> (8-bitsfromhere))) <<
|
||||||
|
(fillbits-bitsfromhere))
|
||||||
|
fillbits -= bitsfromhere
|
||||||
|
self.bitpos += bitsfromhere
|
||||||
|
if self.bitpos >=8:
|
||||||
|
self.bitpos=0
|
||||||
|
self.bytepos = self.bytepos+1
|
||||||
|
return value
|
||||||
|
|
||||||
|
def decode(self):
|
||||||
|
""" algorithm derived from:
|
||||||
|
http://www.rasip.fer.hr/research/compress/algorithms/fund/lz/lzw.html
|
||||||
|
and the PDFReference
|
||||||
|
"""
|
||||||
|
cW = self.CLEARDICT;
|
||||||
|
baos=""
|
||||||
|
while True:
|
||||||
|
pW = cW;
|
||||||
|
cW = self.nextCode();
|
||||||
|
if cW == -1:
|
||||||
|
raise PdfReadError("Missed the stop code in LZWDecode!")
|
||||||
|
if cW == self.STOP:
|
||||||
|
break;
|
||||||
|
elif cW == self.CLEARDICT:
|
||||||
|
self.resetDict();
|
||||||
|
elif pW == self.CLEARDICT:
|
||||||
|
baos+=self.dict[cW]
|
||||||
|
else:
|
||||||
|
if cW < self.dictlen:
|
||||||
|
baos += self.dict[cW]
|
||||||
|
p=self.dict[pW]+self.dict[cW][0]
|
||||||
|
self.dict[self.dictlen]=p
|
||||||
|
self.dictlen+=1
|
||||||
|
else:
|
||||||
|
p=self.dict[pW]+self.dict[pW][0]
|
||||||
|
baos+=p
|
||||||
|
self.dict[self.dictlen] = p;
|
||||||
|
self.dictlen+=1
|
||||||
|
if (self.dictlen >= (1 << self.bitspercode) - 1 and
|
||||||
|
self.bitspercode < 12):
|
||||||
|
self.bitspercode+=1
|
||||||
|
return baos
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def decode(data,decodeParams=None):
|
||||||
|
return LZWDecode.decoder(data).decode()
|
||||||
|
|
||||||
|
|
||||||
|
class ASCII85Decode(object):
|
||||||
|
def decode(data, decodeParms=None):
|
||||||
|
if version_info < ( 3, 0 ):
|
||||||
|
retval = ""
|
||||||
|
group = []
|
||||||
|
x = 0
|
||||||
|
hitEod = False
|
||||||
|
# remove all whitespace from data
|
||||||
|
data = [y for y in data if not (y in ' \n\r\t')]
|
||||||
|
while not hitEod:
|
||||||
|
c = data[x]
|
||||||
|
if len(retval) == 0 and c == "<" and data[x+1] == "~":
|
||||||
|
x += 2
|
||||||
|
continue
|
||||||
|
#elif c.isspace():
|
||||||
|
# x += 1
|
||||||
|
# continue
|
||||||
|
elif c == 'z':
|
||||||
|
assert len(group) == 0
|
||||||
|
retval += '\x00\x00\x00\x00'
|
||||||
|
x += 1
|
||||||
|
continue
|
||||||
|
elif c == "~" and data[x+1] == ">":
|
||||||
|
if len(group) != 0:
|
||||||
|
# cannot have a final group of just 1 char
|
||||||
|
assert len(group) > 1
|
||||||
|
cnt = len(group) - 1
|
||||||
|
group += [ 85, 85, 85 ]
|
||||||
|
hitEod = cnt
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
c = ord(c) - 33
|
||||||
|
assert c >= 0 and c < 85
|
||||||
|
group += [ c ]
|
||||||
|
if len(group) >= 5:
|
||||||
|
b = group[0] * (85**4) + \
|
||||||
|
group[1] * (85**3) + \
|
||||||
|
group[2] * (85**2) + \
|
||||||
|
group[3] * 85 + \
|
||||||
|
group[4]
|
||||||
|
assert b < (2**32 - 1)
|
||||||
|
c4 = chr((b >> 0) % 256)
|
||||||
|
c3 = chr((b >> 8) % 256)
|
||||||
|
c2 = chr((b >> 16) % 256)
|
||||||
|
c1 = chr(b >> 24)
|
||||||
|
retval += (c1 + c2 + c3 + c4)
|
||||||
|
if hitEod:
|
||||||
|
retval = retval[:-4+hitEod]
|
||||||
|
group = []
|
||||||
|
x += 1
|
||||||
|
return retval
|
||||||
|
else:
|
||||||
|
if isinstance(data, str):
|
||||||
|
data = data.encode('ascii')
|
||||||
|
n = b = 0
|
||||||
|
out = bytearray()
|
||||||
|
for c in data:
|
||||||
|
if ord('!') <= c and c <= ord('u'):
|
||||||
|
n += 1
|
||||||
|
b = b*85+(c-33)
|
||||||
|
if n == 5:
|
||||||
|
out += struct.pack(b'>L',b)
|
||||||
|
n = b = 0
|
||||||
|
elif c == ord('z'):
|
||||||
|
assert n == 0
|
||||||
|
out += b'\0\0\0\0'
|
||||||
|
elif c == ord('~'):
|
||||||
|
if n:
|
||||||
|
for _ in range(5-n):
|
||||||
|
b = b*85+84
|
||||||
|
out += struct.pack(b'>L',b)[:n-1]
|
||||||
|
break
|
||||||
|
return bytes(out)
|
||||||
|
decode = staticmethod(decode)
|
||||||
|
|
||||||
|
|
||||||
|
def decodeStreamData(stream):
|
||||||
|
from .generic import NameObject
|
||||||
|
filters = stream.get("/Filter", ())
|
||||||
|
if len(filters) and not isinstance(filters[0], NameObject):
|
||||||
|
# we have a single filter instance
|
||||||
|
filters = (filters,)
|
||||||
|
data = stream._data
|
||||||
|
# If there is not data to decode we should not try to decode the data.
|
||||||
|
if data:
|
||||||
|
for filterType in filters:
|
||||||
|
if filterType == "/FlateDecode" or filterType == "/Fl":
|
||||||
|
data = FlateDecode.decode(data, stream.get("/DecodeParms"))
|
||||||
|
elif filterType == "/ASCIIHexDecode" or filterType == "/AHx":
|
||||||
|
data = ASCIIHexDecode.decode(data)
|
||||||
|
elif filterType == "/LZWDecode" or filterType == "/LZW":
|
||||||
|
data = LZWDecode.decode(data, stream.get("/DecodeParms"))
|
||||||
|
elif filterType == "/ASCII85Decode" or filterType == "/A85":
|
||||||
|
data = ASCII85Decode.decode(data)
|
||||||
|
elif filterType == "/Crypt":
|
||||||
|
decodeParams = stream.get("/DecodeParams", {})
|
||||||
|
if "/Name" not in decodeParams and "/Type" not in decodeParams:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
raise NotImplementedError("/Crypt filter with /Name or /Type not supported yet")
|
||||||
|
else:
|
||||||
|
# unsupported filter
|
||||||
|
raise NotImplementedError("unsupported filter %s" % filterType)
|
||||||
|
return data
|
@ -0,0 +1,553 @@
|
|||||||
|
# vim: sw=4:expandtab:foldmethod=marker
|
||||||
|
#
|
||||||
|
# Copyright (c) 2006, Mathieu Fenniak
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are
|
||||||
|
# met:
|
||||||
|
#
|
||||||
|
# * Redistributions of source code must retain the above copyright notice,
|
||||||
|
# this list of conditions and the following disclaimer.
|
||||||
|
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
# this list of conditions and the following disclaimer in the documentation
|
||||||
|
# and/or other materials provided with the distribution.
|
||||||
|
# * The name of the author may not be used to endorse or promote products
|
||||||
|
# derived from this software without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
from .generic import *
|
||||||
|
from .utils import isString, str_
|
||||||
|
from .pdf import PdfFileReader, PdfFileWriter
|
||||||
|
from .pagerange import PageRange
|
||||||
|
from sys import version_info
|
||||||
|
if version_info < ( 3, 0 ):
|
||||||
|
from cStringIO import StringIO
|
||||||
|
StreamIO = StringIO
|
||||||
|
else:
|
||||||
|
from io import BytesIO
|
||||||
|
from io import FileIO as file
|
||||||
|
StreamIO = BytesIO
|
||||||
|
|
||||||
|
|
||||||
|
class _MergedPage(object):
|
||||||
|
"""
|
||||||
|
_MergedPage is used internally by PdfFileMerger to collect necessary
|
||||||
|
information on each page that is being merged.
|
||||||
|
"""
|
||||||
|
def __init__(self, pagedata, src, id):
|
||||||
|
self.src = src
|
||||||
|
self.pagedata = pagedata
|
||||||
|
self.out_pagedata = None
|
||||||
|
self.id = id
|
||||||
|
|
||||||
|
|
||||||
|
class PdfFileMerger(object):
|
||||||
|
"""
|
||||||
|
Initializes a PdfFileMerger object. PdfFileMerger merges multiple PDFs
|
||||||
|
into a single PDF. It can concatenate, slice, insert, or any combination
|
||||||
|
of the above.
|
||||||
|
|
||||||
|
See the functions :meth:`merge()<merge>` (or :meth:`append()<append>`)
|
||||||
|
and :meth:`write()<write>` for usage information.
|
||||||
|
|
||||||
|
:param bool strict: Determines whether user should be warned of all
|
||||||
|
problems and also causes some correctable problems to be fatal.
|
||||||
|
Defaults to ``True``.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, strict=True):
|
||||||
|
self.inputs = []
|
||||||
|
self.pages = []
|
||||||
|
self.output = PdfFileWriter()
|
||||||
|
self.bookmarks = []
|
||||||
|
self.named_dests = []
|
||||||
|
self.id_count = 0
|
||||||
|
self.strict = strict
|
||||||
|
|
||||||
|
def merge(self, position, fileobj, bookmark=None, pages=None, import_bookmarks=True):
|
||||||
|
"""
|
||||||
|
Merges the pages from the given file into the output file at the
|
||||||
|
specified page number.
|
||||||
|
|
||||||
|
:param int position: The *page number* to insert this file. File will
|
||||||
|
be inserted after the given number.
|
||||||
|
|
||||||
|
:param fileobj: A File Object or an object that supports the standard read
|
||||||
|
and seek methods similar to a File Object. Could also be a
|
||||||
|
string representing a path to a PDF file.
|
||||||
|
|
||||||
|
:param str bookmark: Optionally, you may specify a bookmark to be applied at
|
||||||
|
the beginning of the included file by supplying the text of the bookmark.
|
||||||
|
|
||||||
|
:param pages: can be a :ref:`Page Range <page-range>` or a ``(start, stop[, step])`` tuple
|
||||||
|
to merge only the specified range of pages from the source
|
||||||
|
document into the output document.
|
||||||
|
|
||||||
|
:param bool import_bookmarks: You may prevent the source document's bookmarks
|
||||||
|
from being imported by specifying this as ``False``.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# This parameter is passed to self.inputs.append and means
|
||||||
|
# that the stream used was created in this method.
|
||||||
|
my_file = False
|
||||||
|
|
||||||
|
# If the fileobj parameter is a string, assume it is a path
|
||||||
|
# and create a file object at that location. If it is a file,
|
||||||
|
# copy the file's contents into a BytesIO (or StreamIO) stream object; if
|
||||||
|
# it is a PdfFileReader, copy that reader's stream into a
|
||||||
|
# BytesIO (or StreamIO) stream.
|
||||||
|
# If fileobj is none of the above types, it is not modified
|
||||||
|
decryption_key = None
|
||||||
|
if isString(fileobj):
|
||||||
|
fileobj = file(fileobj, 'rb')
|
||||||
|
my_file = True
|
||||||
|
elif isinstance(fileobj, file):
|
||||||
|
fileobj.seek(0)
|
||||||
|
filecontent = fileobj.read()
|
||||||
|
fileobj = StreamIO(filecontent)
|
||||||
|
my_file = True
|
||||||
|
elif isinstance(fileobj, PdfFileReader):
|
||||||
|
orig_tell = fileobj.stream.tell()
|
||||||
|
fileobj.stream.seek(0)
|
||||||
|
filecontent = StreamIO(fileobj.stream.read())
|
||||||
|
fileobj.stream.seek(orig_tell) # reset the stream to its original location
|
||||||
|
fileobj = filecontent
|
||||||
|
if hasattr(fileobj, '_decryption_key'):
|
||||||
|
decryption_key = fileobj._decryption_key
|
||||||
|
my_file = True
|
||||||
|
|
||||||
|
# Create a new PdfFileReader instance using the stream
|
||||||
|
# (either file or BytesIO or StringIO) created above
|
||||||
|
pdfr = PdfFileReader(fileobj, strict=self.strict)
|
||||||
|
if decryption_key is not None:
|
||||||
|
pdfr._decryption_key = decryption_key
|
||||||
|
|
||||||
|
# Find the range of pages to merge.
|
||||||
|
if pages == None:
|
||||||
|
pages = (0, pdfr.getNumPages())
|
||||||
|
elif isinstance(pages, PageRange):
|
||||||
|
pages = pages.indices(pdfr.getNumPages())
|
||||||
|
elif not isinstance(pages, tuple):
|
||||||
|
raise TypeError('"pages" must be a tuple of (start, stop[, step])')
|
||||||
|
|
||||||
|
srcpages = []
|
||||||
|
if bookmark:
|
||||||
|
bookmark = Bookmark(TextStringObject(bookmark), NumberObject(self.id_count), NameObject('/Fit'))
|
||||||
|
|
||||||
|
outline = []
|
||||||
|
if import_bookmarks:
|
||||||
|
outline = pdfr.getOutlines()
|
||||||
|
outline = self._trim_outline(pdfr, outline, pages)
|
||||||
|
|
||||||
|
if bookmark:
|
||||||
|
self.bookmarks += [bookmark, outline]
|
||||||
|
else:
|
||||||
|
self.bookmarks += outline
|
||||||
|
|
||||||
|
dests = pdfr.namedDestinations
|
||||||
|
dests = self._trim_dests(pdfr, dests, pages)
|
||||||
|
self.named_dests += dests
|
||||||
|
|
||||||
|
# Gather all the pages that are going to be merged
|
||||||
|
for i in range(*pages):
|
||||||
|
pg = pdfr.getPage(i)
|
||||||
|
|
||||||
|
id = self.id_count
|
||||||
|
self.id_count += 1
|
||||||
|
|
||||||
|
mp = _MergedPage(pg, pdfr, id)
|
||||||
|
|
||||||
|
srcpages.append(mp)
|
||||||
|
|
||||||
|
self._associate_dests_to_pages(srcpages)
|
||||||
|
self._associate_bookmarks_to_pages(srcpages)
|
||||||
|
|
||||||
|
# Slice to insert the pages at the specified position
|
||||||
|
self.pages[position:position] = srcpages
|
||||||
|
|
||||||
|
# Keep track of our input files so we can close them later
|
||||||
|
self.inputs.append((fileobj, pdfr, my_file))
|
||||||
|
|
||||||
|
def append(self, fileobj, bookmark=None, pages=None, import_bookmarks=True):
|
||||||
|
"""
|
||||||
|
Identical to the :meth:`merge()<merge>` method, but assumes you want to concatenate
|
||||||
|
all pages onto the end of the file instead of specifying a position.
|
||||||
|
|
||||||
|
:param fileobj: A File Object or an object that supports the standard read
|
||||||
|
and seek methods similar to a File Object. Could also be a
|
||||||
|
string representing a path to a PDF file.
|
||||||
|
|
||||||
|
:param str bookmark: Optionally, you may specify a bookmark to be applied at
|
||||||
|
the beginning of the included file by supplying the text of the bookmark.
|
||||||
|
|
||||||
|
:param pages: can be a :ref:`Page Range <page-range>` or a ``(start, stop[, step])`` tuple
|
||||||
|
to merge only the specified range of pages from the source
|
||||||
|
document into the output document.
|
||||||
|
|
||||||
|
:param bool import_bookmarks: You may prevent the source document's bookmarks
|
||||||
|
from being imported by specifying this as ``False``.
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.merge(len(self.pages), fileobj, bookmark, pages, import_bookmarks)
|
||||||
|
|
||||||
|
def write(self, fileobj):
|
||||||
|
"""
|
||||||
|
Writes all data that has been merged to the given output file.
|
||||||
|
|
||||||
|
:param fileobj: Output file. Can be a filename or any kind of
|
||||||
|
file-like object.
|
||||||
|
"""
|
||||||
|
my_file = False
|
||||||
|
if isString(fileobj):
|
||||||
|
fileobj = file(fileobj, 'wb')
|
||||||
|
my_file = True
|
||||||
|
|
||||||
|
# Add pages to the PdfFileWriter
|
||||||
|
# The commented out line below was replaced with the two lines below it to allow PdfFileMerger to work with PyPdf 1.13
|
||||||
|
for page in self.pages:
|
||||||
|
self.output.addPage(page.pagedata)
|
||||||
|
page.out_pagedata = self.output.getReference(self.output._pages.getObject()["/Kids"][-1].getObject())
|
||||||
|
#idnum = self.output._objects.index(self.output._pages.getObject()["/Kids"][-1].getObject()) + 1
|
||||||
|
#page.out_pagedata = IndirectObject(idnum, 0, self.output)
|
||||||
|
|
||||||
|
# Once all pages are added, create bookmarks to point at those pages
|
||||||
|
self._write_dests()
|
||||||
|
self._write_bookmarks()
|
||||||
|
|
||||||
|
# Write the output to the file
|
||||||
|
self.output.write(fileobj)
|
||||||
|
|
||||||
|
if my_file:
|
||||||
|
fileobj.close()
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
"""
|
||||||
|
Shuts all file descriptors (input and output) and clears all memory
|
||||||
|
usage.
|
||||||
|
"""
|
||||||
|
self.pages = []
|
||||||
|
for fo, pdfr, mine in self.inputs:
|
||||||
|
if mine:
|
||||||
|
fo.close()
|
||||||
|
|
||||||
|
self.inputs = []
|
||||||
|
self.output = None
|
||||||
|
|
||||||
|
def addMetadata(self, infos):
|
||||||
|
"""
|
||||||
|
Add custom metadata to the output.
|
||||||
|
|
||||||
|
:param dict infos: a Python dictionary where each key is a field
|
||||||
|
and each value is your new metadata.
|
||||||
|
Example: ``{u'/Title': u'My title'}``
|
||||||
|
"""
|
||||||
|
self.output.addMetadata(infos)
|
||||||
|
|
||||||
|
def setPageLayout(self, layout):
|
||||||
|
"""
|
||||||
|
Set the page layout
|
||||||
|
|
||||||
|
:param str layout: The page layout to be used
|
||||||
|
|
||||||
|
Valid layouts are:
|
||||||
|
/NoLayout Layout explicitly not specified
|
||||||
|
/SinglePage Show one page at a time
|
||||||
|
/OneColumn Show one column at a time
|
||||||
|
/TwoColumnLeft Show pages in two columns, odd-numbered pages on the left
|
||||||
|
/TwoColumnRight Show pages in two columns, odd-numbered pages on the right
|
||||||
|
/TwoPageLeft Show two pages at a time, odd-numbered pages on the left
|
||||||
|
/TwoPageRight Show two pages at a time, odd-numbered pages on the right
|
||||||
|
"""
|
||||||
|
self.output.setPageLayout(layout)
|
||||||
|
|
||||||
|
def setPageMode(self, mode):
|
||||||
|
"""
|
||||||
|
Set the page mode.
|
||||||
|
|
||||||
|
:param str mode: The page mode to use.
|
||||||
|
|
||||||
|
Valid modes are:
|
||||||
|
/UseNone Do not show outlines or thumbnails panels
|
||||||
|
/UseOutlines Show outlines (aka bookmarks) panel
|
||||||
|
/UseThumbs Show page thumbnails panel
|
||||||
|
/FullScreen Fullscreen view
|
||||||
|
/UseOC Show Optional Content Group (OCG) panel
|
||||||
|
/UseAttachments Show attachments panel
|
||||||
|
"""
|
||||||
|
self.output.setPageMode(mode)
|
||||||
|
|
||||||
|
def _trim_dests(self, pdf, dests, pages):
|
||||||
|
"""
|
||||||
|
Removes any named destinations that are not a part of the specified
|
||||||
|
page set.
|
||||||
|
"""
|
||||||
|
new_dests = []
|
||||||
|
prev_header_added = True
|
||||||
|
for k, o in list(dests.items()):
|
||||||
|
for j in range(*pages):
|
||||||
|
if pdf.getPage(j).getObject() == o['/Page'].getObject():
|
||||||
|
o[NameObject('/Page')] = o['/Page'].getObject()
|
||||||
|
assert str_(k) == str_(o['/Title'])
|
||||||
|
new_dests.append(o)
|
||||||
|
break
|
||||||
|
return new_dests
|
||||||
|
|
||||||
|
def _trim_outline(self, pdf, outline, pages):
|
||||||
|
"""
|
||||||
|
Removes any outline/bookmark entries that are not a part of the
|
||||||
|
specified page set.
|
||||||
|
"""
|
||||||
|
new_outline = []
|
||||||
|
prev_header_added = True
|
||||||
|
for i, o in enumerate(outline):
|
||||||
|
if isinstance(o, list):
|
||||||
|
sub = self._trim_outline(pdf, o, pages)
|
||||||
|
if sub:
|
||||||
|
if not prev_header_added:
|
||||||
|
new_outline.append(outline[i-1])
|
||||||
|
new_outline.append(sub)
|
||||||
|
else:
|
||||||
|
prev_header_added = False
|
||||||
|
for j in range(*pages):
|
||||||
|
if pdf.getPage(j).getObject() == o['/Page'].getObject():
|
||||||
|
o[NameObject('/Page')] = o['/Page'].getObject()
|
||||||
|
new_outline.append(o)
|
||||||
|
prev_header_added = True
|
||||||
|
break
|
||||||
|
return new_outline
|
||||||
|
|
||||||
|
def _write_dests(self):
|
||||||
|
dests = self.named_dests
|
||||||
|
|
||||||
|
for v in dests:
|
||||||
|
pageno = None
|
||||||
|
pdf = None
|
||||||
|
if '/Page' in v:
|
||||||
|
for i, p in enumerate(self.pages):
|
||||||
|
if p.id == v['/Page']:
|
||||||
|
v[NameObject('/Page')] = p.out_pagedata
|
||||||
|
pageno = i
|
||||||
|
pdf = p.src
|
||||||
|
break
|
||||||
|
if pageno != None:
|
||||||
|
self.output.addNamedDestinationObject(v)
|
||||||
|
|
||||||
|
def _write_bookmarks(self, bookmarks=None, parent=None):
|
||||||
|
|
||||||
|
if bookmarks == None:
|
||||||
|
bookmarks = self.bookmarks
|
||||||
|
|
||||||
|
last_added = None
|
||||||
|
for b in bookmarks:
|
||||||
|
if isinstance(b, list):
|
||||||
|
self._write_bookmarks(b, last_added)
|
||||||
|
continue
|
||||||
|
|
||||||
|
pageno = None
|
||||||
|
pdf = None
|
||||||
|
if '/Page' in b:
|
||||||
|
for i, p in enumerate(self.pages):
|
||||||
|
if p.id == b['/Page']:
|
||||||
|
#b[NameObject('/Page')] = p.out_pagedata
|
||||||
|
args = [NumberObject(p.id), NameObject(b['/Type'])]
|
||||||
|
#nothing more to add
|
||||||
|
#if b['/Type'] == '/Fit' or b['/Type'] == '/FitB'
|
||||||
|
if b['/Type'] == '/FitH' or b['/Type'] == '/FitBH':
|
||||||
|
if '/Top' in b and not isinstance(b['/Top'], NullObject):
|
||||||
|
args.append(FloatObject(b['/Top']))
|
||||||
|
else:
|
||||||
|
args.append(FloatObject(0))
|
||||||
|
del b['/Top']
|
||||||
|
elif b['/Type'] == '/FitV' or b['/Type'] == '/FitBV':
|
||||||
|
if '/Left' in b and not isinstance(b['/Left'], NullObject):
|
||||||
|
args.append(FloatObject(b['/Left']))
|
||||||
|
else:
|
||||||
|
args.append(FloatObject(0))
|
||||||
|
del b['/Left']
|
||||||
|
elif b['/Type'] == '/XYZ':
|
||||||
|
if '/Left' in b and not isinstance(b['/Left'], NullObject):
|
||||||
|
args.append(FloatObject(b['/Left']))
|
||||||
|
else:
|
||||||
|
args.append(FloatObject(0))
|
||||||
|
if '/Top' in b and not isinstance(b['/Top'], NullObject):
|
||||||
|
args.append(FloatObject(b['/Top']))
|
||||||
|
else:
|
||||||
|
args.append(FloatObject(0))
|
||||||
|
if '/Zoom' in b and not isinstance(b['/Zoom'], NullObject):
|
||||||
|
args.append(FloatObject(b['/Zoom']))
|
||||||
|
else:
|
||||||
|
args.append(FloatObject(0))
|
||||||
|
del b['/Top'], b['/Zoom'], b['/Left']
|
||||||
|
elif b['/Type'] == '/FitR':
|
||||||
|
if '/Left' in b and not isinstance(b['/Left'], NullObject):
|
||||||
|
args.append(FloatObject(b['/Left']))
|
||||||
|
else:
|
||||||
|
args.append(FloatObject(0))
|
||||||
|
if '/Bottom' in b and not isinstance(b['/Bottom'], NullObject):
|
||||||
|
args.append(FloatObject(b['/Bottom']))
|
||||||
|
else:
|
||||||
|
args.append(FloatObject(0))
|
||||||
|
if '/Right' in b and not isinstance(b['/Right'], NullObject):
|
||||||
|
args.append(FloatObject(b['/Right']))
|
||||||
|
else:
|
||||||
|
args.append(FloatObject(0))
|
||||||
|
if '/Top' in b and not isinstance(b['/Top'], NullObject):
|
||||||
|
args.append(FloatObject(b['/Top']))
|
||||||
|
else:
|
||||||
|
args.append(FloatObject(0))
|
||||||
|
del b['/Left'], b['/Right'], b['/Bottom'], b['/Top']
|
||||||
|
|
||||||
|
b[NameObject('/A')] = DictionaryObject({NameObject('/S'): NameObject('/GoTo'), NameObject('/D'): ArrayObject(args)})
|
||||||
|
|
||||||
|
pageno = i
|
||||||
|
pdf = p.src
|
||||||
|
break
|
||||||
|
if pageno != None:
|
||||||
|
del b['/Page'], b['/Type']
|
||||||
|
last_added = self.output.addBookmarkDict(b, parent)
|
||||||
|
|
||||||
|
def _associate_dests_to_pages(self, pages):
|
||||||
|
for nd in self.named_dests:
|
||||||
|
pageno = None
|
||||||
|
np = nd['/Page']
|
||||||
|
|
||||||
|
if isinstance(np, NumberObject):
|
||||||
|
continue
|
||||||
|
|
||||||
|
for p in pages:
|
||||||
|
if np.getObject() == p.pagedata.getObject():
|
||||||
|
pageno = p.id
|
||||||
|
|
||||||
|
if pageno != None:
|
||||||
|
nd[NameObject('/Page')] = NumberObject(pageno)
|
||||||
|
else:
|
||||||
|
raise ValueError("Unresolved named destination '%s'" % (nd['/Title'],))
|
||||||
|
|
||||||
|
def _associate_bookmarks_to_pages(self, pages, bookmarks=None):
|
||||||
|
if bookmarks == None:
|
||||||
|
bookmarks = self.bookmarks
|
||||||
|
|
||||||
|
for b in bookmarks:
|
||||||
|
if isinstance(b, list):
|
||||||
|
self._associate_bookmarks_to_pages(pages, b)
|
||||||
|
continue
|
||||||
|
|
||||||
|
pageno = None
|
||||||
|
bp = b['/Page']
|
||||||
|
|
||||||
|
if isinstance(bp, NumberObject):
|
||||||
|
continue
|
||||||
|
|
||||||
|
for p in pages:
|
||||||
|
if bp.getObject() == p.pagedata.getObject():
|
||||||
|
pageno = p.id
|
||||||
|
|
||||||
|
if pageno != None:
|
||||||
|
b[NameObject('/Page')] = NumberObject(pageno)
|
||||||
|
else:
|
||||||
|
raise ValueError("Unresolved bookmark '%s'" % (b['/Title'],))
|
||||||
|
|
||||||
|
def findBookmark(self, bookmark, root=None):
|
||||||
|
if root == None:
|
||||||
|
root = self.bookmarks
|
||||||
|
|
||||||
|
for i, b in enumerate(root):
|
||||||
|
if isinstance(b, list):
|
||||||
|
res = self.findBookmark(bookmark, b)
|
||||||
|
if res:
|
||||||
|
return [i] + res
|
||||||
|
elif b == bookmark or b['/Title'] == bookmark:
|
||||||
|
return [i]
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
def addBookmark(self, title, pagenum, parent=None):
|
||||||
|
"""
|
||||||
|
Add a bookmark to this PDF file.
|
||||||
|
|
||||||
|
:param str title: Title to use for this bookmark.
|
||||||
|
:param int pagenum: Page number this bookmark will point to.
|
||||||
|
:param parent: A reference to a parent bookmark to create nested
|
||||||
|
bookmarks.
|
||||||
|
"""
|
||||||
|
if parent == None:
|
||||||
|
iloc = [len(self.bookmarks)-1]
|
||||||
|
elif isinstance(parent, list):
|
||||||
|
iloc = parent
|
||||||
|
else:
|
||||||
|
iloc = self.findBookmark(parent)
|
||||||
|
|
||||||
|
dest = Bookmark(TextStringObject(title), NumberObject(pagenum), NameObject('/FitH'), NumberObject(826))
|
||||||
|
|
||||||
|
if parent == None:
|
||||||
|
self.bookmarks.append(dest)
|
||||||
|
else:
|
||||||
|
bmparent = self.bookmarks
|
||||||
|
for i in iloc[:-1]:
|
||||||
|
bmparent = bmparent[i]
|
||||||
|
npos = iloc[-1]+1
|
||||||
|
if npos < len(bmparent) and isinstance(bmparent[npos], list):
|
||||||
|
bmparent[npos].append(dest)
|
||||||
|
else:
|
||||||
|
bmparent.insert(npos, [dest])
|
||||||
|
return dest
|
||||||
|
|
||||||
|
def addNamedDestination(self, title, pagenum):
|
||||||
|
"""
|
||||||
|
Add a destination to the output.
|
||||||
|
|
||||||
|
:param str title: Title to use
|
||||||
|
:param int pagenum: Page number this destination points at.
|
||||||
|
"""
|
||||||
|
|
||||||
|
dest = Destination(TextStringObject(title), NumberObject(pagenum), NameObject('/FitH'), NumberObject(826))
|
||||||
|
self.named_dests.append(dest)
|
||||||
|
|
||||||
|
|
||||||
|
class OutlinesObject(list):
|
||||||
|
def __init__(self, pdf, tree, parent=None):
|
||||||
|
list.__init__(self)
|
||||||
|
self.tree = tree
|
||||||
|
self.pdf = pdf
|
||||||
|
self.parent = parent
|
||||||
|
|
||||||
|
def remove(self, index):
|
||||||
|
obj = self[index]
|
||||||
|
del self[index]
|
||||||
|
self.tree.removeChild(obj)
|
||||||
|
|
||||||
|
def add(self, title, pagenum):
|
||||||
|
pageRef = self.pdf.getObject(self.pdf._pages)['/Kids'][pagenum]
|
||||||
|
action = DictionaryObject()
|
||||||
|
action.update({
|
||||||
|
NameObject('/D') : ArrayObject([pageRef, NameObject('/FitH'), NumberObject(826)]),
|
||||||
|
NameObject('/S') : NameObject('/GoTo')
|
||||||
|
})
|
||||||
|
actionRef = self.pdf._addObject(action)
|
||||||
|
bookmark = TreeObject()
|
||||||
|
|
||||||
|
bookmark.update({
|
||||||
|
NameObject('/A'): actionRef,
|
||||||
|
NameObject('/Title'): createStringObject(title),
|
||||||
|
})
|
||||||
|
|
||||||
|
self.pdf._addObject(bookmark)
|
||||||
|
|
||||||
|
self.tree.addChild(bookmark)
|
||||||
|
|
||||||
|
def removeAll(self):
|
||||||
|
for child in [x for x in self.tree.children()]:
|
||||||
|
self.tree.removeChild(child)
|
||||||
|
self.pop()
|
@ -0,0 +1,152 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
"""
|
||||||
|
Representation and utils for ranges of PDF file pages.
|
||||||
|
|
||||||
|
Copyright (c) 2014, Steve Witham <switham_github@mac-guyver.com>.
|
||||||
|
All rights reserved. This software is available under a BSD license;
|
||||||
|
see https://github.com/mstamy2/PyPDF2/blob/master/LICENSE
|
||||||
|
"""
|
||||||
|
|
||||||
|
import re
|
||||||
|
from .utils import isString
|
||||||
|
|
||||||
|
_INT_RE = r"(0|-?[1-9]\d*)" # A decimal int, don't allow "-0".
|
||||||
|
PAGE_RANGE_RE = "^({int}|({int}?(:{int}?(:{int}?)?)))$".format(int=_INT_RE)
|
||||||
|
# groups: 12 34 5 6 7 8
|
||||||
|
|
||||||
|
|
||||||
|
class ParseError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
PAGE_RANGE_HELP = """Remember, page indices start with zero.
|
||||||
|
Page range expression examples:
|
||||||
|
: all pages. -1 last page.
|
||||||
|
22 just the 23rd page. :-1 all but the last page.
|
||||||
|
0:3 the first three pages. -2 second-to-last page.
|
||||||
|
:3 the first three pages. -2: last two pages.
|
||||||
|
5: from the sixth page onward. -3:-1 third & second to last.
|
||||||
|
The third, "stride" or "step" number is also recognized.
|
||||||
|
::2 0 2 4 ... to the end. 3:0:-1 3 2 1 but not 0.
|
||||||
|
1:10:2 1 3 5 7 9 2::-1 2 1 0.
|
||||||
|
::-1 all pages in reverse order.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class PageRange(object):
|
||||||
|
"""
|
||||||
|
A slice-like representation of a range of page indices,
|
||||||
|
i.e. page numbers, only starting at zero.
|
||||||
|
The syntax is like what you would put between brackets [ ].
|
||||||
|
The slice is one of the few Python types that can't be subclassed,
|
||||||
|
but this class converts to and from slices, and allows similar use.
|
||||||
|
o PageRange(str) parses a string representing a page range.
|
||||||
|
o PageRange(slice) directly "imports" a slice.
|
||||||
|
o to_slice() gives the equivalent slice.
|
||||||
|
o str() and repr() allow printing.
|
||||||
|
o indices(n) is like slice.indices(n).
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, arg):
|
||||||
|
"""
|
||||||
|
Initialize with either a slice -- giving the equivalent page range,
|
||||||
|
or a PageRange object -- making a copy,
|
||||||
|
or a string like
|
||||||
|
"int", "[int]:[int]" or "[int]:[int]:[int]",
|
||||||
|
where the brackets indicate optional ints.
|
||||||
|
{page_range_help}
|
||||||
|
Note the difference between this notation and arguments to slice():
|
||||||
|
slice(3) means the first three pages;
|
||||||
|
PageRange("3") means the range of only the fourth page.
|
||||||
|
However PageRange(slice(3)) means the first three pages.
|
||||||
|
"""
|
||||||
|
if isinstance(arg, slice):
|
||||||
|
self._slice = arg
|
||||||
|
return
|
||||||
|
|
||||||
|
if isinstance(arg, PageRange):
|
||||||
|
self._slice = arg.to_slice()
|
||||||
|
return
|
||||||
|
|
||||||
|
m = isString(arg) and re.match(PAGE_RANGE_RE, arg)
|
||||||
|
if not m:
|
||||||
|
raise ParseError(arg)
|
||||||
|
elif m.group(2):
|
||||||
|
# Special case: just an int means a range of one page.
|
||||||
|
start = int(m.group(2))
|
||||||
|
stop = start + 1 if start != -1 else None
|
||||||
|
self._slice = slice(start, stop)
|
||||||
|
else:
|
||||||
|
self._slice = slice(*[int(g) if g else None
|
||||||
|
for g in m.group(4, 6, 8)])
|
||||||
|
|
||||||
|
# Just formatting this when there is __doc__ for __init__
|
||||||
|
if __init__.__doc__:
|
||||||
|
__init__.__doc__ = __init__.__doc__.format(page_range_help=PAGE_RANGE_HELP)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def valid(input):
|
||||||
|
""" True if input is a valid initializer for a PageRange. """
|
||||||
|
return isinstance(input, slice) or \
|
||||||
|
isinstance(input, PageRange) or \
|
||||||
|
(isString(input)
|
||||||
|
and bool(re.match(PAGE_RANGE_RE, input)))
|
||||||
|
|
||||||
|
def to_slice(self):
|
||||||
|
""" Return the slice equivalent of this page range. """
|
||||||
|
return self._slice
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
""" A string like "1:2:3". """
|
||||||
|
s = self._slice
|
||||||
|
if s.step == None:
|
||||||
|
if s.start != None and s.stop == s.start + 1:
|
||||||
|
return str(s.start)
|
||||||
|
|
||||||
|
indices = s.start, s.stop
|
||||||
|
else:
|
||||||
|
indices = s.start, s.stop, s.step
|
||||||
|
return ':'.join("" if i == None else str(i) for i in indices)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
""" A string like "PageRange('1:2:3')". """
|
||||||
|
return "PageRange(" + repr(str(self)) + ")"
|
||||||
|
|
||||||
|
def indices(self, n):
|
||||||
|
"""
|
||||||
|
n is the length of the list of pages to choose from.
|
||||||
|
Returns arguments for range(). See help(slice.indices).
|
||||||
|
"""
|
||||||
|
return self._slice.indices(n)
|
||||||
|
|
||||||
|
|
||||||
|
PAGE_RANGE_ALL = PageRange(":") # The range of all pages.
|
||||||
|
|
||||||
|
|
||||||
|
def parse_filename_page_ranges(args):
|
||||||
|
"""
|
||||||
|
Given a list of filenames and page ranges, return a list of
|
||||||
|
(filename, page_range) pairs.
|
||||||
|
First arg must be a filename; other ags are filenames, page-range
|
||||||
|
expressions, slice objects, or PageRange objects.
|
||||||
|
A filename not followed by a page range indicates all pages of the file.
|
||||||
|
"""
|
||||||
|
pairs = []
|
||||||
|
pdf_filename = None
|
||||||
|
did_page_range = False
|
||||||
|
for arg in args + [None]:
|
||||||
|
if PageRange.valid(arg):
|
||||||
|
if not pdf_filename:
|
||||||
|
raise ValueError("The first argument must be a filename, " \
|
||||||
|
"not a page range.")
|
||||||
|
|
||||||
|
pairs.append( (pdf_filename, PageRange(arg)) )
|
||||||
|
did_page_range = True
|
||||||
|
else:
|
||||||
|
# New filename or end of list--do all of the previous file?
|
||||||
|
if pdf_filename and not did_page_range:
|
||||||
|
pairs.append( (pdf_filename, PAGE_RANGE_ALL) )
|
||||||
|
|
||||||
|
pdf_filename = arg
|
||||||
|
did_page_range = False
|
||||||
|
return pairs
|
@ -0,0 +1,295 @@
|
|||||||
|
# Copyright (c) 2006, Mathieu Fenniak
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are
|
||||||
|
# met:
|
||||||
|
#
|
||||||
|
# * Redistributions of source code must retain the above copyright notice,
|
||||||
|
# this list of conditions and the following disclaimer.
|
||||||
|
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
# this list of conditions and the following disclaimer in the documentation
|
||||||
|
# and/or other materials provided with the distribution.
|
||||||
|
# * The name of the author may not be used to endorse or promote products
|
||||||
|
# derived from this software without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Utility functions for PDF library.
|
||||||
|
"""
|
||||||
|
__author__ = "Mathieu Fenniak"
|
||||||
|
__author_email__ = "biziqe@mathieu.fenniak.net"
|
||||||
|
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
try:
|
||||||
|
import __builtin__ as builtins
|
||||||
|
except ImportError: # Py3
|
||||||
|
import builtins
|
||||||
|
|
||||||
|
|
||||||
|
xrange_fn = getattr(builtins, "xrange", range)
|
||||||
|
_basestring = getattr(builtins, "basestring", str)
|
||||||
|
|
||||||
|
bytes_type = type(bytes()) # Works the same in Python 2.X and 3.X
|
||||||
|
string_type = getattr(builtins, "unicode", str)
|
||||||
|
int_types = (int, long) if sys.version_info[0] < 3 else (int,)
|
||||||
|
|
||||||
|
|
||||||
|
# Make basic type tests more consistent
|
||||||
|
def isString(s):
|
||||||
|
"""Test if arg is a string. Compatible with Python 2 and 3."""
|
||||||
|
return isinstance(s, _basestring)
|
||||||
|
|
||||||
|
|
||||||
|
def isInt(n):
|
||||||
|
"""Test if arg is an int. Compatible with Python 2 and 3."""
|
||||||
|
return isinstance(n, int_types)
|
||||||
|
|
||||||
|
|
||||||
|
def isBytes(b):
|
||||||
|
"""Test if arg is a bytes instance. Compatible with Python 2 and 3."""
|
||||||
|
return isinstance(b, bytes_type)
|
||||||
|
|
||||||
|
|
||||||
|
#custom implementation of warnings.formatwarning
|
||||||
|
def formatWarning(message, category, filename, lineno, line=None):
|
||||||
|
file = filename.replace("/", "\\").rsplit("\\", 1)[1] # find the file name
|
||||||
|
return "%s: %s [%s:%s]\n" % (category.__name__, message, file, lineno)
|
||||||
|
|
||||||
|
|
||||||
|
def readUntilWhitespace(stream, maxchars=None):
|
||||||
|
"""
|
||||||
|
Reads non-whitespace characters and returns them.
|
||||||
|
Stops upon encountering whitespace or when maxchars is reached.
|
||||||
|
"""
|
||||||
|
txt = b_("")
|
||||||
|
while True:
|
||||||
|
tok = stream.read(1)
|
||||||
|
if tok.isspace() or not tok:
|
||||||
|
break
|
||||||
|
txt += tok
|
||||||
|
if len(txt) == maxchars:
|
||||||
|
break
|
||||||
|
return txt
|
||||||
|
|
||||||
|
|
||||||
|
def readNonWhitespace(stream):
|
||||||
|
"""
|
||||||
|
Finds and reads the next non-whitespace character (ignores whitespace).
|
||||||
|
"""
|
||||||
|
tok = WHITESPACES[0]
|
||||||
|
while tok in WHITESPACES:
|
||||||
|
tok = stream.read(1)
|
||||||
|
return tok
|
||||||
|
|
||||||
|
|
||||||
|
def skipOverWhitespace(stream):
|
||||||
|
"""
|
||||||
|
Similar to readNonWhitespace, but returns a Boolean if more than
|
||||||
|
one whitespace character was read.
|
||||||
|
"""
|
||||||
|
tok = WHITESPACES[0]
|
||||||
|
cnt = 0;
|
||||||
|
while tok in WHITESPACES:
|
||||||
|
tok = stream.read(1)
|
||||||
|
cnt+=1
|
||||||
|
return (cnt > 1)
|
||||||
|
|
||||||
|
|
||||||
|
def skipOverComment(stream):
|
||||||
|
tok = stream.read(1)
|
||||||
|
stream.seek(-1, 1)
|
||||||
|
if tok == b_('%'):
|
||||||
|
while tok not in (b_('\n'), b_('\r')):
|
||||||
|
tok = stream.read(1)
|
||||||
|
|
||||||
|
|
||||||
|
def readUntilRegex(stream, regex, ignore_eof=False):
|
||||||
|
"""
|
||||||
|
Reads until the regular expression pattern matched (ignore the match)
|
||||||
|
Raise PdfStreamError on premature end-of-file.
|
||||||
|
:param bool ignore_eof: If true, ignore end-of-line and return immediately
|
||||||
|
"""
|
||||||
|
name = b_('')
|
||||||
|
while True:
|
||||||
|
tok = stream.read(16)
|
||||||
|
if not tok:
|
||||||
|
# stream has truncated prematurely
|
||||||
|
if ignore_eof == True:
|
||||||
|
return name
|
||||||
|
else:
|
||||||
|
raise PdfStreamError("Stream has ended unexpectedly")
|
||||||
|
m = regex.search(tok)
|
||||||
|
if m is not None:
|
||||||
|
name += tok[:m.start()]
|
||||||
|
stream.seek(m.start()-len(tok), 1)
|
||||||
|
break
|
||||||
|
name += tok
|
||||||
|
return name
|
||||||
|
|
||||||
|
|
||||||
|
class ConvertFunctionsToVirtualList(object):
|
||||||
|
def __init__(self, lengthFunction, getFunction):
|
||||||
|
self.lengthFunction = lengthFunction
|
||||||
|
self.getFunction = getFunction
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return self.lengthFunction()
|
||||||
|
|
||||||
|
def __getitem__(self, index):
|
||||||
|
if isinstance(index, slice):
|
||||||
|
indices = xrange_fn(*index.indices(len(self)))
|
||||||
|
cls = type(self)
|
||||||
|
return cls(indices.__len__, lambda idx: self[indices[idx]])
|
||||||
|
if not isInt(index):
|
||||||
|
raise TypeError("sequence indices must be integers")
|
||||||
|
len_self = len(self)
|
||||||
|
if index < 0:
|
||||||
|
# support negative indexes
|
||||||
|
index = len_self + index
|
||||||
|
if index < 0 or index >= len_self:
|
||||||
|
raise IndexError("sequence index out of range")
|
||||||
|
return self.getFunction(index)
|
||||||
|
|
||||||
|
|
||||||
|
def RC4_encrypt(key, plaintext):
|
||||||
|
S = [i for i in range(256)]
|
||||||
|
j = 0
|
||||||
|
for i in range(256):
|
||||||
|
j = (j + S[i] + ord_(key[i % len(key)])) % 256
|
||||||
|
S[i], S[j] = S[j], S[i]
|
||||||
|
i, j = 0, 0
|
||||||
|
retval = b_("")
|
||||||
|
for x in range(len(plaintext)):
|
||||||
|
i = (i + 1) % 256
|
||||||
|
j = (j + S[i]) % 256
|
||||||
|
S[i], S[j] = S[j], S[i]
|
||||||
|
t = S[(S[i] + S[j]) % 256]
|
||||||
|
retval += b_(chr(ord_(plaintext[x]) ^ t))
|
||||||
|
return retval
|
||||||
|
|
||||||
|
|
||||||
|
def matrixMultiply(a, b):
|
||||||
|
return [[sum([float(i)*float(j)
|
||||||
|
for i, j in zip(row, col)]
|
||||||
|
) for col in zip(*b)]
|
||||||
|
for row in a]
|
||||||
|
|
||||||
|
|
||||||
|
def markLocation(stream):
|
||||||
|
"""Creates text file showing current location in context."""
|
||||||
|
# Mainly for debugging
|
||||||
|
RADIUS = 5000
|
||||||
|
stream.seek(-RADIUS, 1)
|
||||||
|
outputDoc = open('PyPDF2_pdfLocation.txt', 'w')
|
||||||
|
outputDoc.write(stream.read(RADIUS))
|
||||||
|
outputDoc.write('HERE')
|
||||||
|
outputDoc.write(stream.read(RADIUS))
|
||||||
|
outputDoc.close()
|
||||||
|
stream.seek(-RADIUS, 1)
|
||||||
|
|
||||||
|
|
||||||
|
class PyPdfError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class PdfReadError(PyPdfError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class PageSizeNotDefinedError(PyPdfError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class PdfReadWarning(UserWarning):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class PdfStreamError(PdfReadError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
if sys.version_info[0] < 3:
|
||||||
|
def b_(s):
|
||||||
|
return s
|
||||||
|
else:
|
||||||
|
B_CACHE = {}
|
||||||
|
|
||||||
|
def b_(s):
|
||||||
|
bc = B_CACHE
|
||||||
|
if s in bc:
|
||||||
|
return bc[s]
|
||||||
|
if type(s) == bytes:
|
||||||
|
return s
|
||||||
|
else:
|
||||||
|
r = s.encode('latin-1')
|
||||||
|
if len(s) < 2:
|
||||||
|
bc[s] = r
|
||||||
|
return r
|
||||||
|
|
||||||
|
|
||||||
|
def u_(s):
|
||||||
|
if sys.version_info[0] < 3:
|
||||||
|
return unicode(s, 'unicode_escape')
|
||||||
|
else:
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
def str_(b):
|
||||||
|
if sys.version_info[0] < 3:
|
||||||
|
return b
|
||||||
|
else:
|
||||||
|
if type(b) == bytes:
|
||||||
|
return b.decode('latin-1')
|
||||||
|
else:
|
||||||
|
return b
|
||||||
|
|
||||||
|
|
||||||
|
def ord_(b):
|
||||||
|
if sys.version_info[0] < 3 or type(b) == str:
|
||||||
|
return ord(b)
|
||||||
|
else:
|
||||||
|
return b
|
||||||
|
|
||||||
|
|
||||||
|
def chr_(c):
|
||||||
|
if sys.version_info[0] < 3:
|
||||||
|
return c
|
||||||
|
else:
|
||||||
|
return chr(c)
|
||||||
|
|
||||||
|
|
||||||
|
def barray(b):
|
||||||
|
if sys.version_info[0] < 3:
|
||||||
|
return b
|
||||||
|
else:
|
||||||
|
return bytearray(b)
|
||||||
|
|
||||||
|
|
||||||
|
def hexencode(b):
|
||||||
|
if sys.version_info[0] < 3:
|
||||||
|
return b.encode('hex')
|
||||||
|
else:
|
||||||
|
import codecs
|
||||||
|
coder = codecs.getencoder('hex_codec')
|
||||||
|
return coder(b)[0]
|
||||||
|
|
||||||
|
|
||||||
|
def hexStr(num):
|
||||||
|
return hex(num).replace('L', '')
|
||||||
|
|
||||||
|
|
||||||
|
WHITESPACES = [b_(x) for x in [' ', '\n', '\r', '\t', '\x00']]
|
@ -0,0 +1,358 @@
|
|||||||
|
import re
|
||||||
|
import datetime
|
||||||
|
import decimal
|
||||||
|
from .generic import PdfObject
|
||||||
|
from xml.dom import getDOMImplementation
|
||||||
|
from xml.dom.minidom import parseString
|
||||||
|
from .utils import u_
|
||||||
|
|
||||||
|
RDF_NAMESPACE = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
DC_NAMESPACE = "http://purl.org/dc/elements/1.1/"
|
||||||
|
XMP_NAMESPACE = "http://ns.adobe.com/xap/1.0/"
|
||||||
|
PDF_NAMESPACE = "http://ns.adobe.com/pdf/1.3/"
|
||||||
|
XMPMM_NAMESPACE = "http://ns.adobe.com/xap/1.0/mm/"
|
||||||
|
|
||||||
|
# What is the PDFX namespace, you might ask? I might ask that too. It's
|
||||||
|
# a completely undocumented namespace used to place "custom metadata"
|
||||||
|
# properties, which are arbitrary metadata properties with no semantic or
|
||||||
|
# documented meaning. Elements in the namespace are key/value-style storage,
|
||||||
|
# where the element name is the key and the content is the value. The keys
|
||||||
|
# are transformed into valid XML identifiers by substituting an invalid
|
||||||
|
# identifier character with \u2182 followed by the unicode hex ID of the
|
||||||
|
# original character. A key like "my car" is therefore "my\u21820020car".
|
||||||
|
#
|
||||||
|
# \u2182, in case you're wondering, is the unicode character
|
||||||
|
# \u{ROMAN NUMERAL TEN THOUSAND}, a straightforward and obvious choice for
|
||||||
|
# escaping characters.
|
||||||
|
#
|
||||||
|
# Intentional users of the pdfx namespace should be shot on sight. A
|
||||||
|
# custom data schema and sensical XML elements could be used instead, as is
|
||||||
|
# suggested by Adobe's own documentation on XMP (under "Extensibility of
|
||||||
|
# Schemas").
|
||||||
|
#
|
||||||
|
# Information presented here on the /pdfx/ schema is a result of limited
|
||||||
|
# reverse engineering, and does not constitute a full specification.
|
||||||
|
PDFX_NAMESPACE = "http://ns.adobe.com/pdfx/1.3/"
|
||||||
|
|
||||||
|
iso8601 = re.compile("""
|
||||||
|
(?P<year>[0-9]{4})
|
||||||
|
(-
|
||||||
|
(?P<month>[0-9]{2})
|
||||||
|
(-
|
||||||
|
(?P<day>[0-9]+)
|
||||||
|
(T
|
||||||
|
(?P<hour>[0-9]{2}):
|
||||||
|
(?P<minute>[0-9]{2})
|
||||||
|
(:(?P<second>[0-9]{2}(.[0-9]+)?))?
|
||||||
|
(?P<tzd>Z|[-+][0-9]{2}:[0-9]{2})
|
||||||
|
)?
|
||||||
|
)?
|
||||||
|
)?
|
||||||
|
""", re.VERBOSE)
|
||||||
|
|
||||||
|
|
||||||
|
class XmpInformation(PdfObject):
|
||||||
|
"""
|
||||||
|
An object that represents Adobe XMP metadata.
|
||||||
|
Usually accessed by :meth:`getXmpMetadata()<PyPDF2.PdfFileReader.getXmpMetadata>`
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, stream):
|
||||||
|
self.stream = stream
|
||||||
|
docRoot = parseString(self.stream.getData())
|
||||||
|
self.rdfRoot = docRoot.getElementsByTagNameNS(RDF_NAMESPACE, "RDF")[0]
|
||||||
|
self.cache = {}
|
||||||
|
|
||||||
|
def writeToStream(self, stream, encryption_key):
|
||||||
|
self.stream.writeToStream(stream, encryption_key)
|
||||||
|
|
||||||
|
def getElement(self, aboutUri, namespace, name):
|
||||||
|
for desc in self.rdfRoot.getElementsByTagNameNS(RDF_NAMESPACE, "Description"):
|
||||||
|
if desc.getAttributeNS(RDF_NAMESPACE, "about") == aboutUri:
|
||||||
|
attr = desc.getAttributeNodeNS(namespace, name)
|
||||||
|
if attr != None:
|
||||||
|
yield attr
|
||||||
|
for element in desc.getElementsByTagNameNS(namespace, name):
|
||||||
|
yield element
|
||||||
|
|
||||||
|
def getNodesInNamespace(self, aboutUri, namespace):
|
||||||
|
for desc in self.rdfRoot.getElementsByTagNameNS(RDF_NAMESPACE, "Description"):
|
||||||
|
if desc.getAttributeNS(RDF_NAMESPACE, "about") == aboutUri:
|
||||||
|
for i in range(desc.attributes.length):
|
||||||
|
attr = desc.attributes.item(i)
|
||||||
|
if attr.namespaceURI == namespace:
|
||||||
|
yield attr
|
||||||
|
for child in desc.childNodes:
|
||||||
|
if child.namespaceURI == namespace:
|
||||||
|
yield child
|
||||||
|
|
||||||
|
def _getText(self, element):
|
||||||
|
text = ""
|
||||||
|
for child in element.childNodes:
|
||||||
|
if child.nodeType == child.TEXT_NODE:
|
||||||
|
text += child.data
|
||||||
|
return text
|
||||||
|
|
||||||
|
def _converter_string(value):
|
||||||
|
return value
|
||||||
|
|
||||||
|
def _converter_date(value):
|
||||||
|
m = iso8601.match(value)
|
||||||
|
year = int(m.group("year"))
|
||||||
|
month = int(m.group("month") or "1")
|
||||||
|
day = int(m.group("day") or "1")
|
||||||
|
hour = int(m.group("hour") or "0")
|
||||||
|
minute = int(m.group("minute") or "0")
|
||||||
|
second = decimal.Decimal(m.group("second") or "0")
|
||||||
|
seconds = second.to_integral(decimal.ROUND_FLOOR)
|
||||||
|
milliseconds = (second - seconds) * 1000000
|
||||||
|
tzd = m.group("tzd") or "Z"
|
||||||
|
dt = datetime.datetime(year, month, day, hour, minute, seconds, milliseconds)
|
||||||
|
if tzd != "Z":
|
||||||
|
tzd_hours, tzd_minutes = [int(x) for x in tzd.split(":")]
|
||||||
|
tzd_hours *= -1
|
||||||
|
if tzd_hours < 0:
|
||||||
|
tzd_minutes *= -1
|
||||||
|
dt = dt + datetime.timedelta(hours=tzd_hours, minutes=tzd_minutes)
|
||||||
|
return dt
|
||||||
|
_test_converter_date = staticmethod(_converter_date)
|
||||||
|
|
||||||
|
def _getter_bag(namespace, name, converter):
|
||||||
|
def get(self):
|
||||||
|
cached = self.cache.get(namespace, {}).get(name)
|
||||||
|
if cached:
|
||||||
|
return cached
|
||||||
|
retval = []
|
||||||
|
for element in self.getElement("", namespace, name):
|
||||||
|
bags = element.getElementsByTagNameNS(RDF_NAMESPACE, "Bag")
|
||||||
|
if len(bags):
|
||||||
|
for bag in bags:
|
||||||
|
for item in bag.getElementsByTagNameNS(RDF_NAMESPACE, "li"):
|
||||||
|
value = self._getText(item)
|
||||||
|
value = converter(value)
|
||||||
|
retval.append(value)
|
||||||
|
ns_cache = self.cache.setdefault(namespace, {})
|
||||||
|
ns_cache[name] = retval
|
||||||
|
return retval
|
||||||
|
return get
|
||||||
|
|
||||||
|
def _getter_seq(namespace, name, converter):
|
||||||
|
def get(self):
|
||||||
|
cached = self.cache.get(namespace, {}).get(name)
|
||||||
|
if cached:
|
||||||
|
return cached
|
||||||
|
retval = []
|
||||||
|
for element in self.getElement("", namespace, name):
|
||||||
|
seqs = element.getElementsByTagNameNS(RDF_NAMESPACE, "Seq")
|
||||||
|
if len(seqs):
|
||||||
|
for seq in seqs:
|
||||||
|
for item in seq.getElementsByTagNameNS(RDF_NAMESPACE, "li"):
|
||||||
|
value = self._getText(item)
|
||||||
|
value = converter(value)
|
||||||
|
retval.append(value)
|
||||||
|
else:
|
||||||
|
value = converter(self._getText(element))
|
||||||
|
retval.append(value)
|
||||||
|
ns_cache = self.cache.setdefault(namespace, {})
|
||||||
|
ns_cache[name] = retval
|
||||||
|
return retval
|
||||||
|
return get
|
||||||
|
|
||||||
|
def _getter_langalt(namespace, name, converter):
|
||||||
|
def get(self):
|
||||||
|
cached = self.cache.get(namespace, {}).get(name)
|
||||||
|
if cached:
|
||||||
|
return cached
|
||||||
|
retval = {}
|
||||||
|
for element in self.getElement("", namespace, name):
|
||||||
|
alts = element.getElementsByTagNameNS(RDF_NAMESPACE, "Alt")
|
||||||
|
if len(alts):
|
||||||
|
for alt in alts:
|
||||||
|
for item in alt.getElementsByTagNameNS(RDF_NAMESPACE, "li"):
|
||||||
|
value = self._getText(item)
|
||||||
|
value = converter(value)
|
||||||
|
retval[item.getAttribute("xml:lang")] = value
|
||||||
|
else:
|
||||||
|
retval["x-default"] = converter(self._getText(element))
|
||||||
|
ns_cache = self.cache.setdefault(namespace, {})
|
||||||
|
ns_cache[name] = retval
|
||||||
|
return retval
|
||||||
|
return get
|
||||||
|
|
||||||
|
def _getter_single(namespace, name, converter):
|
||||||
|
def get(self):
|
||||||
|
cached = self.cache.get(namespace, {}).get(name)
|
||||||
|
if cached:
|
||||||
|
return cached
|
||||||
|
value = None
|
||||||
|
for element in self.getElement("", namespace, name):
|
||||||
|
if element.nodeType == element.ATTRIBUTE_NODE:
|
||||||
|
value = element.nodeValue
|
||||||
|
else:
|
||||||
|
value = self._getText(element)
|
||||||
|
break
|
||||||
|
if value != None:
|
||||||
|
value = converter(value)
|
||||||
|
ns_cache = self.cache.setdefault(namespace, {})
|
||||||
|
ns_cache[name] = value
|
||||||
|
return value
|
||||||
|
return get
|
||||||
|
|
||||||
|
dc_contributor = property(_getter_bag(DC_NAMESPACE, "contributor", _converter_string))
|
||||||
|
"""
|
||||||
|
Contributors to the resource (other than the authors). An unsorted
|
||||||
|
array of names.
|
||||||
|
"""
|
||||||
|
|
||||||
|
dc_coverage = property(_getter_single(DC_NAMESPACE, "coverage", _converter_string))
|
||||||
|
"""
|
||||||
|
Text describing the extent or scope of the resource.
|
||||||
|
"""
|
||||||
|
|
||||||
|
dc_creator = property(_getter_seq(DC_NAMESPACE, "creator", _converter_string))
|
||||||
|
"""
|
||||||
|
A sorted array of names of the authors of the resource, listed in order
|
||||||
|
of precedence.
|
||||||
|
"""
|
||||||
|
|
||||||
|
dc_date = property(_getter_seq(DC_NAMESPACE, "date", _converter_date))
|
||||||
|
"""
|
||||||
|
A sorted array of dates (datetime.datetime instances) of signifigance to
|
||||||
|
the resource. The dates and times are in UTC.
|
||||||
|
"""
|
||||||
|
|
||||||
|
dc_description = property(_getter_langalt(DC_NAMESPACE, "description", _converter_string))
|
||||||
|
"""
|
||||||
|
A language-keyed dictionary of textual descriptions of the content of the
|
||||||
|
resource.
|
||||||
|
"""
|
||||||
|
|
||||||
|
dc_format = property(_getter_single(DC_NAMESPACE, "format", _converter_string))
|
||||||
|
"""
|
||||||
|
The mime-type of the resource.
|
||||||
|
"""
|
||||||
|
|
||||||
|
dc_identifier = property(_getter_single(DC_NAMESPACE, "identifier", _converter_string))
|
||||||
|
"""
|
||||||
|
Unique identifier of the resource.
|
||||||
|
"""
|
||||||
|
|
||||||
|
dc_language = property(_getter_bag(DC_NAMESPACE, "language", _converter_string))
|
||||||
|
"""
|
||||||
|
An unordered array specifying the languages used in the resource.
|
||||||
|
"""
|
||||||
|
|
||||||
|
dc_publisher = property(_getter_bag(DC_NAMESPACE, "publisher", _converter_string))
|
||||||
|
"""
|
||||||
|
An unordered array of publisher names.
|
||||||
|
"""
|
||||||
|
|
||||||
|
dc_relation = property(_getter_bag(DC_NAMESPACE, "relation", _converter_string))
|
||||||
|
"""
|
||||||
|
An unordered array of text descriptions of relationships to other
|
||||||
|
documents.
|
||||||
|
"""
|
||||||
|
|
||||||
|
dc_rights = property(_getter_langalt(DC_NAMESPACE, "rights", _converter_string))
|
||||||
|
"""
|
||||||
|
A language-keyed dictionary of textual descriptions of the rights the
|
||||||
|
user has to this resource.
|
||||||
|
"""
|
||||||
|
|
||||||
|
dc_source = property(_getter_single(DC_NAMESPACE, "source", _converter_string))
|
||||||
|
"""
|
||||||
|
Unique identifier of the work from which this resource was derived.
|
||||||
|
"""
|
||||||
|
|
||||||
|
dc_subject = property(_getter_bag(DC_NAMESPACE, "subject", _converter_string))
|
||||||
|
"""
|
||||||
|
An unordered array of descriptive phrases or keywrods that specify the
|
||||||
|
topic of the content of the resource.
|
||||||
|
"""
|
||||||
|
|
||||||
|
dc_title = property(_getter_langalt(DC_NAMESPACE, "title", _converter_string))
|
||||||
|
"""
|
||||||
|
A language-keyed dictionary of the title of the resource.
|
||||||
|
"""
|
||||||
|
|
||||||
|
dc_type = property(_getter_bag(DC_NAMESPACE, "type", _converter_string))
|
||||||
|
"""
|
||||||
|
An unordered array of textual descriptions of the document type.
|
||||||
|
"""
|
||||||
|
|
||||||
|
pdf_keywords = property(_getter_single(PDF_NAMESPACE, "Keywords", _converter_string))
|
||||||
|
"""
|
||||||
|
An unformatted text string representing document keywords.
|
||||||
|
"""
|
||||||
|
|
||||||
|
pdf_pdfversion = property(_getter_single(PDF_NAMESPACE, "PDFVersion", _converter_string))
|
||||||
|
"""
|
||||||
|
The PDF file version, for example 1.0, 1.3.
|
||||||
|
"""
|
||||||
|
|
||||||
|
pdf_producer = property(_getter_single(PDF_NAMESPACE, "Producer", _converter_string))
|
||||||
|
"""
|
||||||
|
The name of the tool that created the PDF document.
|
||||||
|
"""
|
||||||
|
|
||||||
|
xmp_createDate = property(_getter_single(XMP_NAMESPACE, "CreateDate", _converter_date))
|
||||||
|
"""
|
||||||
|
The date and time the resource was originally created. The date and
|
||||||
|
time are returned as a UTC datetime.datetime object.
|
||||||
|
"""
|
||||||
|
|
||||||
|
xmp_modifyDate = property(_getter_single(XMP_NAMESPACE, "ModifyDate", _converter_date))
|
||||||
|
"""
|
||||||
|
The date and time the resource was last modified. The date and time
|
||||||
|
are returned as a UTC datetime.datetime object.
|
||||||
|
"""
|
||||||
|
|
||||||
|
xmp_metadataDate = property(_getter_single(XMP_NAMESPACE, "MetadataDate", _converter_date))
|
||||||
|
"""
|
||||||
|
The date and time that any metadata for this resource was last
|
||||||
|
changed. The date and time are returned as a UTC datetime.datetime
|
||||||
|
object.
|
||||||
|
"""
|
||||||
|
|
||||||
|
xmp_creatorTool = property(_getter_single(XMP_NAMESPACE, "CreatorTool", _converter_string))
|
||||||
|
"""
|
||||||
|
The name of the first known tool used to create the resource.
|
||||||
|
"""
|
||||||
|
|
||||||
|
xmpmm_documentId = property(_getter_single(XMPMM_NAMESPACE, "DocumentID", _converter_string))
|
||||||
|
"""
|
||||||
|
The common identifier for all versions and renditions of this resource.
|
||||||
|
"""
|
||||||
|
|
||||||
|
xmpmm_instanceId = property(_getter_single(XMPMM_NAMESPACE, "InstanceID", _converter_string))
|
||||||
|
"""
|
||||||
|
An identifier for a specific incarnation of a document, updated each
|
||||||
|
time a file is saved.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def custom_properties(self):
|
||||||
|
if not hasattr(self, "_custom_properties"):
|
||||||
|
self._custom_properties = {}
|
||||||
|
for node in self.getNodesInNamespace("", PDFX_NAMESPACE):
|
||||||
|
key = node.localName
|
||||||
|
while True:
|
||||||
|
# see documentation about PDFX_NAMESPACE earlier in file
|
||||||
|
idx = key.find(u_("\u2182"))
|
||||||
|
if idx == -1:
|
||||||
|
break
|
||||||
|
key = key[:idx] + chr(int(key[idx+1:idx+5], base=16)) + key[idx+5:]
|
||||||
|
if node.nodeType == node.ATTRIBUTE_NODE:
|
||||||
|
value = node.nodeValue
|
||||||
|
else:
|
||||||
|
value = self._getText(node)
|
||||||
|
self._custom_properties[key] = value
|
||||||
|
return self._custom_properties
|
||||||
|
|
||||||
|
custom_properties = property(custom_properties)
|
||||||
|
"""
|
||||||
|
Retrieves custom metadata properties defined in the undocumented pdfx
|
||||||
|
metadata schema.
|
||||||
|
|
||||||
|
:return: a dictionary of key/value items for custom metadata properties.
|
||||||
|
:rtype: dict
|
||||||
|
"""
|
@ -0,0 +1,527 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright <20> 2007-2010 Dieter Verfaillie <dieterv@optionexplicit.be>
|
||||||
|
#
|
||||||
|
# This file is part of elib.intl.
|
||||||
|
#
|
||||||
|
# elib.intl is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# elib.intl is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with elib.intl. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# Update by Dysmas : added the option to explicitly define the language :
|
||||||
|
# parameter "code" in the function : install , line 453
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'''
|
||||||
|
The elib.intl module provides enhanced internationalization (I18N) services for
|
||||||
|
your Python modules and applications.
|
||||||
|
|
||||||
|
elib.intl wraps Python's :func:`gettext` functionality and adds the following on
|
||||||
|
Microsoft Windows systems:
|
||||||
|
|
||||||
|
- automatic detection of the current screen language (not necessarily the same
|
||||||
|
as the installation language) provided by MUI packs,
|
||||||
|
- makes sure internationalized C libraries which internally invoke gettext() or
|
||||||
|
dcgettext() can properly locate their message catalogs. This fixes a known
|
||||||
|
limitation in gettext's Windows support when using eg. gtk.builder or gtk.glade.
|
||||||
|
|
||||||
|
See http://www.gnu.org/software/gettext/FAQ.html#windows_setenv for more
|
||||||
|
information.
|
||||||
|
|
||||||
|
The elib.intl module defines the following functions:
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = ['install', 'install_module']
|
||||||
|
__version__ = '0.0.3'
|
||||||
|
__docformat__ = 'restructuredtext'
|
||||||
|
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import locale
|
||||||
|
import gettext
|
||||||
|
|
||||||
|
from logging import getLogger
|
||||||
|
|
||||||
|
|
||||||
|
logger = getLogger('elib.intl')
|
||||||
|
|
||||||
|
|
||||||
|
def _isofromlcid(lcid):
|
||||||
|
'''
|
||||||
|
:param lcid: Microsoft Windows LCID
|
||||||
|
:returns: the ISO 639-1 language code for a given lcid. If there is no
|
||||||
|
ISO 639-1 language code assigned to the language specified by lcid,
|
||||||
|
the ISO 639-2 language code is returned. If the language specified
|
||||||
|
by lcid is unknown in the ISO 639-x database, None is returned.
|
||||||
|
|
||||||
|
More information can be found on the following websites:
|
||||||
|
- List of ISO 639-1 and ISO 639-2 language codes: http://www.loc.gov/standards/iso639-2/
|
||||||
|
- List of known lcid's: http://www.microsoft.com/globaldev/reference/lcid-all.mspx
|
||||||
|
- List of known MUI packs: http://www.microsoft.com/globaldev/reference/win2k/setup/Langid.mspx
|
||||||
|
'''
|
||||||
|
mapping = {1078: 'af', #Afrikaans - South Africa
|
||||||
|
1052: 'sq', #Albanian - Albania
|
||||||
|
1118: 'am', #Amharic - Ethiopia
|
||||||
|
1025: 'ar', #Arabic - Saudi Arabia
|
||||||
|
5121: 'ar', #Arabic - Algeria
|
||||||
|
15361: 'ar', #Arabic - Bahrain
|
||||||
|
3073: 'ar', #Arabic - Egypt
|
||||||
|
2049: 'ar', #Arabic - Iraq
|
||||||
|
11265: 'ar', #Arabic - Jordan
|
||||||
|
13313: 'ar', #Arabic - Kuwait
|
||||||
|
12289: 'ar', #Arabic - Lebanon
|
||||||
|
4097: 'ar', #Arabic - Libya
|
||||||
|
6145: 'ar', #Arabic - Morocco
|
||||||
|
8193: 'ar', #Arabic - Oman
|
||||||
|
16385: 'ar', #Arabic - Qatar
|
||||||
|
10241: 'ar', #Arabic - Syria
|
||||||
|
7169: 'ar', #Arabic - Tunisia
|
||||||
|
14337: 'ar', #Arabic - U.A.E.
|
||||||
|
9217: 'ar', #Arabic - Yemen
|
||||||
|
1067: 'hy', #Armenian - Armenia
|
||||||
|
1101: 'as', #Assamese
|
||||||
|
2092: 'az', #Azeri (Cyrillic)
|
||||||
|
1068: 'az', #Azeri (Latin)
|
||||||
|
1069: 'eu', #Basque
|
||||||
|
1059: 'be', #Belarusian
|
||||||
|
1093: 'bn', #Bengali (India)
|
||||||
|
2117: 'bn', #Bengali (Bangladesh)
|
||||||
|
5146: 'bs', #Bosnian (Bosnia/Herzegovina)
|
||||||
|
1026: 'bg', #Bulgarian
|
||||||
|
1109: 'my', #Burmese
|
||||||
|
1027: 'ca', #Catalan
|
||||||
|
1116: 'chr', #Cherokee - United States
|
||||||
|
2052: 'zh', #Chinese - People's Republic of China
|
||||||
|
4100: 'zh', #Chinese - Singapore
|
||||||
|
1028: 'zh', #Chinese - Taiwan
|
||||||
|
3076: 'zh', #Chinese - Hong Kong SAR
|
||||||
|
5124: 'zh', #Chinese - Macao SAR
|
||||||
|
1050: 'hr', #Croatian
|
||||||
|
4122: 'hr', #Croatian (Bosnia/Herzegovina)
|
||||||
|
1029: 'cs', #Czech
|
||||||
|
1030: 'da', #Danish
|
||||||
|
1125: 'dv', #Divehi
|
||||||
|
1043: 'nl', #Dutch - Netherlands
|
||||||
|
2067: 'nl', #Dutch - Belgium
|
||||||
|
1126: 'bin', #Edo
|
||||||
|
1033: 'en', #English - United States
|
||||||
|
2057: 'en', #English - United Kingdom
|
||||||
|
3081: 'en', #English - Australia
|
||||||
|
10249: 'en', #English - Belize
|
||||||
|
4105: 'en', #English - Canada
|
||||||
|
9225: 'en', #English - Caribbean
|
||||||
|
15369: 'en', #English - Hong Kong SAR
|
||||||
|
16393: 'en', #English - India
|
||||||
|
14345: 'en', #English - Indonesia
|
||||||
|
6153: 'en', #English - Ireland
|
||||||
|
8201: 'en', #English - Jamaica
|
||||||
|
17417: 'en', #English - Malaysia
|
||||||
|
5129: 'en', #English - New Zealand
|
||||||
|
13321: 'en', #English - Philippines
|
||||||
|
18441: 'en', #English - Singapore
|
||||||
|
7177: 'en', #English - South Africa
|
||||||
|
11273: 'en', #English - Trinidad
|
||||||
|
12297: 'en', #English - Zimbabwe
|
||||||
|
1061: 'et', #Estonian
|
||||||
|
1080: 'fo', #Faroese
|
||||||
|
1065: None, #TODO: Farsi
|
||||||
|
1124: 'fil', #Filipino
|
||||||
|
1035: 'fi', #Finnish
|
||||||
|
1036: 'fr', #French - France
|
||||||
|
2060: 'fr', #French - Belgium
|
||||||
|
11276: 'fr', #French - Cameroon
|
||||||
|
3084: 'fr', #French - Canada
|
||||||
|
9228: 'fr', #French - Democratic Rep. of Congo
|
||||||
|
12300: 'fr', #French - Cote d'Ivoire
|
||||||
|
15372: 'fr', #French - Haiti
|
||||||
|
5132: 'fr', #French - Luxembourg
|
||||||
|
13324: 'fr', #French - Mali
|
||||||
|
6156: 'fr', #French - Monaco
|
||||||
|
14348: 'fr', #French - Morocco
|
||||||
|
58380: 'fr', #French - North Africa
|
||||||
|
8204: 'fr', #French - Reunion
|
||||||
|
10252: 'fr', #French - Senegal
|
||||||
|
4108: 'fr', #French - Switzerland
|
||||||
|
7180: 'fr', #French - West Indies
|
||||||
|
1122: 'fy', #Frisian - Netherlands
|
||||||
|
1127: None, #TODO: Fulfulde - Nigeria
|
||||||
|
1071: 'mk', #FYRO Macedonian
|
||||||
|
2108: 'ga', #Gaelic (Ireland)
|
||||||
|
1084: 'gd', #Gaelic (Scotland)
|
||||||
|
1110: 'gl', #Galician
|
||||||
|
1079: 'ka', #Georgian
|
||||||
|
1031: 'de', #German - Germany
|
||||||
|
3079: 'de', #German - Austria
|
||||||
|
5127: 'de', #German - Liechtenstein
|
||||||
|
4103: 'de', #German - Luxembourg
|
||||||
|
2055: 'de', #German - Switzerland
|
||||||
|
1032: 'el', #Greek
|
||||||
|
1140: 'gn', #Guarani - Paraguay
|
||||||
|
1095: 'gu', #Gujarati
|
||||||
|
1128: 'ha', #Hausa - Nigeria
|
||||||
|
1141: 'haw', #Hawaiian - United States
|
||||||
|
1037: 'he', #Hebrew
|
||||||
|
1081: 'hi', #Hindi
|
||||||
|
1038: 'hu', #Hungarian
|
||||||
|
1129: None, #TODO: Ibibio - Nigeria
|
||||||
|
1039: 'is', #Icelandic
|
||||||
|
1136: 'ig', #Igbo - Nigeria
|
||||||
|
1057: 'id', #Indonesian
|
||||||
|
1117: 'iu', #Inuktitut
|
||||||
|
1040: 'it', #Italian - Italy
|
||||||
|
2064: 'it', #Italian - Switzerland
|
||||||
|
1041: 'ja', #Japanese
|
||||||
|
1099: 'kn', #Kannada
|
||||||
|
1137: 'kr', #Kanuri - Nigeria
|
||||||
|
2144: 'ks', #Kashmiri
|
||||||
|
1120: 'ks', #Kashmiri (Arabic)
|
||||||
|
1087: 'kk', #Kazakh
|
||||||
|
1107: 'km', #Khmer
|
||||||
|
1111: 'kok', #Konkani
|
||||||
|
1042: 'ko', #Korean
|
||||||
|
1088: 'ky', #Kyrgyz (Cyrillic)
|
||||||
|
1108: 'lo', #Lao
|
||||||
|
1142: 'la', #Latin
|
||||||
|
1062: 'lv', #Latvian
|
||||||
|
1063: 'lt', #Lithuanian
|
||||||
|
1086: 'ms', #Malay - Malaysia
|
||||||
|
2110: 'ms', #Malay - Brunei Darussalam
|
||||||
|
1100: 'ml', #Malayalam
|
||||||
|
1082: 'mt', #Maltese
|
||||||
|
1112: 'mni', #Manipuri
|
||||||
|
1153: 'mi', #Maori - New Zealand
|
||||||
|
1102: 'mr', #Marathi
|
||||||
|
1104: 'mn', #Mongolian (Cyrillic)
|
||||||
|
2128: 'mn', #Mongolian (Mongolian)
|
||||||
|
1121: 'ne', #Nepali
|
||||||
|
2145: 'ne', #Nepali - India
|
||||||
|
1044: 'no', #Norwegian (Bokm??l)
|
||||||
|
2068: 'no', #Norwegian (Nynorsk)
|
||||||
|
1096: 'or', #Oriya
|
||||||
|
1138: 'om', #Oromo
|
||||||
|
1145: 'pap', #Papiamentu
|
||||||
|
1123: 'ps', #Pashto
|
||||||
|
1045: 'pl', #Polish
|
||||||
|
1046: 'pt', #Portuguese - Brazil
|
||||||
|
2070: 'pt', #Portuguese - Portugal
|
||||||
|
1094: 'pa', #Punjabi
|
||||||
|
2118: 'pa', #Punjabi (Pakistan)
|
||||||
|
1131: 'qu', #Quecha - Bolivia
|
||||||
|
2155: 'qu', #Quecha - Ecuador
|
||||||
|
3179: 'qu', #Quecha - Peru
|
||||||
|
1047: 'rm', #Rhaeto-Romanic
|
||||||
|
1048: 'ro', #Romanian
|
||||||
|
2072: 'ro', #Romanian - Moldava
|
||||||
|
1049: 'ru', #Russian
|
||||||
|
2073: 'ru', #Russian - Moldava
|
||||||
|
1083: 'se', #Sami (Lappish)
|
||||||
|
1103: 'sa', #Sanskrit
|
||||||
|
1132: 'nso', #Sepedi
|
||||||
|
3098: 'sr', #Serbian (Cyrillic)
|
||||||
|
2074: 'sr', #Serbian (Latin)
|
||||||
|
1113: 'sd', #Sindhi - India
|
||||||
|
2137: 'sd', #Sindhi - Pakistan
|
||||||
|
1115: 'si', #Sinhalese - Sri Lanka
|
||||||
|
1051: 'sk', #Slovak
|
||||||
|
1060: 'sl', #Slovenian
|
||||||
|
1143: 'so', #Somali
|
||||||
|
1070: 'wen', #Sorbian
|
||||||
|
3082: 'es', #Spanish - Spain (Modern Sort)
|
||||||
|
1034: 'es', #Spanish - Spain (Traditional Sort)
|
||||||
|
11274: 'es', #Spanish - Argentina
|
||||||
|
16394: 'es', #Spanish - Bolivia
|
||||||
|
13322: 'es', #Spanish - Chile
|
||||||
|
9226: 'es', #Spanish - Colombia
|
||||||
|
5130: 'es', #Spanish - Costa Rica
|
||||||
|
7178: 'es', #Spanish - Dominican Republic
|
||||||
|
12298: 'es', #Spanish - Ecuador
|
||||||
|
17418: 'es', #Spanish - El Salvador
|
||||||
|
4106: 'es', #Spanish - Guatemala
|
||||||
|
18442: 'es', #Spanish - Honduras
|
||||||
|
58378: 'es', #Spanish - Latin America
|
||||||
|
2058: 'es', #Spanish - Mexico
|
||||||
|
19466: 'es', #Spanish - Nicaragua
|
||||||
|
6154: 'es', #Spanish - Panama
|
||||||
|
15370: 'es', #Spanish - Paraguay
|
||||||
|
10250: 'es', #Spanish - Peru
|
||||||
|
20490: 'es', #Spanish - Puerto Rico
|
||||||
|
21514: 'es', #Spanish - United States
|
||||||
|
14346: 'es', #Spanish - Uruguay
|
||||||
|
8202: 'es', #Spanish - Venezuela
|
||||||
|
1072: None, #TODO: Sutu
|
||||||
|
1089: 'sw', #Swahili
|
||||||
|
1053: 'sv', #Swedish
|
||||||
|
2077: 'sv', #Swedish - Finland
|
||||||
|
1114: 'syr', #Syriac
|
||||||
|
1064: 'tg', #Tajik
|
||||||
|
1119: None, #TODO: Tamazight (Arabic)
|
||||||
|
2143: None, #TODO: Tamazight (Latin)
|
||||||
|
1097: 'ta', #Tamil
|
||||||
|
1092: 'tt', #Tatar
|
||||||
|
1098: 'te', #Telugu
|
||||||
|
1054: 'th', #Thai
|
||||||
|
2129: 'bo', #Tibetan - Bhutan
|
||||||
|
1105: 'bo', #Tibetan - People's Republic of China
|
||||||
|
2163: 'ti', #Tigrigna - Eritrea
|
||||||
|
1139: 'ti', #Tigrigna - Ethiopia
|
||||||
|
1073: 'ts', #Tsonga
|
||||||
|
1074: 'tn', #Tswana
|
||||||
|
1055: 'tr', #Turkish
|
||||||
|
1090: 'tk', #Turkmen
|
||||||
|
1152: 'ug', #Uighur - China
|
||||||
|
1058: 'uk', #Ukrainian
|
||||||
|
1056: 'ur', #Urdu
|
||||||
|
2080: 'ur', #Urdu - India
|
||||||
|
2115: 'uz', #Uzbek (Cyrillic)
|
||||||
|
1091: 'uz', #Uzbek (Latin)
|
||||||
|
1075: 've', #Venda
|
||||||
|
1066: 'vi', #Vietnamese
|
||||||
|
1106: 'cy', #Welsh
|
||||||
|
1076: 'xh', #Xhosa
|
||||||
|
1144: 'ii', #Yi
|
||||||
|
1085: 'yi', #Yiddish
|
||||||
|
1130: 'yo', #Yoruba
|
||||||
|
1077: 'zu'} #Zulu
|
||||||
|
|
||||||
|
return mapping[lcid]
|
||||||
|
|
||||||
|
def _getscreenlanguage():
|
||||||
|
global language_code
|
||||||
|
'''
|
||||||
|
:returns: the ISO 639-x language code for this session.
|
||||||
|
|
||||||
|
If the LANGUAGE environment variable is set, it's value overrides the
|
||||||
|
screen language detection. Otherwise the screen language is determined by
|
||||||
|
the currently selected Microsoft Windows MUI language pack or the Microsoft
|
||||||
|
Windows installation language.
|
||||||
|
|
||||||
|
Works on Microsoft Windows 2000 and up.
|
||||||
|
'''
|
||||||
|
if sys.platform == 'win32' or sys.platform == 'nt':
|
||||||
|
# Start with nothing
|
||||||
|
lang = None
|
||||||
|
|
||||||
|
# Check the LANGUAGE environment variable
|
||||||
|
lang = os.getenv('LANGUAGE')
|
||||||
|
if language_code != "" :
|
||||||
|
lang = language_code
|
||||||
|
if lang is None:
|
||||||
|
# Start with nothing
|
||||||
|
lcid = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
from ctypes import windll
|
||||||
|
lcid = windll.kernel32.GetUserDefaultUILanguage()
|
||||||
|
except:
|
||||||
|
logger.debug('Failed to get current screen language with \'GetUserDefaultUILanguage\'')
|
||||||
|
finally:
|
||||||
|
if lcid is None:
|
||||||
|
lang = 'C'
|
||||||
|
else:
|
||||||
|
lang = _isofromlcid(lcid)
|
||||||
|
|
||||||
|
logger.debug('Windows screen language is \'%s\' (lcid %s)' % (lang, lcid))
|
||||||
|
|
||||||
|
return lang
|
||||||
|
|
||||||
|
def _putenv(name, value):
|
||||||
|
'''
|
||||||
|
:param name: environment variable name
|
||||||
|
:param value: environment variable value
|
||||||
|
|
||||||
|
This function ensures that changes to an environment variable are applied
|
||||||
|
to each copy of the environment variables used by a process. Starting from
|
||||||
|
Python 2.4, os.environ changes only apply to the copy Python keeps (os.environ)
|
||||||
|
and are no longer automatically applied to the other copies for the process.
|
||||||
|
|
||||||
|
On Microsoft Windows, each process has multiple copies of the environment
|
||||||
|
variables, one managed by the OS and one managed by the C library. We also
|
||||||
|
need to take care of the fact that the C library used by Python is not
|
||||||
|
necessarily the same as the C library used by pygtk and friends. This because
|
||||||
|
the latest releases of pygtk and friends are built with mingw32 and are thus
|
||||||
|
linked against msvcrt.dll. The official gtk+ binaries have always been built
|
||||||
|
in this way.
|
||||||
|
'''
|
||||||
|
|
||||||
|
if sys.platform == 'win32' or sys.platform == 'nt':
|
||||||
|
from ctypes import windll
|
||||||
|
from ctypes import cdll
|
||||||
|
from ctypes.util import find_msvcrt
|
||||||
|
|
||||||
|
# Update Python's copy of the environment variables
|
||||||
|
os.environ[name] = value
|
||||||
|
|
||||||
|
# Update the copy maintained by Windows (so SysInternals Process Explorer sees it)
|
||||||
|
try:
|
||||||
|
result = windll.kernel32.SetEnvironmentVariableW(name, value)
|
||||||
|
if result == 0: raise Warning
|
||||||
|
except Exception:
|
||||||
|
logger.debug('Failed to set environment variable \'%s\' (\'kernel32.SetEnvironmentVariableW\')' % name)
|
||||||
|
else:
|
||||||
|
logger.debug('Set environment variable \'%s\' to \'%s\' (\'kernel32.SetEnvironmentVariableW\')' % (name, value))
|
||||||
|
|
||||||
|
# Update the copy maintained by msvcrt (used by gtk+ runtime)
|
||||||
|
try:
|
||||||
|
result = cdll.msvcrt._putenv('%s=%s' % (name, value))
|
||||||
|
if result !=0: raise Warning
|
||||||
|
except Exception:
|
||||||
|
logger.debug('Failed to set environment variable \'%s\' (\'msvcrt._putenv\')' % name)
|
||||||
|
else:
|
||||||
|
logger.debug('Set environment variable \'%s\' to \'%s\' (\'msvcrt._putenv\')' % (name, value))
|
||||||
|
|
||||||
|
# Update the copy maintained by whatever c runtime is used by Python
|
||||||
|
try:
|
||||||
|
msvcrt = find_msvcrt()
|
||||||
|
msvcrtname = str(msvcrt).split('.')[0] if '.' in msvcrt else str(msvcrt)
|
||||||
|
result = cdll.LoadLibrary(msvcrt)._putenv('%s=%s' % (name, value))
|
||||||
|
if result != 0: raise Warning
|
||||||
|
except Exception:
|
||||||
|
logger.debug('Failed to set environment variable \'%s\' (\'%s._putenv\')' % (name, msvcrtname))
|
||||||
|
else:
|
||||||
|
logger.debug('Set environment variable \'%s\' to \'%s\' (\'%s._putenv\')' % (name, value, msvcrtname))
|
||||||
|
|
||||||
|
def _dugettext(domain, message):
|
||||||
|
'''
|
||||||
|
:param domain: translation domain
|
||||||
|
:param message: message to translate
|
||||||
|
:returns: the translated message
|
||||||
|
|
||||||
|
Unicode version of :func:`gettext.dgettext`.
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
t = gettext.translation(domain, gettext._localedirs.get(domain, None),
|
||||||
|
codeset=gettext._localecodesets.get(domain))
|
||||||
|
except IOError:
|
||||||
|
return message
|
||||||
|
else:
|
||||||
|
return t.ugettext(message)
|
||||||
|
|
||||||
|
def _install(domain, localedir, asglobal=False):
|
||||||
|
'''
|
||||||
|
:param domain: translation domain
|
||||||
|
:param localedir: locale directory
|
||||||
|
:param asglobal: if True, installs the function _() in Python<EFBFBD>s builtin namespace. Default is False
|
||||||
|
|
||||||
|
Private function doing all the work for the :func:`elib.intl.install` and
|
||||||
|
:func:`elib.intl.install_module` functions.
|
||||||
|
'''
|
||||||
|
# prep locale system
|
||||||
|
if asglobal:
|
||||||
|
locale.setlocale(locale.LC_ALL, '')
|
||||||
|
|
||||||
|
# on windows systems, set the LANGUAGE environment variable
|
||||||
|
if sys.platform == 'win32' or sys.platform == 'nt':
|
||||||
|
_putenv('LANGUAGE', _getscreenlanguage())
|
||||||
|
#print "=========2>", os.getenv('LANGUAGE')
|
||||||
|
#print ("=========2>",_getscreenlanguage())
|
||||||
|
|
||||||
|
|
||||||
|
# The locale module on Max OS X lacks bindtextdomain so we specifically
|
||||||
|
# test on linux2 here. See commit 4ae8b26fd569382ab66a9e844daa0e01de409ceb
|
||||||
|
if sys.platform == 'linux2':
|
||||||
|
locale.bindtextdomain(domain, localedir)
|
||||||
|
locale.bind_textdomain_codeset(domain, 'UTF-8')
|
||||||
|
locale.textdomain(domain)
|
||||||
|
|
||||||
|
# initialize Python's gettext interface
|
||||||
|
gettext.bindtextdomain(domain, localedir)
|
||||||
|
gettext.bind_textdomain_codeset(domain, 'UTF-8')
|
||||||
|
|
||||||
|
if asglobal:
|
||||||
|
gettext.textdomain(domain)
|
||||||
|
|
||||||
|
# on windows systems, initialize libintl
|
||||||
|
domain = domain.encode("cp1252")
|
||||||
|
localedir = localedir.encode("cp1252")
|
||||||
|
if sys.platform == 'win32' or sys.platform == 'nt':
|
||||||
|
from ctypes import cdll
|
||||||
|
libintl = cdll.LoadLibrary("libintl-8.dll")
|
||||||
|
libintl.bindtextdomain(domain, localedir)
|
||||||
|
libintl.bind_textdomain_codeset(domain, 'UTF-8')
|
||||||
|
|
||||||
|
if asglobal:
|
||||||
|
libintl.textdomain(domain)
|
||||||
|
|
||||||
|
del libintl
|
||||||
|
|
||||||
|
def install(domain, localedir, code = ""):
|
||||||
|
'''
|
||||||
|
:param domain: translation domain
|
||||||
|
:param localedir: locale directory
|
||||||
|
:param code: Language code required. Default means autodetect.
|
||||||
|
|
||||||
|
Installs the function _() in Python<EFBFBD>s builtin namespace, based on
|
||||||
|
domain and localedir. Codeset is always UTF-8.
|
||||||
|
|
||||||
|
As seen below, you usually mark the strings in your application that are
|
||||||
|
candidates for translation, by wrapping them in a call to the _() function,
|
||||||
|
like this:
|
||||||
|
|
||||||
|
.. sourcecode:: python
|
||||||
|
|
||||||
|
import elib.intl
|
||||||
|
elib.intl.install('myapplication', '/path/to/usr/share/locale')
|
||||||
|
print _('This string will be translated.')
|
||||||
|
|
||||||
|
Note that this is only one way, albeit the most convenient way,
|
||||||
|
to make the _() function available to your application. Because it affects
|
||||||
|
the entire application globally, and specifically Python<EFBFBD>s built-in
|
||||||
|
namespace, localized modules should never install _(). Instead, you should
|
||||||
|
use :func:`elib.intl.install_module` to make _() available to your module.
|
||||||
|
'''
|
||||||
|
|
||||||
|
global language_code
|
||||||
|
language_code = code
|
||||||
|
|
||||||
|
_install(domain, localedir, True)
|
||||||
|
gettext.install(domain, localedir)
|
||||||
|
|
||||||
|
def install_module(domain, localedir):
|
||||||
|
'''
|
||||||
|
:param domain: translation domain
|
||||||
|
:param localedir: locale directory
|
||||||
|
:returns: an anonymous function object, based on domain and localedir.
|
||||||
|
Codeset is always UTF-8.
|
||||||
|
|
||||||
|
You may find this function usefull when writing localized modules.
|
||||||
|
Use this code to make _() available to your module:
|
||||||
|
|
||||||
|
.. sourcecode:: python
|
||||||
|
|
||||||
|
import elib.intl
|
||||||
|
_ = elib.intl.install_module('mymodule', '/path/to/usr/share/locale')
|
||||||
|
print _('This string will be translated.')
|
||||||
|
|
||||||
|
When writing a package, you can usually do this in the package's __init__.py
|
||||||
|
file and import the _() function from the package namespace as needed.
|
||||||
|
'''
|
||||||
|
_install(domain, localedir, False)
|
||||||
|
return lambda message: _dugettext(domain, message)
|
||||||
|
|
||||||
|
|
||||||
|
def main() :
|
||||||
|
language = ""
|
||||||
|
if sys.platform == 'win32' or sys.platform == 'nt':
|
||||||
|
install("pdfbooklet", "share/locale", language)
|
||||||
|
print (_getscreenlanguage())
|
||||||
|
else :
|
||||||
|
install("pdfbooklet", "/usr/share/locale", language)
|
||||||
|
print (_("There is no selection"))
|
||||||
|
if __name__ == '__main__' :
|
||||||
|
main()
|
@ -0,0 +1,183 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# coding: utf-8 -*-
|
||||||
|
|
||||||
|
|
||||||
|
# version 3.0.3
|
||||||
|
|
||||||
|
|
||||||
|
import os, sys
|
||||||
|
|
||||||
|
|
||||||
|
from gi.repository import Gtk, Gio
|
||||||
|
from pdfbooklet.PyPDF2_G import PdfFileReader
|
||||||
|
|
||||||
|
|
||||||
|
def alert(message, type = 0) :
|
||||||
|
|
||||||
|
dialog = Gtk.MessageDialog(None, Gtk.DialogFlags.MODAL, Gtk.MessageType.WARNING,
|
||||||
|
Gtk.ButtonsType.CLOSE , message)
|
||||||
|
dialog.run()
|
||||||
|
dialog.destroy()
|
||||||
|
|
||||||
|
class Chooser:
|
||||||
|
def __init__(self,
|
||||||
|
inputFiles_a = None,
|
||||||
|
share_path_u = "",
|
||||||
|
mru_dir = ""):
|
||||||
|
|
||||||
|
self.inputFiles_a = inputFiles_a
|
||||||
|
self.chooser1 = Gtk.Builder()
|
||||||
|
self.chooser1.add_from_file(os.path.join(share_path_u, 'data/chooser_dialog.glade'))
|
||||||
|
self.chooser1.connect_signals(self)
|
||||||
|
self.chooser = self.chooser1.get_object("filechooserdialog1")
|
||||||
|
|
||||||
|
# treeview
|
||||||
|
self.treeview1 = self.chooser1.get_object("treeview1")
|
||||||
|
|
||||||
|
# create a TreeStore with one string column to use as the model
|
||||||
|
#self.treestore = self.treeview1.get_model()
|
||||||
|
self.treestore = Gtk.ListStore(str,int)
|
||||||
|
self.cell = Gtk.CellRendererText()
|
||||||
|
|
||||||
|
# set the model for TreeView
|
||||||
|
self.treeview1.set_model(self.treestore)
|
||||||
|
self.tvcolumn = Gtk.TreeViewColumn(_('Filename'))
|
||||||
|
self.treeview1.append_column(self.tvcolumn)
|
||||||
|
|
||||||
|
# add the cell to the tvcolumn and allow it to expand
|
||||||
|
self.tvcolumn.pack_start(self.cell, True)
|
||||||
|
|
||||||
|
# set the cell "text" attribute to column 0 - retrieve text
|
||||||
|
# from that column in treestore
|
||||||
|
self.tvcolumn.add_attribute(self.cell, 'text', 0)
|
||||||
|
|
||||||
|
## self.tvcolumn = Gtk.TreeViewColumn(_('Pages'))
|
||||||
|
## self.treeview1.append_column(self.tvcolumn)
|
||||||
|
## self.tvcolumn.pack_start(self.cell, True)
|
||||||
|
## self.tvcolumn.add_attribute(self.cell, 'text', 1)
|
||||||
|
|
||||||
|
# Allow drag and drop reordering of rows
|
||||||
|
self.treeview1.set_reorderable(True)
|
||||||
|
|
||||||
|
# load files in parameter list
|
||||||
|
for key in self.inputFiles_a :
|
||||||
|
self.treestore.append([self.inputFiles_a[key], 0])
|
||||||
|
|
||||||
|
|
||||||
|
old_dir = ""
|
||||||
|
old_name = ""
|
||||||
|
|
||||||
|
|
||||||
|
chooser = self.chooser1.get_object("filechooserdialog1")
|
||||||
|
chooser.set_current_folder(mru_dir)
|
||||||
|
chooser.set_select_multiple(True)
|
||||||
|
|
||||||
|
filter_all = Gtk.FileFilter()
|
||||||
|
filter_all.set_name(_('All files'))
|
||||||
|
filter_all.add_pattern('*')
|
||||||
|
chooser.add_filter(filter_all)
|
||||||
|
|
||||||
|
filter_pdf = Gtk.FileFilter()
|
||||||
|
filter_pdf.set_name(_('PDF files'))
|
||||||
|
filter_pdf.add_mime_type('application/pdf')
|
||||||
|
filter_pdf.add_pattern('*.pdf')
|
||||||
|
chooser.add_filter(filter_pdf)
|
||||||
|
chooser.set_filter(filter_pdf)
|
||||||
|
|
||||||
|
response = chooser.run()
|
||||||
|
|
||||||
|
|
||||||
|
def chooserClose(self, widget) :
|
||||||
|
self.chooser.destroy()
|
||||||
|
|
||||||
|
def chooserOK(self, widget) :
|
||||||
|
self.treestore.clear()
|
||||||
|
self.genFilesArray()
|
||||||
|
self.chooser.destroy()
|
||||||
|
|
||||||
|
def pdf_remove(self, widget) :
|
||||||
|
selection = self.treeview1.get_selection()
|
||||||
|
#sel = selection.get_selected_rows()
|
||||||
|
model, iter0 = selection.get_selected()
|
||||||
|
model.remove(iter0)
|
||||||
|
|
||||||
|
def pdf_up(self, widget) :
|
||||||
|
selection = self.treeview1.get_selection()
|
||||||
|
model, iter0 = selection.get_selected()
|
||||||
|
string = model.get_string_from_iter(iter0)
|
||||||
|
newpos = int(string) - 1
|
||||||
|
if newpos < 0 : newpos = 0
|
||||||
|
newpos = model.get_iter_from_string(str(newpos))
|
||||||
|
model.move_before(iter0, newpos)
|
||||||
|
|
||||||
|
def pdf_down(self, widget) :
|
||||||
|
selection = self.treeview1.get_selection()
|
||||||
|
model, iter0 = selection.get_selected()
|
||||||
|
model.move_after(iter0, model.iter_next(iter0))
|
||||||
|
|
||||||
|
# clears the list and open a file
|
||||||
|
def pdf_open(self,widget) :
|
||||||
|
self.treestore.clear()
|
||||||
|
self.add_file("")
|
||||||
|
|
||||||
|
def add_file(self, widget):
|
||||||
|
|
||||||
|
for filename in self.chooser.get_filenames():
|
||||||
|
if os.path.isfile(filename):
|
||||||
|
# FIXME
|
||||||
|
## f = Gio.File(filename)
|
||||||
|
## f_info = f.query_info('standard::content-type')
|
||||||
|
## mime_type = f_info.get_content_type()
|
||||||
|
mime_type = ".pdf"
|
||||||
|
if mime_type == 'application/pdf' or mime_type == '.pdf':
|
||||||
|
self.loadPdfFile(filename)
|
||||||
|
else :
|
||||||
|
print(_('File type not supported!'))
|
||||||
|
else:
|
||||||
|
print(_('File %s does not exist') % filename)
|
||||||
|
|
||||||
|
|
||||||
|
def loadPdfFile(self,filename) :
|
||||||
|
|
||||||
|
pdfFile = PdfFileReader(open(filename, "rb"))
|
||||||
|
numpages = pdfFile.getNumPages()
|
||||||
|
self.treestore.append([filename, numpages])
|
||||||
|
|
||||||
|
# regenerate the array of files (easier to use than the treestore)
|
||||||
|
def genFilesArray(self, dummy = "") :
|
||||||
|
inputFiles_a = {}
|
||||||
|
selectedFiles1 = self.chooser.get_filenames()
|
||||||
|
|
||||||
|
# eliminate directories
|
||||||
|
selectedFiles = []
|
||||||
|
for file_u in selectedFiles1 :
|
||||||
|
if os.path.isdir(file_u) :
|
||||||
|
alert(_("You have chosen a directory, it is not supported"))
|
||||||
|
else :
|
||||||
|
# FIXME
|
||||||
|
## f = gio.File(filename)
|
||||||
|
## f_info = f.query_info('standard::content-type')
|
||||||
|
## mime_type = f_info.get_content_type()
|
||||||
|
## if mime_type == 'application/pdf' or mime_type == '.pdf':
|
||||||
|
## self.loadPdfFile(filename)
|
||||||
|
## else :
|
||||||
|
## print(_('File type not supported!'))
|
||||||
|
selectedFiles.append(file_u)
|
||||||
|
|
||||||
|
if len(selectedFiles) == 0 :
|
||||||
|
print(_('Closed, no files selected'))
|
||||||
|
return
|
||||||
|
|
||||||
|
size_i = len(self.treestore)
|
||||||
|
|
||||||
|
if size_i == 0 : # nothing in the list
|
||||||
|
for i in range(len(selectedFiles)) :
|
||||||
|
inputFiles_a[i + 1] = selectedFiles[i]
|
||||||
|
else : # use the list
|
||||||
|
for i in range(size_i) :
|
||||||
|
iter0 = self.treestore.get_iter(i)
|
||||||
|
filename_s = self.treestore.get_value(iter0,0)
|
||||||
|
inputFiles_a[i + 1] = filename_s
|
||||||
|
self.inputFiles_a = inputFiles_a
|
||||||
|
|
||||||
|
|
@ -0,0 +1,163 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
PdfShuffler 0.6.0 - GTK+ based utility for splitting, rearrangement and
|
||||||
|
modification of PDF documents.
|
||||||
|
Copyright (C) 2008-2012 Konstantinos Poulios
|
||||||
|
<https://sourceforge.net/projects/pdfshuffler>
|
||||||
|
|
||||||
|
This file is part of PdfShuffler.
|
||||||
|
|
||||||
|
PdfShuffler is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from gi.repository import Gtk, GObject
|
||||||
|
from gi.repository import cairo
|
||||||
|
|
||||||
|
from math import pi as M_PI
|
||||||
|
|
||||||
|
class CellRendererImage(Gtk.CellRenderer):
|
||||||
|
__gproperties__ = {
|
||||||
|
"image": (GObject.TYPE_PYOBJECT, "Image", "Image",
|
||||||
|
GObject.PARAM_READWRITE),
|
||||||
|
"width": (GObject.TYPE_FLOAT, "Width", "Width",
|
||||||
|
0., 1.e4, 0., GObject.PARAM_READWRITE),
|
||||||
|
"height": (GObject.TYPE_FLOAT, "Height", "Height",
|
||||||
|
0., 1.e4, 0., GObject.PARAM_READWRITE),
|
||||||
|
"rotation": (GObject.TYPE_INT, "Rotation", "Rotation",
|
||||||
|
0, 360, 0, GObject.PARAM_READWRITE),
|
||||||
|
"scale": (GObject.TYPE_FLOAT, "Scale", "Scale",
|
||||||
|
0.01, 100., 1., GObject.PARAM_READWRITE),
|
||||||
|
"resample": (GObject.TYPE_FLOAT,
|
||||||
|
"Resample", "Resample Coefficient",
|
||||||
|
1., 100., 1., GObject.PARAM_READWRITE),
|
||||||
|
"cropL": (GObject.TYPE_FLOAT, "CropL", "CropL",
|
||||||
|
0., 1., 0., GObject.PARAM_READWRITE),
|
||||||
|
"cropR": (GObject.TYPE_FLOAT, "CropR", "CropR",
|
||||||
|
0., 1., 0., GObject.PARAM_READWRITE),
|
||||||
|
"cropT": (GObject.TYPE_FLOAT, "CropT", "CropT",
|
||||||
|
0., 1., 0., GObject.PARAM_READWRITE),
|
||||||
|
"cropB": (GObject.TYPE_FLOAT, "CropB", "CropB",
|
||||||
|
0., 1., 0., GObject.PARAM_READWRITE),
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
## self.__GObject_init__() Original code modified in the line below
|
||||||
|
Gtk.CellRendererText.__init__(self)
|
||||||
|
GObject.GObject.__init__(self)
|
||||||
|
self.th1 = 2. # border thickness
|
||||||
|
self.th2 = 3. # shadow thickness
|
||||||
|
|
||||||
|
def get_geometry(self):
|
||||||
|
|
||||||
|
rotation = int(self.rotation) % 360
|
||||||
|
rotation = ((rotation) / 90) * 90
|
||||||
|
if not self.image:
|
||||||
|
w0 = w1 = self.width / self.resample
|
||||||
|
h0 = h1 = self.height / self.resample
|
||||||
|
else:
|
||||||
|
w0 = self.image.get_width()
|
||||||
|
h0 = self.image.get_height()
|
||||||
|
if rotation == 90 or rotation == 270:
|
||||||
|
w1, h1 = h0, w0
|
||||||
|
else:
|
||||||
|
w1, h1 = w0, h0
|
||||||
|
|
||||||
|
x = self.cropL * w1
|
||||||
|
y = self.cropT * h1
|
||||||
|
|
||||||
|
scale = self.resample * self.scale
|
||||||
|
w2 = int(scale * (1. - self.cropL - self.cropR) * w1)
|
||||||
|
h2 = int(scale * (1. - self.cropT - self.cropB) * h1)
|
||||||
|
|
||||||
|
return w0,h0,w1,h1,w2,h2,rotation
|
||||||
|
|
||||||
|
def do_set_property(self, pspec, value):
|
||||||
|
setattr(self, pspec.name, value)
|
||||||
|
|
||||||
|
def do_get_property(self, pspec):
|
||||||
|
return getattr(self, pspec.name)
|
||||||
|
|
||||||
|
def do_render(self, window, widget, cell_area, \
|
||||||
|
expose_area, flags):
|
||||||
|
if not self.image:
|
||||||
|
return
|
||||||
|
|
||||||
|
w0,h0,w1,h1,w2,h2,rotation = self.get_geometry()
|
||||||
|
th = int(2*self.th1+self.th2)
|
||||||
|
w = w2 + th
|
||||||
|
h = h2 + th
|
||||||
|
|
||||||
|
x = cell_area.x
|
||||||
|
y = cell_area.y
|
||||||
|
if cell_area and w > 0 and h > 0:
|
||||||
|
x += self.get_property('xalign') * \
|
||||||
|
(cell_area.width - w - self.get_property('xpad'))
|
||||||
|
y += self.get_property('yalign') * \
|
||||||
|
(cell_area.height - h - self.get_property('ypad'))
|
||||||
|
|
||||||
|
cr = window # cr = window.cairo_create()
|
||||||
|
cr.translate(x,y)
|
||||||
|
|
||||||
|
x = self.cropL * w1
|
||||||
|
y = self.cropT * h1
|
||||||
|
|
||||||
|
#shadow
|
||||||
|
cr.set_source_rgb(0.5, 0.5, 1)
|
||||||
|
cr.rectangle(th, th, w2, h2)
|
||||||
|
cr.fill()
|
||||||
|
|
||||||
|
#border
|
||||||
|
cr.set_source_rgb(0, 0, 0)
|
||||||
|
cr.rectangle(0, 0, w2+2*self.th1, h2+2*self.th1)
|
||||||
|
cr.fill()
|
||||||
|
|
||||||
|
#image
|
||||||
|
cr.set_source_rgb(1, 1, 1)
|
||||||
|
cr.rectangle(self.th1, self.th1, w2, h2)
|
||||||
|
cr.fill_preserve()
|
||||||
|
cr.clip()
|
||||||
|
|
||||||
|
cr.translate(self.th1,self.th1)
|
||||||
|
scale = self.resample * self.scale
|
||||||
|
cr.scale(scale, scale)
|
||||||
|
cr.translate(-x,-y)
|
||||||
|
if rotation > 0:
|
||||||
|
cr.translate(w1/2,h1/2)
|
||||||
|
cr.rotate(rotation * M_PI / 180)
|
||||||
|
cr.translate(-w0/2,-h0/2)
|
||||||
|
|
||||||
|
cr.set_source_surface(self.image)
|
||||||
|
cr.paint()
|
||||||
|
|
||||||
|
def do_get_size(self, widget, cell_area=None):
|
||||||
|
x = y = 0
|
||||||
|
w0,h0,w1,h1,w2,h2,rotation = self.get_geometry()
|
||||||
|
th = int(2*self.th1+self.th2)
|
||||||
|
w = w2 + th
|
||||||
|
h = h2 + th
|
||||||
|
|
||||||
|
if cell_area and w > 0 and h > 0:
|
||||||
|
x = self.get_property('xalign') * \
|
||||||
|
(cell_area.width - w - self.get_property('xpad'))
|
||||||
|
y = self.get_property('yalign') * \
|
||||||
|
(cell_area.height - h - self.get_property('ypad'))
|
||||||
|
w += 2 * self.get_property('xpad')
|
||||||
|
h += 2 * self.get_property('ypad')
|
||||||
|
return int(x), int(y), w, h
|
||||||
|
|
@ -0,0 +1,10 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
Version=2.0
|
||||||
|
Name=PDF-Booklet
|
||||||
|
Comment=PDF Merging, Rearranging, Splitting, Rotating and Cropping
|
||||||
|
Type=Application
|
||||||
|
Exec=pdfbooklet
|
||||||
|
Icon=pdfbooklet
|
||||||
|
Categories=Office;
|
||||||
|
Terminal=false
|
||||||
|
StartupNotify=false
|
@ -0,0 +1,8 @@
|
|||||||
|
This package was debianized by the alien program by converting
|
||||||
|
a binary .tgz package on Fri, 05 Jul 2019 11:09:47 +0000
|
||||||
|
|
||||||
|
Copyright: unknown
|
||||||
|
|
||||||
|
Information from the binary package:
|
||||||
|
-rw-rw-r-- 1 travis travis 5324800 Jul 5 11:09 ./pdfbooklet-3.1.2-all_64_corr.tar.gz
|
||||||
|
|
1286
pdfbooklet_3.1.2-3_all/usr/share/locale/fr/LC_MESSAGES/pdfbooklet.po
Normal file
@ -0,0 +1,281 @@
|
|||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: PDF-Shuffler 0.5\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2015-08-18 08:12+0200\n"
|
||||||
|
"PO-Revision-Date: 2015-08-18 08:26+0100\n"
|
||||||
|
"Last-Translator: DP <daniel.pot@wanadoo.fr>\n"
|
||||||
|
"Language-Team: Emmanuel <emmanuel@simple-linux.com>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Poedit-Language: french\n"
|
||||||
|
"X-Poedit-Country: FRANCE\n"
|
||||||
|
|
||||||
|
#: ..\..\..\pdfshuffler_g.py:127
|
||||||
|
msgid "Can't load icon. Application is not installed correctly."
|
||||||
|
msgstr "Impossible de charger l'icône. L'application n'est pas installée correctement."
|
||||||
|
|
||||||
|
#: ..\..\..\pdfshuffler_g.py:318
|
||||||
|
msgid "No document"
|
||||||
|
msgstr "Pas de document"
|
||||||
|
|
||||||
|
#: ..\..\..\pdfshuffler_g.py:320
|
||||||
|
msgid "Several documents"
|
||||||
|
msgstr "Plusieurs documents"
|
||||||
|
|
||||||
|
#: ..\..\..\pdfshuffler_g.py:336
|
||||||
|
#, python-format
|
||||||
|
msgid "Rendering thumbnails... [%(i1)s/%(i2)s]"
|
||||||
|
msgstr "Rendu miniatures... [%(i1)s/%(i2)s]"
|
||||||
|
|
||||||
|
#: ..\..\..\pdfshuffler_g.py:453
|
||||||
|
msgid "page"
|
||||||
|
msgstr "page"
|
||||||
|
|
||||||
|
#: ..\..\..\pdfshuffler_g.py:479
|
||||||
|
msgid "Export ..."
|
||||||
|
msgstr "Exporter ..."
|
||||||
|
|
||||||
|
#: ..\..\..\pdfshuffler_g.py:488
|
||||||
|
#: ..\..\..\pdfshuffler_g.py:610
|
||||||
|
msgid "PDF files"
|
||||||
|
msgstr "Fichier PDF"
|
||||||
|
|
||||||
|
#: ..\..\..\pdfshuffler_g.py:494
|
||||||
|
#: ..\..\..\pdfshuffler_g.py:605
|
||||||
|
msgid "All files"
|
||||||
|
msgstr "Tous les fichiers"
|
||||||
|
|
||||||
|
#: ..\..\..\pdfshuffler_g.py:538
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"File %s is encrypted.\n"
|
||||||
|
"Support for encrypted files has not been implemented yet.\n"
|
||||||
|
"File export failed."
|
||||||
|
msgstr ""
|
||||||
|
"Le fichier %s est crypté.\n"
|
||||||
|
"Le support pour ce type de fichier n'a pas encore été implémenté.\n"
|
||||||
|
"L'exportation du fichier a échoué"
|
||||||
|
|
||||||
|
#: ..\..\..\pdfshuffler_g.py:594
|
||||||
|
msgid "Import..."
|
||||||
|
msgstr "Importer ..."
|
||||||
|
|
||||||
|
#: ..\..\..\pdfshuffler_g.py:630
|
||||||
|
msgid "OpenDocument not supported yet!"
|
||||||
|
msgstr "OpenDocument n'est pas encore supporté !"
|
||||||
|
|
||||||
|
#: ..\..\..\pdfshuffler_g.py:632
|
||||||
|
msgid "Image file not supported yet!"
|
||||||
|
msgstr "Le format image n'est pas encore supporté !"
|
||||||
|
|
||||||
|
#: ..\..\..\pdfshuffler_g.py:634
|
||||||
|
msgid "File type not supported!"
|
||||||
|
msgstr "Type de ficher pas encore supporté !"
|
||||||
|
|
||||||
|
#: ..\..\..\pdfshuffler_g.py:636
|
||||||
|
#, python-format
|
||||||
|
msgid "File %s does not exist"
|
||||||
|
msgstr "Le fichier %s n'existe pas"
|
||||||
|
|
||||||
|
#: ..\..\..\pdfshuffler_g.py:638
|
||||||
|
msgid "Closed, no files selected"
|
||||||
|
msgstr "Fermé, aucun fichier sélectionné"
|
||||||
|
|
||||||
|
#: ..\..\..\pdfshuffler_g.py:1030
|
||||||
|
msgid "Left"
|
||||||
|
msgstr "Gauche"
|
||||||
|
|
||||||
|
#: ..\..\..\pdfshuffler_g.py:1030
|
||||||
|
msgid "Right"
|
||||||
|
msgstr "Droite"
|
||||||
|
|
||||||
|
#: ..\..\..\pdfshuffler_g.py:1031
|
||||||
|
msgid "Top"
|
||||||
|
msgstr "Dessus"
|
||||||
|
|
||||||
|
#: ..\..\..\pdfshuffler_g.py:1031
|
||||||
|
msgid "Bottom"
|
||||||
|
msgstr "Bas"
|
||||||
|
|
||||||
|
#: ..\..\..\pdfshuffler_g.py:1049
|
||||||
|
msgid "Crop Selected Pages"
|
||||||
|
msgstr "Couper la(les) page(s) sélectionné(es)"
|
||||||
|
|
||||||
|
#: ..\..\..\pdfshuffler_g.py:1057
|
||||||
|
msgid "Crop Margins"
|
||||||
|
msgstr "Couper les marges"
|
||||||
|
|
||||||
|
#: ..\..\..\pdfshuffler_g.py:1064
|
||||||
|
#, python-format
|
||||||
|
msgid "% of width"
|
||||||
|
msgstr " \\%de la largeur"
|
||||||
|
|
||||||
|
#: ..\..\..\pdfshuffler_g.py:1064
|
||||||
|
#, python-format
|
||||||
|
msgid "% of height"
|
||||||
|
msgstr " \\%de la hauteur"
|
||||||
|
|
||||||
|
#: ..\..\..\pdfshuffler_g.py:1102
|
||||||
|
msgid "Dialog closed"
|
||||||
|
msgstr "Fenêtre de dialogue fermée"
|
||||||
|
|
||||||
|
#: ..\..\..\pdfshuffler_g.py:1116
|
||||||
|
#, python-format
|
||||||
|
msgid "%s is a tool for rearranging and modifying PDF files. Developed using GTK+ and Python"
|
||||||
|
msgstr "%s est un outil destiné à réarranger et modifier les pages de fichiers PDF. Développé avec GTK+ et Python"
|
||||||
|
|
||||||
|
#: ..\..\..\data\pdfshuffler_g.glade:83
|
||||||
|
#: ..\..\..\data\pdfshuffler_g.glade:370
|
||||||
|
msgid "Rotate _Right"
|
||||||
|
msgstr "Tourner à droite"
|
||||||
|
|
||||||
|
#: ..\..\..\data\pdfshuffler_g.glade:95
|
||||||
|
#: ..\..\..\data\pdfshuffler_g.glade:358
|
||||||
|
msgid "Rotate _Left"
|
||||||
|
msgstr "Tourner à gauche"
|
||||||
|
|
||||||
|
#: ..\..\..\data\pdfshuffler_g.glade:107
|
||||||
|
msgid "C_rop"
|
||||||
|
msgstr "_Couper les mages"
|
||||||
|
|
||||||
|
#: ..\..\..\data\pdfshuffler_g.glade:130
|
||||||
|
msgid "Add _Blank Page Before"
|
||||||
|
msgstr "Ajouter une page_ blanche avant"
|
||||||
|
|
||||||
|
#: ..\..\..\data\pdfshuffler_g.glade:190
|
||||||
|
msgid "Add Blank Page _After"
|
||||||
|
msgstr "_Ajouter une page blanche après"
|
||||||
|
|
||||||
|
#: ..\..\..\data\pdfshuffler_g.glade:281
|
||||||
|
msgid "_File"
|
||||||
|
msgstr "_Fichier"
|
||||||
|
|
||||||
|
#: ..\..\..\data\pdfshuffler_g.glade:289
|
||||||
|
msgid "_Open"
|
||||||
|
msgstr "_Ouvrir"
|
||||||
|
|
||||||
|
#: ..\..\..\data\pdfshuffler_g.glade:301
|
||||||
|
msgid "_Save"
|
||||||
|
msgstr "_Enregistrer"
|
||||||
|
|
||||||
|
#: ..\..\..\data\pdfshuffler_g.glade:313
|
||||||
|
msgid "Save _As..."
|
||||||
|
msgstr "Enregistrer _sous..."
|
||||||
|
|
||||||
|
#: ..\..\..\data\pdfshuffler_g.glade:331
|
||||||
|
msgid "_Quit"
|
||||||
|
msgstr "_Quitter"
|
||||||
|
|
||||||
|
#: ..\..\..\data\pdfshuffler_g.glade:350
|
||||||
|
msgid "_Edit"
|
||||||
|
msgstr "É_diter"
|
||||||
|
|
||||||
|
#: ..\..\..\data\pdfshuffler_g.glade:382
|
||||||
|
msgid "Add blank page _before"
|
||||||
|
msgstr "Ajouter une page _blanche avant"
|
||||||
|
|
||||||
|
#: ..\..\..\data\pdfshuffler_g.glade:439
|
||||||
|
msgid "Add blank page _after"
|
||||||
|
msgstr "Ajouter une page blanche _après"
|
||||||
|
|
||||||
|
#: ..\..\..\data\pdfshuffler_g.glade:502
|
||||||
|
msgid "_Delete"
|
||||||
|
msgstr "_Effacer"
|
||||||
|
|
||||||
|
#: ..\..\..\data\pdfshuffler_g.glade:514
|
||||||
|
msgid "_Crop"
|
||||||
|
msgstr "_Recouper"
|
||||||
|
|
||||||
|
#: ..\..\..\data\pdfshuffler_g.glade:533
|
||||||
|
msgid "_View"
|
||||||
|
msgstr "_Voir"
|
||||||
|
|
||||||
|
#: ..\..\..\data\pdfshuffler_g.glade:541
|
||||||
|
msgid "Zoom _in"
|
||||||
|
msgstr "_Zoom avant"
|
||||||
|
|
||||||
|
#: ..\..\..\data\pdfshuffler_g.glade:553
|
||||||
|
msgid "Zoom _out"
|
||||||
|
msgstr "Zoom _arrière"
|
||||||
|
|
||||||
|
#: ..\..\..\data\pdfshuffler_g.glade:572
|
||||||
|
msgid "_Help"
|
||||||
|
msgstr "_Aide"
|
||||||
|
|
||||||
|
#: ..\..\..\data\pdfshuffler_g.glade:580
|
||||||
|
msgid "_About"
|
||||||
|
msgstr "A propos"
|
||||||
|
|
||||||
|
#: ..\..\..\data\pdfshuffler_g.glade:617
|
||||||
|
msgid "Open"
|
||||||
|
msgstr "Ouvrir"
|
||||||
|
|
||||||
|
#: ..\..\..\data\pdfshuffler_g.glade:632
|
||||||
|
msgid "Save"
|
||||||
|
msgstr "Enregistrer"
|
||||||
|
|
||||||
|
#: ..\..\..\data\pdfshuffler_g.glade:647
|
||||||
|
msgid "Save as"
|
||||||
|
msgstr "Enregistrer sous..."
|
||||||
|
|
||||||
|
#: ..\..\..\data\pdfshuffler_g.glade:672
|
||||||
|
msgid "Zoom in"
|
||||||
|
msgstr "Agrandir"
|
||||||
|
|
||||||
|
#: ..\..\..\data\pdfshuffler_g.glade:687
|
||||||
|
msgid "Zoom out"
|
||||||
|
msgstr "Réduire"
|
||||||
|
|
||||||
|
#: ..\..\..\data\pdfshuffler_g.glade:712
|
||||||
|
msgid "Rotate left"
|
||||||
|
msgstr "Tourner à gauche"
|
||||||
|
|
||||||
|
#: ..\..\..\data\pdfshuffler_g.glade:727
|
||||||
|
msgid "Rotate right"
|
||||||
|
msgstr "Tourner à droite"
|
||||||
|
|
||||||
|
#: ..\..\..\data\pdfshuffler_g.glade:742
|
||||||
|
msgid "Crop"
|
||||||
|
msgstr "Couper les marges"
|
||||||
|
|
||||||
|
#: ..\..\..\data\pdfshuffler_g.glade:757
|
||||||
|
msgid "Delete"
|
||||||
|
msgstr "Effacer"
|
||||||
|
|
||||||
|
#~ msgid "Error writing file: %s"
|
||||||
|
#~ msgstr "Une erreur s'est produite pendant l'écriture du fichier : %s"
|
||||||
|
|
||||||
|
#~ msgid "File %s is encrypted."
|
||||||
|
#~ msgstr "Le fichier %s est codé."
|
||||||
|
|
||||||
|
#~ msgid "File export failed."
|
||||||
|
#~ msgstr "Exportation des fichiers échouée."
|
||||||
|
|
||||||
|
#~ msgid "exporting to:"
|
||||||
|
#~ msgstr "exporter en :"
|
||||||
|
|
||||||
|
#~ msgid "Import pdf"
|
||||||
|
#~ msgstr "Importer PDF"
|
||||||
|
|
||||||
|
#~ msgid "Export pdf"
|
||||||
|
#~ msgstr "Exporter PDF"
|
||||||
|
|
||||||
|
#~ msgid "Rotate Page(s) Clockwise"
|
||||||
|
#~ msgstr "Rotation de la(les) page(s) en sens horaire"
|
||||||
|
|
||||||
|
#~ msgid "Rotate Page(s) Counterclockwise"
|
||||||
|
#~ msgstr "Rotation de la(les) page(s) en sens anti-horaire"
|
||||||
|
|
||||||
|
#~ msgid "Crop Page(s)"
|
||||||
|
#~ msgstr "Couper la(les) page(s)"
|
||||||
|
|
||||||
|
#~ msgid ""
|
||||||
|
#~ "PDF-Shuffler is a simple pyGTK utility which lets you merge, split and "
|
||||||
|
#~ "rearrange PDF documents. You can also rotate and crop individual pages of "
|
||||||
|
#~ "a pdf document."
|
||||||
|
#~ msgstr ""
|
||||||
|
#~ "PDF-Shuffler est un simple outil pyGTK qui vous permet de réunir, couper "
|
||||||
|
#~ "et réarrangez des documents PDF. Vous pouvez aussi pivoter et couper des "
|
||||||
|
#~ "pages individuelles d'un document pdf."
|
@ -0,0 +1,299 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<interface>
|
||||||
|
<!-- interface-requires gtk+ 3.0 -->
|
||||||
|
<!-- interface-naming-policy toplevel-contextual -->
|
||||||
|
<object class="GtkFileChooserDialog" id="filechooserdialog1">
|
||||||
|
<property name="width_request">800</property>
|
||||||
|
<property name="height_request">600</property>
|
||||||
|
<property name="border_width">5</property>
|
||||||
|
<property name="modal">True</property>
|
||||||
|
<property name="destroy_with_parent">True</property>
|
||||||
|
<property name="type_hint">normal</property>
|
||||||
|
<property name="skip_taskbar_hint">True</property>
|
||||||
|
<property name="select_multiple">True</property>
|
||||||
|
<child internal-child="vbox">
|
||||||
|
<object class="GtkVBox" id="dialog-vbox3">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<property name="spacing">2</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkVBox" id="vbox2">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkHButtonBox" id="hbuttonbox1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="spacing">7</property>
|
||||||
|
<property name="layout_style">end</property>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="button1">
|
||||||
|
<property name="label" translatable="yes">Open Selected File(s)</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<property name="image">image1</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<signal name="clicked" handler="chooserOK"/>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="button3">
|
||||||
|
<property name="label">gtk-cancel</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<property name="use_stock">True</property>
|
||||||
|
<signal name="clicked" handler="chooserClose"/>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkFrame" id="frame6">
|
||||||
|
<property name="height_request">150</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="label_xalign">0</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkHBox" id="hbox1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkScrolledWindow" id="scrolledwindow2">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="hscrollbar_policy">automatic</property>
|
||||||
|
<property name="vscrollbar_policy">automatic</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkTreeView" id="treeview1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="border_width">2</property>
|
||||||
|
<property name="reorderable">True</property>
|
||||||
|
<property name="enable_search">False</property>
|
||||||
|
<property name="show_expanders">False</property>
|
||||||
|
<property name="enable_grid_lines">horizontal</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkVBox" id="vbox10">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="button14">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<signal name="clicked" handler="pdf_up"/>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImage" id="image10">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="stock">gtk-go-up</property>
|
||||||
|
<property name="icon-size">2</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="position">3</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="button15">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<signal name="clicked" handler="pdf_down"/>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImage" id="image9">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="stock">gtk-go-down</property>
|
||||||
|
<property name="icon-size">2</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">4</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkVBox" id="vbox1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="button20">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<signal name="clicked" handler="pdf_open"/>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImage" id="image13">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="stock">gtk-new</property>
|
||||||
|
<property name="icon-size">2</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="button19">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<signal name="clicked" handler="add_file"/>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImage" id="image12">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="stock">gtk-add</property>
|
||||||
|
<property name="icon-size">2</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="button13">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<signal name="clicked" handler="pdf_remove"/>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImage" id="image11">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="stock">gtk-remove</property>
|
||||||
|
<property name="icon-size">2</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child type="label">
|
||||||
|
<object class="GtkLabel" id="label1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="label" translatable="yes"><b>Input files</b></property>
|
||||||
|
<property name="use_markup">True</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child internal-child="action_area">
|
||||||
|
<object class="GtkHButtonBox" id="dialog-action_area3">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="layout_style">end</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="button21">
|
||||||
|
<property name="label" translatable="yes">Open File(s) in List</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<property name="image">image2</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<signal name="clicked" handler="genFilesArray"/>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="button2">
|
||||||
|
<property name="label">gtk-cancel</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<property name="use_stock">True</property>
|
||||||
|
<signal name="clicked" handler="chooserClose"/>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="pack_type">end</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<action-widgets>
|
||||||
|
<action-widget response="2">button21</action-widget>
|
||||||
|
<action-widget response="0">button2</action-widget>
|
||||||
|
</action-widgets>
|
||||||
|
</object>
|
||||||
|
<object class="GtkImage" id="image2">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="stock">gtk-ok</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkImage" id="image1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="stock">gtk-ok</property>
|
||||||
|
</object>
|
||||||
|
</interface>
|
BIN
pdfbooklet_3.1.2-3_all/usr/share/pdfbooklet/data/nofile.pdf
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
Version=2.0
|
||||||
|
Name=PDF-Booklet
|
||||||
|
Comment=PDF Merging, Rearranging, Splitting, Rotating and Cropping
|
||||||
|
Type=Application
|
||||||
|
Exec=pdfbooklet
|
||||||
|
Icon=pdfbooklet
|
||||||
|
Categories=Office;
|
||||||
|
Terminal=false
|
||||||
|
StartupNotify=false
|
BIN
pdfbooklet_3.1.2-3_all/usr/share/pdfbooklet/data/pdfbooklet.ico
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
pdfbooklet_3.1.2-3_all/usr/share/pdfbooklet/data/pdfbooklet.png
Normal file
After Width: | Height: | Size: 258 B |
333
pdfbooklet_3.1.2-3_all/usr/share/pdfbooklet/data/pdfbooklet.svg
Normal file
@ -0,0 +1,333 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="300"
|
||||||
|
height="300"
|
||||||
|
id="svg2"
|
||||||
|
sodipodi:version="0.32"
|
||||||
|
inkscape:version="0.48.2 r9819"
|
||||||
|
version="1.0"
|
||||||
|
sodipodi:docname="pdfbooklet.svg"
|
||||||
|
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||||
|
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet.png"
|
||||||
|
inkscape:export-xdpi="14.4"
|
||||||
|
inkscape:export-ydpi="14.4">
|
||||||
|
<defs
|
||||||
|
id="defs4">
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient4751">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ff0000;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4753" />
|
||||||
|
<stop
|
||||||
|
id="stop4763"
|
||||||
|
offset="0.91071427"
|
||||||
|
style="stop-color:#7f007f;stop-opacity:1;" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#0000ff;stop-opacity:1;"
|
||||||
|
offset="1"
|
||||||
|
id="stop4755" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient4743">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#4d4d4d;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4745" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#4d4d4d;stop-opacity:0;"
|
||||||
|
offset="1"
|
||||||
|
id="stop4747" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient4735">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#d6e3e3;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4737" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#00ffff;stop-opacity:1;"
|
||||||
|
offset="1"
|
||||||
|
id="stop4739" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient4727">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#3758ff;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4729" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#0000ff;stop-opacity:1;"
|
||||||
|
offset="1"
|
||||||
|
id="stop4731" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient4717">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffb2ff;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4719" />
|
||||||
|
<stop
|
||||||
|
id="stop4725"
|
||||||
|
offset="1"
|
||||||
|
style="stop-color:#ff00ff;stop-opacity:1;" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient4707">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffda42;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4709" />
|
||||||
|
<stop
|
||||||
|
id="stop4715"
|
||||||
|
offset="1"
|
||||||
|
style="stop-color:#ff0000;stop-opacity:1;" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient4691">
|
||||||
|
<stop
|
||||||
|
id="stop4705"
|
||||||
|
offset="0"
|
||||||
|
style="stop-color:#ffffff;stop-opacity:1;" />
|
||||||
|
<stop
|
||||||
|
id="stop4703"
|
||||||
|
offset="1"
|
||||||
|
style="stop-color:#04ff00;stop-opacity:1;" />
|
||||||
|
</linearGradient>
|
||||||
|
<inkscape:perspective
|
||||||
|
sodipodi:type="inkscape:persp3d"
|
||||||
|
inkscape:vp_x="0 : 526.18109 : 1"
|
||||||
|
inkscape:vp_y="0 : 1000 : 0"
|
||||||
|
inkscape:vp_z="744.09448 : 526.18109 : 1"
|
||||||
|
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
|
||||||
|
id="perspective10" />
|
||||||
|
<inkscape:perspective
|
||||||
|
id="perspective2390"
|
||||||
|
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
|
||||||
|
inkscape:vp_z="744.09448 : 526.18109 : 1"
|
||||||
|
inkscape:vp_y="0 : 1000 : 0"
|
||||||
|
inkscape:vp_x="0 : 526.18109 : 1"
|
||||||
|
sodipodi:type="inkscape:persp3d" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient4691"
|
||||||
|
id="linearGradient4699"
|
||||||
|
x1="15.185715"
|
||||||
|
y1="119.40044"
|
||||||
|
x2="201.11098"
|
||||||
|
y2="119.40044"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="translate(0,-18)" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient4707"
|
||||||
|
id="linearGradient4713"
|
||||||
|
x1="0.881223"
|
||||||
|
y1="109.5406"
|
||||||
|
x2="170.03773"
|
||||||
|
y2="109.5406"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="translate(0,-18)" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient4717"
|
||||||
|
id="linearGradient4723"
|
||||||
|
x1="22.021743"
|
||||||
|
y1="99.182249"
|
||||||
|
x2="153.85376"
|
||||||
|
y2="99.182249"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="translate(0,-18)" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient4727"
|
||||||
|
id="linearGradient4733"
|
||||||
|
x1="12.858827"
|
||||||
|
y1="101.05511"
|
||||||
|
x2="125.1628"
|
||||||
|
y2="101.05511"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="translate(0.7613146,-17.953527)"
|
||||||
|
spreadMethod="pad" />
|
||||||
|
<radialGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient4735"
|
||||||
|
id="radialGradient4741"
|
||||||
|
cx="189.2718"
|
||||||
|
cy="133.60805"
|
||||||
|
fx="189.2718"
|
||||||
|
fy="133.60805"
|
||||||
|
r="111.12802"
|
||||||
|
gradientTransform="matrix(1,0,0,0.8186404,-57.578695,84.012848)"
|
||||||
|
gradientUnits="userSpaceOnUse" />
|
||||||
|
<radialGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient4743"
|
||||||
|
id="radialGradient4749"
|
||||||
|
cx="139.74099"
|
||||||
|
cy="255.0762"
|
||||||
|
fx="139.74099"
|
||||||
|
fy="255.0762"
|
||||||
|
r="130.42264"
|
||||||
|
gradientTransform="matrix(1.5440848,0,0,0.1951499,-0.6671924,127.80153)"
|
||||||
|
gradientUnits="userSpaceOnUse" />
|
||||||
|
<radialGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient4751"
|
||||||
|
id="radialGradient4767"
|
||||||
|
cx="215.10474"
|
||||||
|
cy="177.57961"
|
||||||
|
fx="215.10474"
|
||||||
|
fy="177.57961"
|
||||||
|
r="202.15565"
|
||||||
|
gradientTransform="matrix(1,0,0,0.1297218,0,154.54365)"
|
||||||
|
gradientUnits="userSpaceOnUse" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
gridtolerance="10000"
|
||||||
|
guidetolerance="10"
|
||||||
|
objecttolerance="10"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="0.98994949"
|
||||||
|
inkscape:cx="118.615"
|
||||||
|
inkscape:cy="120.88252"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:window-width="1000"
|
||||||
|
inkscape:window-height="723"
|
||||||
|
inkscape:window-x="91"
|
||||||
|
inkscape:window-y="25"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1">
|
||||||
|
<path
|
||||||
|
style="fill:#808080;stroke:#4d4d4d;stroke-width:1.55596292;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
d="M 3.6961424,132.18198 C 2.0734071,137.17299 5.3215966,138.82427 9.4737962,140.08403 L 21.878827,143.73734 L 21.93547,145.18199 C 22.063721,148.21357 24.603735,150.44398 27.628159,150.19475 L 37.852434,149.34554 L 144.85256,187.55164 C 147.74004,188.84041 151.03082,185.53512 152.32956,182.00055 L 162.59651,158.04802 L 237.92198,209.66552 C 240.3826,211.47359 243.99965,211.10563 246.05061,208.8435 L 299.26781,121.18769 C 301.31878,118.92557 300.99161,115.63206 298.53099,113.82398"
|
||||||
|
id="rect3192"
|
||||||
|
sodipodi:nodetypes="ccccccccccccc"
|
||||||
|
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
|
||||||
|
inkscape:export-xdpi="5.0848861"
|
||||||
|
inkscape:export-ydpi="5.0848861" />
|
||||||
|
<rect
|
||||||
|
style="fill:url(#linearGradient4733);fill-opacity:1.0;stroke:#000000;stroke-width:2.17599440000000000;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
id="rect2398"
|
||||||
|
width="110.12798"
|
||||||
|
height="127.43299"
|
||||||
|
x="14.708143"
|
||||||
|
y="19.385107"
|
||||||
|
ry="5.4777718"
|
||||||
|
transform="matrix(0.996623,-8.2113516e-2,4.2261543e-2,0.9991066,0,0)"
|
||||||
|
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
|
||||||
|
inkscape:export-xdpi="5.0848861"
|
||||||
|
inkscape:export-ydpi="5.0848861" />
|
||||||
|
<path
|
||||||
|
style="fill:url(#linearGradient4723);fill-opacity:1;stroke:#000000;stroke-width:2.17512703;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
d="M 48.822926,13.984228 L 146.97785,15.809809 C 150.02702,15.966042 152.60863,18.546516 152.7662,21.595637 L 140.04042,143.15846 C 140.19798,146.20757 137.87007,148.5365 134.82089,148.38027 L 28.897664,142.02316 C 25.848474,141.86694 23.266872,139.28646 23.109307,136.23734 L 43.603394,19.206039 C 43.445829,16.156918 45.773736,13.827994 48.822926,13.984228 z"
|
||||||
|
id="rect3173"
|
||||||
|
sodipodi:nodetypes="ccccccccc"
|
||||||
|
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
|
||||||
|
inkscape:export-xdpi="5.0848861"
|
||||||
|
inkscape:export-ydpi="5.0848861" />
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="ccccccczc"
|
||||||
|
id="path3176"
|
||||||
|
d="M 77.468573,15.926305 L 163.16182,40.40946 C 166.211,40.565688 168.79261,43.146168 168.95017,46.195288 L 123.20908,161.93187 C 123.36663,164.98099 121.03874,167.30992 117.98955,167.15368 L 8.1821682,134.90221 C 4.0299791,133.64299 0.7711377,132.00367 2.3938114,127.01247 L 71.439841,21.148117 C 73.107769,18.590777 74.419383,15.770071 77.468573,15.926305 z"
|
||||||
|
style="fill:url(#linearGradient4713);fill-opacity:1;stroke:#000000;stroke-width:2.17512703;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
|
||||||
|
inkscape:export-xdpi="5.0848861"
|
||||||
|
inkscape:export-ydpi="5.0848861" />
|
||||||
|
<path
|
||||||
|
style="fill:url(#linearGradient4699);fill-opacity:1;stroke:#000000;stroke-width:2.17512703;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
d="M 101.42086,20.215059 L 194.23507,47.530409 C 197.28424,47.686637 199.86585,50.267117 200.02342,53.316237 L 151.04551,176.82113 C 149.74652,180.35577 146.44758,183.65573 143.56023,182.36662 L 21.453033,138.78637 C 17.627627,137.3569 14.949799,134.46878 16.959396,131.05846 L 92.479018,25.275031 C 94.253024,22.790104 94.892122,19.654227 101.42086,20.215059 z"
|
||||||
|
id="path3178"
|
||||||
|
sodipodi:nodetypes="ccccccczc"
|
||||||
|
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
|
||||||
|
inkscape:export-xdpi="5.0848861"
|
||||||
|
inkscape:export-ydpi="5.0848861" />
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="ccccccccc"
|
||||||
|
id="path3180"
|
||||||
|
d="m 22.998972,167.35118 72.936413,-61.88033 c 2.05122,-2.26151 5.683065,-2.62641 8.143185,-0.81816 l 135.57057,81.6271 c 2.46012,1.80827 2.78931,5.08465 0.73808,7.34616 l -53.20188,87.6828 c -2.05121,2.26152 -5.68306,2.62641 -8.14318,0.81815 L 23.737057,174.69734 c -2.460114,-1.80826 -2.789302,-5.08463 -0.738085,-7.34616 z"
|
||||||
|
style="fill:url(#radialGradient4741);fill-opacity:1;stroke:#000000;stroke-width:2.17512703;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
|
||||||
|
inkscape:export-xdpi="5.0848861"
|
||||||
|
inkscape:export-ydpi="5.0848861"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:27.77963257px;font-style:normal;font-weight:normal;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
|
||||||
|
x="-20.606281"
|
||||||
|
y="149.67995"
|
||||||
|
id="text3205"
|
||||||
|
transform="matrix(0.7546661,-0.656109,0.8129658,0.6182944,0,0)"
|
||||||
|
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
|
||||||
|
inkscape:export-xdpi="5.0848861"
|
||||||
|
inkscape:export-ydpi="5.0848861"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3207"
|
||||||
|
x="-20.606281"
|
||||||
|
y="149.67995"
|
||||||
|
style="font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold">PDF</tspan></text>
|
||||||
|
<text
|
||||||
|
transform="matrix(-0.5491289,0.833383,-0.8542178,-0.5246662,0,0)"
|
||||||
|
id="text3229"
|
||||||
|
y="-282.16574"
|
||||||
|
x="-57.589748"
|
||||||
|
style="font-size:27.77963066px;font-style:normal;font-weight:normal;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
|
||||||
|
xml:space="preserve"
|
||||||
|
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
|
||||||
|
inkscape:export-xdpi="5.0848861"
|
||||||
|
inkscape:export-ydpi="5.0848861"><tspan
|
||||||
|
y="-282.16574"
|
||||||
|
x="-57.589748"
|
||||||
|
id="tspan3231"
|
||||||
|
sodipodi:role="line"
|
||||||
|
style="font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold">PDF</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:65.77364348999999777px;font-style:normal;font-weight:normal;fill:url(#radialGradient4767);fill-opacity:1;stroke:#000000;stroke-width:2.34399998;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
x="7.2658076"
|
||||||
|
y="202.10019"
|
||||||
|
id="text3233"
|
||||||
|
transform="scale(0.6989506,1.4307163)"
|
||||||
|
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
|
||||||
|
inkscape:export-xdpi="5.0848861"
|
||||||
|
inkscape:export-ydpi="5.0848861"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3235"
|
||||||
|
x="7.2658076"
|
||||||
|
y="202.10019"
|
||||||
|
style="fill:url(#radialGradient4767);fill-opacity:1;stroke:#000000;stroke-width:2.34399998;stroke-miterlimit:4;stroke-dasharray:none">PDF-Shuffler</tspan></text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 13 KiB |
3519
pdfbooklet_3.1.2-3_all/usr/share/pdfbooklet/data/pdfbooklet3.glade
Normal file
BIN
pdfbooklet_3.1.2-3_all/usr/share/pdfbooklet/data/pdfshuffler.ico
Normal file
After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 6.3 KiB |
@ -0,0 +1,968 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<interface>
|
||||||
|
<!-- interface-requires gtk+ 3.0 -->
|
||||||
|
<object class="GtkAdjustment" id="adjustment1">
|
||||||
|
<property name="lower">-24</property>
|
||||||
|
<property name="upper">5</property>
|
||||||
|
<property name="value">-14</property>
|
||||||
|
<property name="step_increment">1</property>
|
||||||
|
<property name="page_increment">10</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkAdjustment" id="adjustment2">
|
||||||
|
<property name="upper">100</property>
|
||||||
|
<property name="step_increment">1</property>
|
||||||
|
<property name="page_increment">10</property>
|
||||||
|
<property name="page_size">10</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkDialog" id="dialog1">
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="border_width">5</property>
|
||||||
|
<property name="type_hint">normal</property>
|
||||||
|
<child internal-child="vbox">
|
||||||
|
<object class="GtkBox" id="dialog-vbox1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<property name="spacing">2</property>
|
||||||
|
<child internal-child="action_area">
|
||||||
|
<object class="GtkButtonBox" id="dialog-action_area1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="layout_style">end</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="button1">
|
||||||
|
<property name="label" translatable="yes">button</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="button2">
|
||||||
|
<property name="label" translatable="yes">button</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="pack_type">end</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkTable" id="table1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="n_rows">5</property>
|
||||||
|
<property name="n_columns">3</property>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkEntry" id="Left">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="invisible_char">●</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">1</property>
|
||||||
|
<property name="right_attach">2</property>
|
||||||
|
<property name="top_attach">1</property>
|
||||||
|
<property name="bottom_attach">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkEntry" id="Right">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="invisible_char">●</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">1</property>
|
||||||
|
<property name="right_attach">2</property>
|
||||||
|
<property name="top_attach">2</property>
|
||||||
|
<property name="bottom_attach">3</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkEntry" id="Top">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="invisible_char">●</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">1</property>
|
||||||
|
<property name="right_attach">2</property>
|
||||||
|
<property name="top_attach">3</property>
|
||||||
|
<property name="bottom_attach">4</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkEntry" id="Bottom">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="invisible_char">●</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">1</property>
|
||||||
|
<property name="right_attach">2</property>
|
||||||
|
<property name="top_attach">4</property>
|
||||||
|
<property name="bottom_attach">5</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<action-widgets>
|
||||||
|
<action-widget response="0">button1</action-widget>
|
||||||
|
<action-widget response="0">button2</action-widget>
|
||||||
|
</action-widgets>
|
||||||
|
</object>
|
||||||
|
<object class="GtkImage" id="image1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="stock">gtk-redo</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkImage" id="image10">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="stock">gtk-zoom-in</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkImage" id="image11">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="stock">gtk-zoom-out</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkImage" id="image12">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="stock">gtk-leave-fullscreen</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkImage" id="image13">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="stock">gtk-undo</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkImage" id="image14">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="stock">gtk-redo</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkImage" id="image15">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="stock">gtk-new</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkImage" id="image16">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="stock">gtk-new</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkImage" id="image17">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="stock">gtk-about</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkImage" id="image2">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="stock">gtk-undo</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkImage" id="image3">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="stock">gtk-leave-fullscreen</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkImage" id="image4">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="stock">gtk-new</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkMenu" id="contextmenu1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImageMenuItem" id="menu1_RR">
|
||||||
|
<property name="label" translatable="yes">Rotate _Right</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="image">image1</property>
|
||||||
|
<property name="use_stock">False</property>
|
||||||
|
<signal name="activate" handler="rotate_page_right" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImageMenuItem" id="menu1_RL">
|
||||||
|
<property name="label" translatable="yes">Rotate _Left</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="image">image2</property>
|
||||||
|
<property name="use_stock">False</property>
|
||||||
|
<signal name="activate" handler="rotate_page_left" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImageMenuItem" id="menu1_crop">
|
||||||
|
<property name="label" translatable="yes">C_rop</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="image">image3</property>
|
||||||
|
<property name="use_stock">False</property>
|
||||||
|
<signal name="activate" handler="crop_page_dialog" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImageMenuItem" id="menu1_del">
|
||||||
|
<property name="label">gtk-clear</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="use_stock">True</property>
|
||||||
|
<signal name="activate" handler="clear_selected" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImageMenuItem" id="menu1_BB">
|
||||||
|
<property name="label" translatable="yes">Add _Blank Page Before</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="image">image4</property>
|
||||||
|
<property name="use_stock">False</property>
|
||||||
|
<child type="submenu">
|
||||||
|
<object class="GtkMenu" id="menu1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="before_1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label">_1</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<signal name="activate" handler="add_blank_page" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="before_2">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label">_2</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<signal name="activate" handler="add_blank_page" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="before_3">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label">_3</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<signal name="activate" handler="add_blank_page" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="before_4">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label">_4</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<signal name="activate" handler="add_blank_page" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="menuitem1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Add Blank Page _After</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<child type="submenu">
|
||||||
|
<object class="GtkMenu" id="menu2">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="after_1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label">_1</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<signal name="activate" handler="add_blank_page" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="after_2">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label">_2</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<signal name="activate" handler="add_blank_page" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="after_3">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label">_3</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<signal name="activate" handler="add_blank_page" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="after_4">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label">_4</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<signal name="activate" handler="add_blank_page" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<object class="GtkImage" id="image5">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="stock">gtk-open</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkImage" id="image6">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="stock">gtk-save</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkImage" id="image7">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="stock">gtk-save-as</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkImage" id="image8">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="stock">gtk-quit</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkImage" id="image9">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="stock">gtk-delete</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkWindow" id="main_window">
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkVBox" id="vbox1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuBar" id="menubar">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="menuitem_file">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" translatable="yes">_File</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<child type="submenu">
|
||||||
|
<object class="GtkMenu" id="menu_file">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImageMenuItem" id="imagemenuitem_import">
|
||||||
|
<property name="label" translatable="yes">_Open</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="image">image5</property>
|
||||||
|
<property name="use_stock">False</property>
|
||||||
|
<signal name="activate" handler="on_action_add_doc_activate" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImageMenuItem" id="imagemenuitem_save">
|
||||||
|
<property name="label" translatable="yes">_Save</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="sensitive">False</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="image">image6</property>
|
||||||
|
<property name="use_stock">False</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImageMenuItem" id="imagemenuitem_save_as">
|
||||||
|
<property name="label" translatable="yes">Save _As...</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="image">image7</property>
|
||||||
|
<property name="use_stock">False</property>
|
||||||
|
<signal name="activate" handler="choose_export_pdf_name" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSeparatorMenuItem" id="separatormenuitem_file">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImageMenuItem" id="imagemenuitem_quit">
|
||||||
|
<property name="label" translatable="yes">_Quit</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="image">image8</property>
|
||||||
|
<property name="use_stock">False</property>
|
||||||
|
<signal name="activate" handler="close_application" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="menuitem_edit">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" translatable="yes">_Edit</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<child type="submenu">
|
||||||
|
<object class="GtkMenu" id="menu_edit">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImageMenuItem" id="imagemenuitem_rotate_left">
|
||||||
|
<property name="label" translatable="yes">Rotate _Left</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="image">image13</property>
|
||||||
|
<property name="use_stock">False</property>
|
||||||
|
<signal name="activate" handler="rotate_page_left" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImageMenuItem" id="imagemenuitem_rotate_right">
|
||||||
|
<property name="label" translatable="yes">Rotate _Right</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="image">image14</property>
|
||||||
|
<property name="use_stock">False</property>
|
||||||
|
<signal name="activate" handler="rotate_page_right" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImageMenuItem" id="imagemenuitem_add_before">
|
||||||
|
<property name="label" translatable="yes">Add blank page _before</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="image">image15</property>
|
||||||
|
<property name="use_stock">False</property>
|
||||||
|
<child type="submenu">
|
||||||
|
<object class="GtkMenu" id="menu3">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="beforemenu_1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label">_1</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<signal name="activate" handler="add_blank_page" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="beforemenu_2">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label">_2</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<signal name="activate" handler="add_blank_page" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="beforemenu_3">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label">_3</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<signal name="activate" handler="add_blank_page" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="beforemenu_4">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label">_4</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<signal name="activate" handler="add_blank_page" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImageMenuItem" id="imagemenuitem_add_after">
|
||||||
|
<property name="label" translatable="yes">Add blank page _after</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="image">image16</property>
|
||||||
|
<property name="use_stock">False</property>
|
||||||
|
<child type="submenu">
|
||||||
|
<object class="GtkMenu" id="menu4">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="aftermenu_1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label">_1</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<signal name="activate" handler="add_blank_page" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="aftermenu_2">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label">_2</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<signal name="activate" handler="add_blank_page" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="aftermenu_3">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label">_3</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<signal name="activate" handler="add_blank_page" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="aftermenu_4">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label">_4</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<signal name="activate" handler="add_blank_page" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSeparatorMenuItem" id="separatormenuitem1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImageMenuItem" id="imagemenuitem_delete">
|
||||||
|
<property name="label" translatable="yes">_Delete</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="image">image9</property>
|
||||||
|
<property name="use_stock">False</property>
|
||||||
|
<signal name="activate" handler="clear_selected" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImageMenuItem" id="menuitem2_crop">
|
||||||
|
<property name="label" translatable="yes">_Crop</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="image">image12</property>
|
||||||
|
<property name="use_stock">False</property>
|
||||||
|
<signal name="activate" handler="crop_page_dialog" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="menuitem_view">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" translatable="yes">_View</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<child type="submenu">
|
||||||
|
<object class="GtkMenu" id="menu_view">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImageMenuItem" id="imagemenuitem_zoomin">
|
||||||
|
<property name="label" translatable="yes">Zoom _in</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="image">image10</property>
|
||||||
|
<property name="use_stock">False</property>
|
||||||
|
<signal name="activate" handler="zoom_in" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImageMenuItem" id="imagemenuitem_zoomout">
|
||||||
|
<property name="label" translatable="yes">Zoom _out</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="image">image11</property>
|
||||||
|
<property name="use_stock">False</property>
|
||||||
|
<signal name="activate" handler="zoom_out" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="menuitem_help">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" translatable="yes">_Help</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<child type="submenu">
|
||||||
|
<object class="GtkMenu" id="menu_help">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImageMenuItem" id="imagemenuitem_about">
|
||||||
|
<property name="label" translatable="yes">_About</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="image">image17</property>
|
||||||
|
<property name="use_stock">False</property>
|
||||||
|
<signal name="activate" handler="about_dialog" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkHBox" id="hbox1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkToolbar" id="toolbar1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="toolbar_style">icons</property>
|
||||||
|
<property name="show_arrow">False</property>
|
||||||
|
<property name="icon_size">4</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkToolButton" id="toolbutton1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Open</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="stock_id">gtk-open</property>
|
||||||
|
<signal name="clicked" handler="on_action_add_doc_activate" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="homogeneous">True</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkToolButton" id="toolbutton2">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Save</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="stock_id">gtk-save</property>
|
||||||
|
<signal name="clicked" handler="choose_export_pdf_name" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="homogeneous">True</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkToolButton" id="toolbutton3">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Save as</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="stock_id">gtk-save-as</property>
|
||||||
|
<signal name="clicked" handler="choose_export_pdf_name" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="homogeneous">True</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSeparatorToolItem" id="toolbutton4">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="homogeneous">True</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkToolButton" id="toolbutton5">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Zoom in</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="stock_id">gtk-zoom-in</property>
|
||||||
|
<signal name="clicked" handler="zoom_in" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="homogeneous">True</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkToolButton" id="toolbutton6">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Zoom out</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="stock_id">gtk-zoom-out</property>
|
||||||
|
<signal name="clicked" handler="zoom_out" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="homogeneous">True</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSeparatorToolItem" id="toolbutton7">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="homogeneous">True</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkToolButton" id="toolbutton8">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Rotate left</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="stock_id">gtk-undo</property>
|
||||||
|
<signal name="clicked" handler="rotate_page_left" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="homogeneous">True</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkToolButton" id="toolbutton9">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Rotate right</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="stock_id">gtk-redo</property>
|
||||||
|
<signal name="clicked" handler="rotate_page_right" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="homogeneous">True</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkToolButton" id="toolbutton10">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Crop</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="stock_id">gtk-leave-fullscreen</property>
|
||||||
|
<signal name="clicked" handler="crop_page_dialog" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="homogeneous">True</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkToolButton" id="toolbutton11">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Delete</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="stock_id">gtk-delete</property>
|
||||||
|
<signal name="clicked" handler="clear_selected" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="homogeneous">True</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkHScale" id="hscale1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="adjustment">adjustment1</property>
|
||||||
|
<property name="lower_stepper_sensitivity">on</property>
|
||||||
|
<property name="upper_stepper_sensitivity">off</property>
|
||||||
|
<property name="restrict_to_fill_level">False</property>
|
||||||
|
<property name="fill_level">5</property>
|
||||||
|
<property name="digits">2</property>
|
||||||
|
<property name="draw_value">False</property>
|
||||||
|
<property name="value_pos">right</property>
|
||||||
|
<signal name="change-value" handler="zoom_bar" swapped="no"/>
|
||||||
|
<signal name="move-slider" handler="zoom_bar" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkScrolledWindow" id="scrolledwindow">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkProgressBar" id="progressbar">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">3</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</interface>
|
@ -0,0 +1,97 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html><head>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
|
<meta name="Generator" content="Atlantis Word Processor 2.0.5.1, http://www.AtlantisWordProcessor.com"><title>Important Note for Linux users</title>
|
||||||
|
|
||||||
|
<style>p{margin-top:0pt;margin-bottom:0pt;font-family:Arial;font-size:11pt;color:black}</style></head><body bgcolor="#ffffca">
|
||||||
|
<p style="margin-top: 12pt; margin-bottom: 3pt;"><span style="font-size: 14pt; color: blue;"><b>Important Note for Linux users</b></span></p>
|
||||||
|
<p style="font-weight: bold; color: rgb(204, 0, 0);">You will find the
|
||||||
|
last version of Linux installers in the beta directory. <br>
|
||||||
|
</p>
|
||||||
|
<p style="font-weight: bold; color: rgb(204, 0, 0);">pdfbooklet_3.0.6_all.deb hs been tested and seems OK. <br>
|
||||||
|
</p>
|
||||||
|
<p style="font-weight: bold; color: rgb(204, 0, 0);">The .rpm installer has not been tested. <br>
|
||||||
|
</p>
|
||||||
|
<p style="font-weight: bold; color: rgb(204, 0, 0);">For the tar.gz files, see the dependencies below. <br>
|
||||||
|
<br>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p><br>
|
||||||
|
</p>
|
||||||
|
<p>PdfBooklet is developed originally in Windows and for Windows.
|
||||||
|
Nevertheless it works perfectly on Linux, we have made the code
|
||||||
|
compatible. It runs in Python 2.7 or 3.4.</p>
|
||||||
|
|
||||||
|
<p><br>
|
||||||
|
</p>
|
||||||
|
<p><b>1) Installation</b></p>
|
||||||
|
<p>You sould normally use the <span style="font-weight: bold;">.deb file</span> which should work out of the box.<br>
|
||||||
|
The <span style="font-weight: bold;">.rpm</span> file is not yet tested, and the dependencies are not properly set. <br>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p><span style="color: rgb(0, 0, 0);"> </span> <br>
|
||||||
|
</p><span style="color: rgb(0, 0, 0);"></span>
|
||||||
|
<p>In case these installers do not work for you, we are providing other solutions. </p>
|
||||||
|
<p style="margin-top: 12pt; margin-bottom: 3pt; margin-left: 40px;"><b>a) Install from source</b></p>
|
||||||
|
<p style="margin-left: 40px;">Decompress the file : <i>Install by unzipping – linux.zip </i>in a directory where you have full write rights. Run pdfbooklet.py with the following command :</p>
|
||||||
|
<p style="margin-left: 40px;"><span style="color: rgb(0, 0, 0);"> </span></p>
|
||||||
|
<p style="margin-left: 40px;"><span style="font-family: Courier New;">python pdfbooklet.py</span></p>
|
||||||
|
<p style="margin-left: 40px;">or<span style="font-family: Courier New;"> </span></p>
|
||||||
|
<p style="margin-left: 40px;"><span style="font-family: Courier New;">python3 pdfbooklet.py</span></p>
|
||||||
|
<p style="margin-left: 40px;"><span style="color: rgb(0, 0, 0);"> </span></p>
|
||||||
|
<p style="margin-left: 40px;">If you have the dependencies satisfied, the program should run. If
|
||||||
|
not, either install the missing packages, if you know how to do that,
|
||||||
|
or use the second solution :</p>
|
||||||
|
<p style="margin-left: 40px;"><span style="color: rgb(0, 0, 0);"> </span></p>
|
||||||
|
<p style="margin-top: 12pt; margin-bottom: 3pt; margin-left: 40px;"><b>b) Install the pyinstaller bundle</b></p>
|
||||||
|
<p style="margin-left: 40px;">To solve the dependencies problem, we have built a bundle with
|
||||||
|
pyinstaller, which contains everything needed : Python3, Gtk3, Poppler.
|
||||||
|
</p>
|
||||||
|
<p style="margin-left: 40px;">Unzip the big file : pdfbooklet 3.x.x pyinstaller.zip, in a directory where you have write rights. </p>
|
||||||
|
<p style="margin-left: 40px;">Run the file : pdfbooklet</p>
|
||||||
|
<p style="margin-top: 12pt; margin-bottom: 3pt; margin-left: 40px;"><b>c) Install from tarball</b></p>
|
||||||
|
<p style="margin-left: 40px;">We offer also the tarballs in 32 and 64 bits if you know how to install them. </p>
|
||||||
|
<p style="margin-top: 12pt; margin-bottom: 3pt;"><span style="font-size: 12pt; color: rgb(0, 0, 0);"><b><i>2) Known problems<br>
|
||||||
|
</i></b></span></p>
|
||||||
|
<ol>
|
||||||
|
<li style="font-family: monospace;">
|
||||||
|
<p>Dependencies problems : see below the modules which must be installed. Otherwise consider using the pyinstaller bundle. </p>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p>pdfbooklet needs read/write rights in the forder where
|
||||||
|
pdfbooklet.cfg is located and the installer does not always provides
|
||||||
|
this. <span style="font-size: 12pt; color: rgb(0, 0, 0);"><b><i><br>
|
||||||
|
</i></b></span></p>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<p style="margin-top: 9pt; margin-bottom: 3pt;"><span style="font-size: 12pt;"><b><i>Technical information </i></b></span></p>
|
||||||
|
<p><span style="color: rgb(0, 0, 0);"> </span></p>
|
||||||
|
<p> The needed dependencies for python3 are :<br>
|
||||||
|
python-gi<br>
|
||||||
|
python-gi-cairo<br>
|
||||||
|
</p>
|
||||||
|
<p> python3-gi<br>
|
||||||
|
<span style="color: rgb(0, 0, 0);"> python3-cairo</span><br>
|
||||||
|
</p>
|
||||||
|
<p> python3-gi-cairo</p>
|
||||||
|
<p> gir1.2-gtk-3.0</p>
|
||||||
|
<p> gir1.2-poppler-0.18<br>
|
||||||
|
They are installed with the following commande line :<br>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p> - sudo apt-get install python-gi python-gi-cairo python3-gi <span style="color: rgb(0, 0, 0);">python3-cairo </span>python3-gi-cairo gir1.2-gtk-3.0 gir1.2-poppler-0.18 </p>
|
||||||
|
<p><br>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p><span style="color: rgb(0, 0, 0);"> </span></p>
|
||||||
|
<p>For python 2.7 :</p>
|
||||||
|
<p>- sudo apt-get install python-gobject-cairo</p>
|
||||||
|
<p><span style="color: rgb(0, 0, 0);"> </span></p>
|
||||||
|
<p><span style="color: rgb(0, 0, 0);"> </span></p>
|
||||||
|
<p><span style="color: rgb(0, 0, 0);"> </span></p>
|
||||||
|
</body></html>
|
@ -0,0 +1,333 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="300"
|
||||||
|
height="300"
|
||||||
|
id="svg2"
|
||||||
|
sodipodi:version="0.32"
|
||||||
|
inkscape:version="0.48.2 r9819"
|
||||||
|
version="1.0"
|
||||||
|
sodipodi:docname="pdfbooklet.svg"
|
||||||
|
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||||
|
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet.png"
|
||||||
|
inkscape:export-xdpi="14.4"
|
||||||
|
inkscape:export-ydpi="14.4">
|
||||||
|
<defs
|
||||||
|
id="defs4">
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient4751">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ff0000;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4753" />
|
||||||
|
<stop
|
||||||
|
id="stop4763"
|
||||||
|
offset="0.91071427"
|
||||||
|
style="stop-color:#7f007f;stop-opacity:1;" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#0000ff;stop-opacity:1;"
|
||||||
|
offset="1"
|
||||||
|
id="stop4755" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient4743">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#4d4d4d;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4745" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#4d4d4d;stop-opacity:0;"
|
||||||
|
offset="1"
|
||||||
|
id="stop4747" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient4735">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#d6e3e3;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4737" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#00ffff;stop-opacity:1;"
|
||||||
|
offset="1"
|
||||||
|
id="stop4739" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient4727">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#3758ff;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4729" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#0000ff;stop-opacity:1;"
|
||||||
|
offset="1"
|
||||||
|
id="stop4731" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient4717">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffb2ff;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4719" />
|
||||||
|
<stop
|
||||||
|
id="stop4725"
|
||||||
|
offset="1"
|
||||||
|
style="stop-color:#ff00ff;stop-opacity:1;" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient4707">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffda42;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4709" />
|
||||||
|
<stop
|
||||||
|
id="stop4715"
|
||||||
|
offset="1"
|
||||||
|
style="stop-color:#ff0000;stop-opacity:1;" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient4691">
|
||||||
|
<stop
|
||||||
|
id="stop4705"
|
||||||
|
offset="0"
|
||||||
|
style="stop-color:#ffffff;stop-opacity:1;" />
|
||||||
|
<stop
|
||||||
|
id="stop4703"
|
||||||
|
offset="1"
|
||||||
|
style="stop-color:#04ff00;stop-opacity:1;" />
|
||||||
|
</linearGradient>
|
||||||
|
<inkscape:perspective
|
||||||
|
sodipodi:type="inkscape:persp3d"
|
||||||
|
inkscape:vp_x="0 : 526.18109 : 1"
|
||||||
|
inkscape:vp_y="0 : 1000 : 0"
|
||||||
|
inkscape:vp_z="744.09448 : 526.18109 : 1"
|
||||||
|
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
|
||||||
|
id="perspective10" />
|
||||||
|
<inkscape:perspective
|
||||||
|
id="perspective2390"
|
||||||
|
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
|
||||||
|
inkscape:vp_z="744.09448 : 526.18109 : 1"
|
||||||
|
inkscape:vp_y="0 : 1000 : 0"
|
||||||
|
inkscape:vp_x="0 : 526.18109 : 1"
|
||||||
|
sodipodi:type="inkscape:persp3d" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient4691"
|
||||||
|
id="linearGradient4699"
|
||||||
|
x1="15.185715"
|
||||||
|
y1="119.40044"
|
||||||
|
x2="201.11098"
|
||||||
|
y2="119.40044"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="translate(0,-18)" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient4707"
|
||||||
|
id="linearGradient4713"
|
||||||
|
x1="0.881223"
|
||||||
|
y1="109.5406"
|
||||||
|
x2="170.03773"
|
||||||
|
y2="109.5406"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="translate(0,-18)" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient4717"
|
||||||
|
id="linearGradient4723"
|
||||||
|
x1="22.021743"
|
||||||
|
y1="99.182249"
|
||||||
|
x2="153.85376"
|
||||||
|
y2="99.182249"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="translate(0,-18)" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient4727"
|
||||||
|
id="linearGradient4733"
|
||||||
|
x1="12.858827"
|
||||||
|
y1="101.05511"
|
||||||
|
x2="125.1628"
|
||||||
|
y2="101.05511"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="translate(0.7613146,-17.953527)"
|
||||||
|
spreadMethod="pad" />
|
||||||
|
<radialGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient4735"
|
||||||
|
id="radialGradient4741"
|
||||||
|
cx="189.2718"
|
||||||
|
cy="133.60805"
|
||||||
|
fx="189.2718"
|
||||||
|
fy="133.60805"
|
||||||
|
r="111.12802"
|
||||||
|
gradientTransform="matrix(1,0,0,0.8186404,-57.578695,84.012848)"
|
||||||
|
gradientUnits="userSpaceOnUse" />
|
||||||
|
<radialGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient4743"
|
||||||
|
id="radialGradient4749"
|
||||||
|
cx="139.74099"
|
||||||
|
cy="255.0762"
|
||||||
|
fx="139.74099"
|
||||||
|
fy="255.0762"
|
||||||
|
r="130.42264"
|
||||||
|
gradientTransform="matrix(1.5440848,0,0,0.1951499,-0.6671924,127.80153)"
|
||||||
|
gradientUnits="userSpaceOnUse" />
|
||||||
|
<radialGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient4751"
|
||||||
|
id="radialGradient4767"
|
||||||
|
cx="215.10474"
|
||||||
|
cy="177.57961"
|
||||||
|
fx="215.10474"
|
||||||
|
fy="177.57961"
|
||||||
|
r="202.15565"
|
||||||
|
gradientTransform="matrix(1,0,0,0.1297218,0,154.54365)"
|
||||||
|
gradientUnits="userSpaceOnUse" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
gridtolerance="10000"
|
||||||
|
guidetolerance="10"
|
||||||
|
objecttolerance="10"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="0.98994949"
|
||||||
|
inkscape:cx="118.615"
|
||||||
|
inkscape:cy="120.88252"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:window-width="1000"
|
||||||
|
inkscape:window-height="723"
|
||||||
|
inkscape:window-x="91"
|
||||||
|
inkscape:window-y="25"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1">
|
||||||
|
<path
|
||||||
|
style="fill:#808080;stroke:#4d4d4d;stroke-width:1.55596292;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
d="M 3.6961424,132.18198 C 2.0734071,137.17299 5.3215966,138.82427 9.4737962,140.08403 L 21.878827,143.73734 L 21.93547,145.18199 C 22.063721,148.21357 24.603735,150.44398 27.628159,150.19475 L 37.852434,149.34554 L 144.85256,187.55164 C 147.74004,188.84041 151.03082,185.53512 152.32956,182.00055 L 162.59651,158.04802 L 237.92198,209.66552 C 240.3826,211.47359 243.99965,211.10563 246.05061,208.8435 L 299.26781,121.18769 C 301.31878,118.92557 300.99161,115.63206 298.53099,113.82398"
|
||||||
|
id="rect3192"
|
||||||
|
sodipodi:nodetypes="ccccccccccccc"
|
||||||
|
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
|
||||||
|
inkscape:export-xdpi="5.0848861"
|
||||||
|
inkscape:export-ydpi="5.0848861" />
|
||||||
|
<rect
|
||||||
|
style="fill:url(#linearGradient4733);fill-opacity:1.0;stroke:#000000;stroke-width:2.17599440000000000;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
id="rect2398"
|
||||||
|
width="110.12798"
|
||||||
|
height="127.43299"
|
||||||
|
x="14.708143"
|
||||||
|
y="19.385107"
|
||||||
|
ry="5.4777718"
|
||||||
|
transform="matrix(0.996623,-8.2113516e-2,4.2261543e-2,0.9991066,0,0)"
|
||||||
|
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
|
||||||
|
inkscape:export-xdpi="5.0848861"
|
||||||
|
inkscape:export-ydpi="5.0848861" />
|
||||||
|
<path
|
||||||
|
style="fill:url(#linearGradient4723);fill-opacity:1;stroke:#000000;stroke-width:2.17512703;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
d="M 48.822926,13.984228 L 146.97785,15.809809 C 150.02702,15.966042 152.60863,18.546516 152.7662,21.595637 L 140.04042,143.15846 C 140.19798,146.20757 137.87007,148.5365 134.82089,148.38027 L 28.897664,142.02316 C 25.848474,141.86694 23.266872,139.28646 23.109307,136.23734 L 43.603394,19.206039 C 43.445829,16.156918 45.773736,13.827994 48.822926,13.984228 z"
|
||||||
|
id="rect3173"
|
||||||
|
sodipodi:nodetypes="ccccccccc"
|
||||||
|
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
|
||||||
|
inkscape:export-xdpi="5.0848861"
|
||||||
|
inkscape:export-ydpi="5.0848861" />
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="ccccccczc"
|
||||||
|
id="path3176"
|
||||||
|
d="M 77.468573,15.926305 L 163.16182,40.40946 C 166.211,40.565688 168.79261,43.146168 168.95017,46.195288 L 123.20908,161.93187 C 123.36663,164.98099 121.03874,167.30992 117.98955,167.15368 L 8.1821682,134.90221 C 4.0299791,133.64299 0.7711377,132.00367 2.3938114,127.01247 L 71.439841,21.148117 C 73.107769,18.590777 74.419383,15.770071 77.468573,15.926305 z"
|
||||||
|
style="fill:url(#linearGradient4713);fill-opacity:1;stroke:#000000;stroke-width:2.17512703;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
|
||||||
|
inkscape:export-xdpi="5.0848861"
|
||||||
|
inkscape:export-ydpi="5.0848861" />
|
||||||
|
<path
|
||||||
|
style="fill:url(#linearGradient4699);fill-opacity:1;stroke:#000000;stroke-width:2.17512703;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
d="M 101.42086,20.215059 L 194.23507,47.530409 C 197.28424,47.686637 199.86585,50.267117 200.02342,53.316237 L 151.04551,176.82113 C 149.74652,180.35577 146.44758,183.65573 143.56023,182.36662 L 21.453033,138.78637 C 17.627627,137.3569 14.949799,134.46878 16.959396,131.05846 L 92.479018,25.275031 C 94.253024,22.790104 94.892122,19.654227 101.42086,20.215059 z"
|
||||||
|
id="path3178"
|
||||||
|
sodipodi:nodetypes="ccccccczc"
|
||||||
|
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
|
||||||
|
inkscape:export-xdpi="5.0848861"
|
||||||
|
inkscape:export-ydpi="5.0848861" />
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="ccccccccc"
|
||||||
|
id="path3180"
|
||||||
|
d="m 22.998972,167.35118 72.936413,-61.88033 c 2.05122,-2.26151 5.683065,-2.62641 8.143185,-0.81816 l 135.57057,81.6271 c 2.46012,1.80827 2.78931,5.08465 0.73808,7.34616 l -53.20188,87.6828 c -2.05121,2.26152 -5.68306,2.62641 -8.14318,0.81815 L 23.737057,174.69734 c -2.460114,-1.80826 -2.789302,-5.08463 -0.738085,-7.34616 z"
|
||||||
|
style="fill:url(#radialGradient4741);fill-opacity:1;stroke:#000000;stroke-width:2.17512703;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
|
||||||
|
inkscape:export-xdpi="5.0848861"
|
||||||
|
inkscape:export-ydpi="5.0848861"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:27.77963257px;font-style:normal;font-weight:normal;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
|
||||||
|
x="-20.606281"
|
||||||
|
y="149.67995"
|
||||||
|
id="text3205"
|
||||||
|
transform="matrix(0.7546661,-0.656109,0.8129658,0.6182944,0,0)"
|
||||||
|
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
|
||||||
|
inkscape:export-xdpi="5.0848861"
|
||||||
|
inkscape:export-ydpi="5.0848861"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3207"
|
||||||
|
x="-20.606281"
|
||||||
|
y="149.67995"
|
||||||
|
style="font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold">PDF</tspan></text>
|
||||||
|
<text
|
||||||
|
transform="matrix(-0.5491289,0.833383,-0.8542178,-0.5246662,0,0)"
|
||||||
|
id="text3229"
|
||||||
|
y="-282.16574"
|
||||||
|
x="-57.589748"
|
||||||
|
style="font-size:27.77963066px;font-style:normal;font-weight:normal;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
|
||||||
|
xml:space="preserve"
|
||||||
|
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
|
||||||
|
inkscape:export-xdpi="5.0848861"
|
||||||
|
inkscape:export-ydpi="5.0848861"><tspan
|
||||||
|
y="-282.16574"
|
||||||
|
x="-57.589748"
|
||||||
|
id="tspan3231"
|
||||||
|
sodipodi:role="line"
|
||||||
|
style="font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold">PDF</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:65.77364348999999777px;font-style:normal;font-weight:normal;fill:url(#radialGradient4767);fill-opacity:1;stroke:#000000;stroke-width:2.34399998;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
x="7.2658076"
|
||||||
|
y="202.10019"
|
||||||
|
id="text3233"
|
||||||
|
transform="scale(0.6989506,1.4307163)"
|
||||||
|
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
|
||||||
|
inkscape:export-xdpi="5.0848861"
|
||||||
|
inkscape:export-ydpi="5.0848861"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3235"
|
||||||
|
x="7.2658076"
|
||||||
|
y="202.10019"
|
||||||
|
style="fill:url(#radialGradient4767);fill-opacity:1;stroke:#000000;stroke-width:2.34399998;stroke-miterlimit:4;stroke-dasharray:none">PDF-Shuffler</tspan></text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 13 KiB |
BIN
pdfbooklet_3.1.2-3_all/usr/share/pixmaps/pdfbooklet.png
Normal file
After Width: | Height: | Size: 10 KiB |