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 |