mirror of
https://github.com/ciromattia/kcc
synced 2026-04-15 21:48:44 +00:00
Compare commits
321 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
00d239e1d8 | ||
|
|
26bd2d3ed0 | ||
|
|
e7aa49b70c | ||
|
|
da41edc2f1 | ||
|
|
ecbf60fb28 | ||
|
|
57b571b6c2 | ||
|
|
44bdc0245b | ||
|
|
1ec07fe4ec | ||
|
|
5f8f7e0919 | ||
|
|
f404b9090d | ||
|
|
68521f7c63 | ||
|
|
f5dd813c4c | ||
|
|
7924c492b3 | ||
|
|
2fc21c33e2 | ||
|
|
cb76504acb | ||
|
|
db6b0eddfe | ||
|
|
7d529a2acc | ||
|
|
ad3ff35aaa | ||
|
|
c62eeeb712 | ||
|
|
5a36a13105 | ||
|
|
12684d6562 | ||
|
|
c5f68ae12a | ||
|
|
7bd9c766cc | ||
|
|
c6b1417d9c | ||
|
|
98bf28a713 | ||
|
|
f2d6d5b458 | ||
|
|
5de492ffb6 | ||
|
|
5c2c6ed825 | ||
|
|
c2730ab01c | ||
|
|
bfba66d47d | ||
|
|
b5bc2f8e00 | ||
|
|
917eaef548 | ||
|
|
3187ebb054 | ||
|
|
b9276e9ede | ||
|
|
147d815057 | ||
|
|
180123fee2 | ||
|
|
2768e622f2 | ||
|
|
b629b45d46 | ||
|
|
f66c83425c | ||
|
|
68b4b7114d | ||
|
|
36f8c82eaf | ||
|
|
bd665c3261 | ||
|
|
94586fa590 | ||
|
|
89806dfcfc | ||
|
|
c9eb73ab90 | ||
|
|
2edcc0369a | ||
|
|
bc0a52b848 | ||
|
|
5ae72bf06d | ||
|
|
24c32643c1 | ||
|
|
40b988f964 | ||
|
|
ac794eff85 | ||
|
|
eaa387a9d6 | ||
|
|
d0f5d6dac4 | ||
|
|
b174534c1c | ||
|
|
19d486a4ee | ||
|
|
652762b709 | ||
|
|
e6df87f8fd | ||
|
|
1a9cd0beb5 | ||
|
|
108e351126 | ||
|
|
dfe3e10470 | ||
|
|
787ad9fa66 | ||
|
|
f10e8869a9 | ||
|
|
715ada328f | ||
|
|
56f23ab488 | ||
|
|
996af59e00 | ||
|
|
37aa84c4aa | ||
|
|
50574632e6 | ||
|
|
0afb9e8c0b | ||
|
|
7511c7eed6 | ||
|
|
836a4146f9 | ||
|
|
15a240ccea | ||
|
|
0722ddf8b0 | ||
|
|
b3159b94e7 | ||
|
|
ef5207c990 | ||
|
|
db77d89817 | ||
|
|
4571fadadb | ||
|
|
94f56238ae | ||
|
|
5efb5d6dbb | ||
|
|
623f615dd9 | ||
|
|
39fbbc42b3 | ||
|
|
99405ab8a6 | ||
|
|
aadfca8306 | ||
|
|
5450502c2a | ||
|
|
c976b06413 | ||
|
|
b6facda95b | ||
|
|
3f608eb602 | ||
|
|
104cd04994 | ||
|
|
b323204628 | ||
|
|
56195d301d | ||
|
|
287723ca6f | ||
|
|
90490149c7 | ||
|
|
2210f484df | ||
|
|
d5502e85b0 | ||
|
|
59b26cfc8b | ||
|
|
a722e5fa49 | ||
|
|
fce3072dca | ||
|
|
f53cdf9cd7 | ||
|
|
de74318c69 | ||
|
|
b137e69510 | ||
|
|
888663fa4c | ||
|
|
8a2ba96ac5 | ||
|
|
cb6b0e0a7b | ||
|
|
49d2a7fbab | ||
|
|
3d84b27d58 | ||
|
|
e98a23d0c0 | ||
|
|
7f80dacea8 | ||
|
|
6efb3dcef3 | ||
|
|
942a828b7e | ||
|
|
df5ee1badf | ||
|
|
e3ab28642d | ||
|
|
a1831c45d5 | ||
|
|
52bea9957a | ||
|
|
a71339ec34 | ||
|
|
c5f09c44b8 | ||
|
|
64b199ef74 | ||
|
|
8dd0b0e694 | ||
|
|
181a2e8ab4 | ||
|
|
3fdff845b7 | ||
|
|
2ee5dc310b | ||
|
|
f32e9560b5 | ||
|
|
621827c1c2 | ||
|
|
dc312f36c2 | ||
|
|
4573ff6ec2 | ||
|
|
d77498405b | ||
|
|
e491fca445 | ||
|
|
d22ee1a488 | ||
|
|
7ebcccd8a2 | ||
|
|
9a691c3c63 | ||
|
|
2b04a0298e | ||
|
|
9867f63d00 | ||
|
|
866f8898be | ||
|
|
9f2ac7a176 | ||
|
|
634213f380 | ||
|
|
ce82b5ec66 | ||
|
|
062b239f2f | ||
|
|
f5f5c05f1e | ||
|
|
a229ba44bf | ||
|
|
27e5cc3b00 | ||
|
|
63d752280a | ||
|
|
60b7a90589 | ||
|
|
63413fa4ba | ||
|
|
3a536df626 | ||
|
|
35bc4a2987 | ||
|
|
3bb8cc7778 | ||
|
|
bd53c6108d | ||
|
|
3d8bcb4020 | ||
|
|
162c146bed | ||
|
|
e4750fc965 | ||
|
|
ebe7d910de | ||
|
|
aa96381eb5 | ||
|
|
a2b9b5aa8b | ||
|
|
1e5bfc9f66 | ||
|
|
25a68ebdea | ||
|
|
786d2a9e1f | ||
|
|
4133cd21ba | ||
|
|
237ef728e1 | ||
|
|
991bf5d4a9 | ||
|
|
aa8b78b4e4 | ||
|
|
c2e6a0b791 | ||
|
|
42cf9e099f | ||
|
|
d99064596a | ||
|
|
b1e7a88353 | ||
|
|
f8610e1cd7 | ||
|
|
562dad02fa | ||
|
|
66b867c1ca | ||
|
|
b46ada9596 | ||
|
|
aaa2de81fc | ||
|
|
b0c6315fee | ||
|
|
509d78c0a6 | ||
|
|
65ef77bace | ||
|
|
170064853c | ||
|
|
c7e9d883fa | ||
|
|
a8521dbc9a | ||
|
|
0f44629273 | ||
|
|
f12361e7cf | ||
|
|
450076e6e8 | ||
|
|
6d445ae151 | ||
|
|
921511dcf2 | ||
|
|
d76a624a82 | ||
|
|
cf3df581e1 | ||
|
|
87009f27a6 | ||
|
|
cccbd36463 | ||
|
|
19b438844d | ||
|
|
878e92b527 | ||
|
|
116dce09fd | ||
|
|
3af30faee9 | ||
|
|
cf0b6b3484 | ||
|
|
96a8c1d354 | ||
|
|
20712b6c42 | ||
|
|
84d836bf0e | ||
|
|
d944d6385e | ||
|
|
a38013eabc | ||
|
|
def9e42a61 | ||
|
|
34aaeab8b1 | ||
|
|
eaff6cc633 | ||
|
|
54f48d2156 | ||
|
|
42d845cf07 | ||
|
|
e5e53d3aa7 | ||
|
|
f952634971 | ||
|
|
19ff6a51cc | ||
|
|
8fbe558f65 | ||
|
|
6bdb0ab942 | ||
|
|
7656a85708 | ||
|
|
d016bade8e | ||
|
|
3cc99c6221 | ||
|
|
93f5d105cf | ||
|
|
c1c44bdf88 | ||
|
|
72132ea908 | ||
|
|
29f901f92a | ||
|
|
22b7258aa3 | ||
|
|
c0f788bd67 | ||
|
|
8f10e93c08 | ||
|
|
4a473e3716 | ||
|
|
89d31cb8e5 | ||
|
|
80b65b12b7 | ||
|
|
e835502837 | ||
|
|
5bcdc78725 | ||
|
|
acb4dfad8f | ||
|
|
7f5de29174 | ||
|
|
11007402cd | ||
|
|
0cf92fc48f | ||
|
|
953942ca00 | ||
|
|
c46ca8b507 | ||
|
|
48d3bee225 | ||
|
|
3b0e5cc309 | ||
|
|
e5be31f9d5 | ||
|
|
17ea85c31f | ||
|
|
572e1422bf | ||
|
|
af263073b5 | ||
|
|
7facf2d620 | ||
|
|
eef3ff434b | ||
|
|
fa94e18a6a | ||
|
|
c680cfd5c5 | ||
|
|
3e8469611d | ||
|
|
39ab475156 | ||
|
|
636de67a17 | ||
|
|
d80c18f652 | ||
|
|
9f68e009f1 | ||
|
|
557bd2bbbf | ||
|
|
d33c53b691 | ||
|
|
ddd223c2ec | ||
|
|
50f5b600b1 | ||
|
|
d94df8390a | ||
|
|
8b33331929 | ||
|
|
86a9dde1eb | ||
|
|
33dec77063 | ||
|
|
fe06e2fa19 | ||
|
|
7b5e3eaafd | ||
|
|
0a30f1ffb9 | ||
|
|
8687604d26 | ||
|
|
0a9fd6c439 | ||
|
|
c95a9395de | ||
|
|
77066d7a9f | ||
|
|
c8e5b7de9a | ||
|
|
3e11a88a7c | ||
|
|
a7e4968836 | ||
|
|
6d9e2d3c03 | ||
|
|
0789e7a353 | ||
|
|
ff97a85552 | ||
|
|
33cfd92cef | ||
|
|
58513ef59f | ||
|
|
6056e3e767 | ||
|
|
1b1ed7c4ab | ||
|
|
5b44e4bddd | ||
|
|
54592969a4 | ||
|
|
38007ab3d5 | ||
|
|
bdd10c7617 | ||
|
|
c0f4bc021a | ||
|
|
34d6af93a6 | ||
|
|
0df481dabb | ||
|
|
55c5b91411 | ||
|
|
be745f4602 | ||
|
|
8bf5ad0f12 | ||
|
|
1b723b2fee | ||
|
|
6095eb98c4 | ||
|
|
95bb070a6b | ||
|
|
75a338304a | ||
|
|
1c28305b83 | ||
|
|
1f1abb80be | ||
|
|
3addc4563a | ||
|
|
e37e7566e2 | ||
|
|
eedf537902 | ||
|
|
5e8bd52433 | ||
|
|
910e8a6cf9 | ||
|
|
edfc2467a3 | ||
|
|
205170efe4 | ||
|
|
fceac407ee | ||
|
|
4c5ebe5949 | ||
|
|
d12ad26e79 | ||
|
|
bd57665b55 | ||
|
|
c3b8d48813 | ||
|
|
c8933e7326 | ||
|
|
c95c64ccff | ||
|
|
c5bcd4c2e4 | ||
|
|
9e402897c5 | ||
|
|
cbf87df551 | ||
|
|
ea01492e1f | ||
|
|
82445d5d3a | ||
|
|
839bc4cc9e | ||
|
|
98c6a569bf | ||
|
|
85ad95c0d0 | ||
|
|
1d0498fdce | ||
|
|
ee390c34e9 | ||
|
|
b853615f7d | ||
|
|
5b2bb30902 | ||
|
|
da4788a6c6 | ||
|
|
3022635a71 | ||
|
|
38d3ae6a6a | ||
|
|
3f0eea44f4 | ||
|
|
5077f60881 | ||
|
|
279f70a6bd | ||
|
|
01f3596fde | ||
|
|
23d3577a06 | ||
|
|
22c75951e0 | ||
|
|
3d3fb5dc61 | ||
|
|
e4a8213a2c | ||
|
|
b2f71ae163 | ||
|
|
53256b0e34 | ||
|
|
4ebd3e046d | ||
|
|
d07d49d2e7 | ||
|
|
111bfb9302 |
11
.gitignore
vendored
11
.gitignore
vendored
@@ -2,10 +2,11 @@
|
||||
*.cbz
|
||||
*.cbr
|
||||
.idea
|
||||
build
|
||||
dist
|
||||
kindlegen*
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
/UnRAR.exe
|
||||
/7za.exe
|
||||
build
|
||||
dist
|
||||
Output
|
||||
test
|
||||
solaio
|
||||
kindlegen*
|
||||
|
||||
25
KCC.qrc
25
KCC.qrc
@@ -1,25 +0,0 @@
|
||||
<RCC>
|
||||
<qresource prefix="Icon">
|
||||
<file>icons/comic2ebook.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="Devices">
|
||||
<file>icons/Other.png</file>
|
||||
<file>icons/Kindle.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="Formats">
|
||||
<file>icons/CBZ.png</file>
|
||||
<file>icons/EPUB.png</file>
|
||||
<file>icons/MOBI.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="Status">
|
||||
<file>icons/error.png</file>
|
||||
<file>icons/info.png</file>
|
||||
<file>icons/warning.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="Other">
|
||||
<file>icons/clear.png</file>
|
||||
<file>icons/convert.png</file>
|
||||
<file>icons/document_new.png</file>
|
||||
<file>icons/folder_new.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -1,7 +1,7 @@
|
||||
ISC LICENSE
|
||||
ISC LICENSE
|
||||
|
||||
Copyright (c) 2013 Ciro Mattia Gonano <ciromattia@gmail.com>
|
||||
Copyright (c) 2013 Paweł Jastrzębski <pawelj@vulturis.eu>
|
||||
Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
|
||||
Copyright (c) 2013-2015 Paweł Jastrzębski <pawelj@iosphe.re>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for
|
||||
any purpose with or without fee is hereby granted, provided that the
|
||||
|
||||
436
README.md
436
README.md
@@ -1,75 +1,85 @@
|
||||
# KCC
|
||||
|
||||
**KindleComicConverter** is a Python app to convert comic files or folders to ePub or Panel View MOBI.
|
||||
It was initally developed for Kindle but since v2.2 it outputs valid ePub 2.0 so _**despite its name, KCC is
|
||||
actually a comic to EPUB converter that every e-reader owner can happily use**_.
|
||||
**Kindle Comic Converter** is a Python app to convert comic/manga files or folders to EPUB, Panel View MOBI or E-Ink optimized CBZ.
|
||||
It was initially developed for Kindle but since version 2.2 it outputs valid EPUB 2.0 so _**despite its name, KCC is
|
||||
actually a comic/manga to EPUB converter that every e-reader owner can happily use**_.
|
||||
It can also optionally optimize images by applying a number of transformations.
|
||||
|
||||
### A word of warning
|
||||
**KCC** _is not_ [Amazon's Kindle Comic Creator](http://www.amazon.com/gp/feature.html?ie=UTF8&docId=1001103761) nor is in any way endorsed by Amazon.
|
||||
Amazon's tool is for comic publishers and involves a lot of manual effort, while **KCC** is for comic readers.
|
||||
If you want to read some comments over *Amazon's KC2* you can take a look at [this](http://www.mobileread.com/forums/showthread.php?t=207461&page=7#96) and [that](http://www.mobileread.com/forums/showthread.php?t=211047) threads on Mobileread.
|
||||
_KC2_ in no way is a replacement for **KCC** so you can be quite confident we'll going to carry on developing our little monster ;)
|
||||
Amazon's tool is for comic publishers and involves a lot of manual effort, while **KCC** is for comic/manga readers.
|
||||
_KC2_ in no way is a replacement for **KCC** so you can be quite confident we'll going to carry on developing our little monster ;-)
|
||||
|
||||
### Issues / new features / donations
|
||||
If you have general questions about usage, feedback etc. please [post it here](http://www.mobileread.com/forums/showthread.php?t=207461).
|
||||
If you have some **technical** problems using KCC please [file an issue here](https://github.com/ciromattia/kcc/issues/new).
|
||||
If you can fix an open issue, fork & make a pull request.
|
||||
|
||||
### Donations
|
||||
If you find **KCC** valuable you can consider donating to the authors:
|
||||
|
||||
* Ciro Mattia Gonano [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=D8WNYNPBGDAS2)
|
||||
* Paweł Jastrzębski [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=YTTJ4LK2JDHPS)
|
||||
- Ciro Mattia Gonano:
|
||||
- [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=D8WNYNPBGDAS2)
|
||||
- [](http://flattr.com/thing/2260449/ciromattiakcc-on-GitHub)
|
||||
- Paweł Jastrzębski:
|
||||
- [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=YTTJ4LK2JDHPS)
|
||||
- Bitcoin: 1W15wwqsfd7wbaZ6wvSJf1LW1bz6q5L8b
|
||||
|
||||
## BINARY RELEASES
|
||||
You can find the latest released binary at the following links:
|
||||
- **Win64:** [http://kcc.vulturis.eu/Win64/](http://kcc.vulturis.eu/Win64/)
|
||||
- **Win32:** [http://kcc.vulturis.eu/Win32/](http://kcc.vulturis.eu/Win32/)
|
||||
- **OS X:** [http://kcc.vulturis.eu/OSX/](http://kcc.vulturis.eu/OSX/)
|
||||
- **Linux:** Just download sourcecode and launch: `python kcc.py`
|
||||
- **Windows (Vista or newer):** [http://kcc.iosphe.re/Windows/](http://kcc.iosphe.re/Windows/)
|
||||
- **Linux:** [http://kcc.iosphe.re/Linux/](http://kcc.iosphe.re/Linux/)
|
||||
- **OS X (10.8+):** [http://kcc.iosphe.re/OSX/](http://kcc.iosphe.re/OSX/)
|
||||
|
||||
## INPUT FORMATS
|
||||
**KCC** can understand and convert, at the moment, the following file types:
|
||||
- PNG, JPG, GIF, TIFF, BMP
|
||||
- Folders
|
||||
**KCC** can understand and convert, at the moment, the following input types:
|
||||
- Folders containing: PNG, JPG or GIF files
|
||||
- CBZ, ZIP
|
||||
- CBR, RAR *(With `unrar` executable)*
|
||||
- CB7, 7Z *(With `7za` executable)*
|
||||
- PDF *(Extracting only contained JPG images)*
|
||||
- PDF *(Only extracting JPG images)*
|
||||
|
||||
## OPTIONAL REQUIREMENTS
|
||||
- [KindleGen](http://www.amazon.com/gp/feature.html?ie=UTF8&docId=1000765211) v2.9+ in a directory reachable by your _PATH_ or in _KCC_ directory *(For .mobi generation)*
|
||||
- [KindleGen](http://www.amazon.com/gp/feature.html?ie=UTF8&docId=1000765211) v2.9+ in a directory reachable by your _PATH_ or in _KCC_ directory *(For MOBI generation)*
|
||||
- [UnRAR](http://www.rarlab.com/download.htm) *(For CBR/RAR support)*
|
||||
- [7za](http://www.7-zip.org/download.html) *(For 7z/CB7 support)*
|
||||
|
||||
### For compiling/running from source:
|
||||
- Python 2.7 - Included in MacOS and Linux, follow the [official documentation](http://www.python.org/getit/windows/) to install on Windows.
|
||||
- PyQt4 - Please refer to official documentation for installing into your system.
|
||||
- [Pillow](http://pypi.python.org/pypi/Pillow/) - For comic optimizations. Please refer to official documentation for installing into your system.
|
||||
### For running from source:
|
||||
- Python 3.3+
|
||||
- [PyQt](http://www.riverbankcomputing.co.uk/software/pyqt/download5) 5.2.0+
|
||||
- [Pillow](http://pypi.python.org/pypi/Pillow/) 2.7.0+
|
||||
- [psutil](https://pypi.python.org/pypi/psutil) 2.0+
|
||||
- [python-slugify](http://pypi.python.org/pypi/python-slugify) 0.1.0+
|
||||
- [scandir](https://pypi.python.org/pypi/scandir) 0.9+
|
||||
|
||||
On Debian based distributions these two commands should install all dependencies:
|
||||
```
|
||||
sudo apt-get install python3 python3-dev python3-pip python3-pyqt5 libpng-dev libjpeg-dev p7zip-full unrar
|
||||
sudo pip3 install pillow python-slugify psutil scandir
|
||||
```
|
||||
|
||||
### For freezing code:
|
||||
- Windows - [py2exe](https://pypi.python.org/pypi/py2exe) 0.9.2.2+
|
||||
- OS X - [py2app](https://bitbucket.org/ronaldoussoren/py2app) 0.9.0+
|
||||
|
||||
## USAGE
|
||||
|
||||
### Important tips:
|
||||
* Use high quality source files. **This little detail have a major impact on the final result.**
|
||||
* Read tooltip of _High/Ultra quality_ option. There are many important informations there.
|
||||
* When converting images smaller than device resolution remember to enable upscaling.
|
||||
* Panel View (auto zooming every part of page) can be disabled directly on Kindle. There is no KCC option to do that.
|
||||
* If you're converting color images and the end result is not satisfactory, experiment with gamma correction option (check 1.0 setting first).
|
||||
* Check our [wiki](https://github.com/ciromattia/kcc/wiki/Other-devices) for a list of tested Non-Kindle E-Readers.
|
||||
* The first image found will be set as the comic's cover.
|
||||
* All files/directories will be added to EPUB in alphabetical order.
|
||||
* Output MOBI file should be uploaded via USB. Other methods might corrupt it.
|
||||
|
||||
### GUI
|
||||
|
||||
Should be pretty self-explanatory. All options have detailed informations in tooltips.
|
||||
After completed conversion you should find ready file alongside the original input file (same directory).
|
||||
|
||||
### Standalone `comic2ebook.py` usage:
|
||||
Please check [our wiki](https://github.com/ciromattia/kcc/wiki/) for more details.
|
||||
|
||||
CLI version of **KCC** is intended for power users. It is not idiot-proof like GUI :-)
|
||||
|
||||
### Standalone `kcc-c2e.py` usage:
|
||||
|
||||
```
|
||||
Usage: comic2ebook.py [options] comic_file|comic_folder
|
||||
Usage: kcc-c2e [options] comic_file|comic_folder
|
||||
|
||||
Options:
|
||||
MAIN:
|
||||
-p PROFILE, --profile=PROFILE
|
||||
Device profile (Choose one among K1, K2, K345, KDX, KDXG, KHD, KF, KFHD, KFHD8, KFHDX, KFHDX8, KFA) [Default=KHD]
|
||||
Device profile (Available options: K1, K2, K345, KDX,
|
||||
KPW, KV, KFHD, KFHDX, KFHDX8, KFA, KoMT, KoG, KoA,
|
||||
KoAHD, KoAH2O) [Default=KV]
|
||||
-q QUALITY, --quality=QUALITY
|
||||
Quality of Panel View. 0 - Normal 1 - High 2 - Ultra [Default=0]
|
||||
-m, --manga-style Manga style (Right-to-left reading and splitting)
|
||||
@@ -80,14 +90,16 @@ Options:
|
||||
Output generated file to specified directory or file
|
||||
-t TITLE, --title=TITLE
|
||||
Comic title [Default=filename or directory name]
|
||||
--cbz-output Outputs a CBZ archive and does not generate EPUB
|
||||
-f FORMAT, --format=FORMAT
|
||||
Output format (Available options: Auto, MOBI,
|
||||
EPUB, CBZ) [Default=Auto]
|
||||
--batchsplit Split output into multiple files
|
||||
|
||||
PROCESSING:
|
||||
--blackborders Disable autodetection and force black borders
|
||||
--whiteborders Disable autodetection and force white borders
|
||||
--forcecolor Don't convert images to grayscale
|
||||
--forcepng Create PNG files instead JPEG (For non-Kindle devices)
|
||||
--forcepng Create PNG files instead JPEG
|
||||
--gamma=GAMMA Apply gamma correction to linearize the image [Default=Auto]
|
||||
--nocutpagenumbers Don't try to cut page numbering on images
|
||||
--noprocessing Don't apply image preprocessing
|
||||
@@ -103,20 +115,20 @@ Options:
|
||||
Replace screen height provided by device profile
|
||||
|
||||
OTHER:
|
||||
-v, --verbose Verbose output
|
||||
-h, --help Show this help message and exit
|
||||
```
|
||||
|
||||
### Standalone `comic2panel.py` usage:
|
||||
### Standalone `kcc-c2p.py` usage:
|
||||
|
||||
```
|
||||
Usage: comic2panel.py [options] comic_folder
|
||||
Usage: kcc-c2p [options] comic_folder
|
||||
|
||||
Options:
|
||||
MANDATORY:
|
||||
-y HEIGHT, --height=HEIGHT
|
||||
Height of the target device screen
|
||||
-i, --in-place Overwrite source directory
|
||||
-m, --merge Combine every directory into a single image before splitting
|
||||
|
||||
OTHER:
|
||||
-d, --debug Create debug file for every splitted image
|
||||
@@ -124,135 +136,151 @@ Options:
|
||||
```
|
||||
|
||||
## CREDITS
|
||||
**KCC** is made by [Ciro Mattia Gonano](http://github.com/ciromattia) and [Paweł Jastrzębski](http://github.com/AcidWeb)
|
||||
**KCC** is made by [Ciro Mattia Gonano](http://github.com/ciromattia) and [Paweł Jastrzębski](http://github.com/AcidWeb).
|
||||
|
||||
This script born as a cross-platform alternative to `KindleComicParser` by **Dc5e** (published [here](http://www.mobileread.com/forums/showthread.php?t=192783))
|
||||
This script born as a cross-platform alternative to `KindleComicParser` by **Dc5e** (published [here](http://www.mobileread.com/forums/showthread.php?t=192783)).
|
||||
|
||||
The app relies and includes the following scripts/binaries:
|
||||
The app relies and includes the following scripts:
|
||||
|
||||
- `KindleUnpack` script by Charles **M. Hannum, P. Durrant, K. Hendricks, S. Siebert, fandrieu, DiapDealer, nickredding**. Released with GPLv3 License.
|
||||
- `rarfile.py` script © 2005-2011 **Marko Kreen** <markokr@gmail.com>. Released with ISC License.
|
||||
- `image.py` class from **Alex Yatskov**'s [Mangle](http://foosoft.net/mangle/) with subsequent [proDOOMman](https://github.com/proDOOMman/Mangle)'s and [Birua](https://github.com/Birua/Mangle)'s patches.
|
||||
- `DualMetaFix` script by **K. Hendricks**. Released with GPL-3 License.
|
||||
- `rarfile.py` script © 2005-2014 **Marko Kreen** <markokr@gmail.com>. Released with ISC License.
|
||||
- `image.py` class from **Alex Yatskov**'s [Mangle](https://github.com/FooSoft/mangle/) with subsequent [proDOOMman](https://github.com/proDOOMman/Mangle)'s and [Birua](https://github.com/Birua/Mangle)'s patches.
|
||||
- Icon is by **Nikolay Verin** ([http://ncrow.deviantart.com/](http://ncrow.deviantart.com/)) and released under [CC BY-NC-SA 3.0](http://creativecommons.org/licenses/by-nc-sa/3.0/) License.
|
||||
|
||||
## SAMPLE FILES CREATED BY KCC
|
||||
* [Kindle Paperwhite](http://kcc.vulturis.eu/Samples/Ubunchu!-KPW.mobi)
|
||||
* [Kindle](http://kcc.vulturis.eu/Samples/Ubunchu!-K345.mobi)
|
||||
* [Kindle DX/DXG](http://kcc.vulturis.eu/Samples/Ubunchu!-KDX.mobi)
|
||||
* [Kindle Fire](http://kcc.vulturis.eu/Samples/Ubunchu!-KF.mobi)
|
||||
* [Kindle Fire HD](http://kcc.vulturis.eu/Samples/Ubunchu!-KFHD.mobi)
|
||||
* [Kindle Fire HD 8.9"](http://kcc.vulturis.eu/Samples/Ubunchu!-KFHD8.mobi)
|
||||
* [Kindle Fire HDX](http://kcc.vulturis.eu/Samples/Ubunchu!-KFHDX.mobi)
|
||||
* [Kindle Fire HDX 8.9"](http://kcc.vulturis.eu/Samples/Ubunchu!-KFHDX8.mobi)
|
||||
* [Kindle Voyage](http://kcc.iosphe.re/Samples/Ubunchu!-KV.mobi)
|
||||
* [Kindle Paperwhite](http://kcc.iosphe.re/Samples/Ubunchu!-KPW.mobi)
|
||||
* [Kindle](http://kcc.iosphe.re/Samples/Ubunchu!-K345.mobi)
|
||||
* [Kindle DX/DXG](http://kcc.iosphe.re/Samples/Ubunchu!-KDX.cbz)
|
||||
* [Kobo Mini/Touch](http://kcc.iosphe.re/Samples/Ubunchu!-KoMT.cbz)
|
||||
* [Kobo Glow](http://kcc.iosphe.re/Samples/Ubunchu!-KoG.cbz)
|
||||
* [Kobo Aura](http://kcc.iosphe.re/Samples/Ubunchu!-KoA.cbz)
|
||||
* [Kobo Aura HD](http://kcc.iosphe.re/Samples/Ubunchu!-KoAHD.cbz)
|
||||
* [Kobo Aura H2O](http://kcc.iosphe.re/Samples/Ubunchu!-KoAH2O.cbz)
|
||||
|
||||
## CHANGELOG
|
||||
####1.00
|
||||
* Initial version
|
||||
####4.5:
|
||||
* Added simple ComicRack medadata editor
|
||||
* Re-enabled Manga Cover Database support
|
||||
* ComicRack bookmarks are now parsed
|
||||
* Fixed glitches in Kindle Voyage profile
|
||||
* Fixed problems with directory locks on Windows
|
||||
* Fixed sorting anomalies
|
||||
* Improved conversion speed
|
||||
|
||||
####1.10
|
||||
* Added support for CBZ/CBR files in comic2ebook.py
|
||||
####4.4.1:
|
||||
* Fixed problems with OSX GUI
|
||||
* Added one missing DLL to Windows installer
|
||||
|
||||
####1.11
|
||||
* Added support for CBZ/CBR files in KindleComicConverter
|
||||
####4.4:
|
||||
* Improved speed and quality of conversion
|
||||
* Added RAR5 support
|
||||
* Dropped BMP and TIFF support
|
||||
* Fixed some WebToon mode bugs
|
||||
* Fixed CBR parsing on OSX
|
||||
|
||||
####1.20
|
||||
* Comic optimizations! Split pages not target-oriented (landscape with portrait target or portrait with landscape target), add palette and other image optimizations from Mangle. WARNING: PIL is required for all image mangling!
|
||||
####4.3.1:
|
||||
* Fixed Kindle Voyage profile
|
||||
* Fixed some bugs in OS X release
|
||||
* CLI version now support multiple input files at once
|
||||
* Disabled MCB support
|
||||
* Other minor tweaks
|
||||
|
||||
####1.30
|
||||
* Fixed an issue in OPF generation for device resolution
|
||||
* Reworked options system (call with -h option to get the inline help)
|
||||
####4.3:
|
||||
* Added profiles for Kindle Voyage and Kobo Aura H2O
|
||||
* Added missing features to CLI version
|
||||
* Other minor bug fixes
|
||||
|
||||
####1.40
|
||||
* Added some options for controlling image optimization
|
||||
* Further optimization (ImageOps, page numbering cut, autocontrast)
|
||||
####4.2.1:
|
||||
* Improved margin color detection
|
||||
* Fixed random crashes of MOBI processing step
|
||||
* Fixed resizing problems in high quality mode
|
||||
* Fixed some MCD support bugs
|
||||
* Default output format for Kindle DX is now CBZ
|
||||
|
||||
####1.41
|
||||
* Fixed a serious bug on resizing when img ratio was bigger than device one
|
||||
####4.2:
|
||||
* Added [Manga Cover Database](http://manga.joentjuh.nl/) support
|
||||
* Officially dropped Windows XP support
|
||||
* Fixed _Other_ profile
|
||||
* Fixed problems with page order on stock KOBO CBZ reader
|
||||
* Many other small bug fixes and tweaks
|
||||
|
||||
####1.50
|
||||
* Added subfolder support for multiple chapters.
|
||||
####4.1:
|
||||
* Thanks to code contributed by Kevin Hendricks speed of MOBI creation was greatly increased
|
||||
* Improved performance on Windows
|
||||
* Improved MOBI splitting and changed maximal size of output file
|
||||
* Fixed _No optimization_ mode
|
||||
* Multiple small tweaks nad minor bug fixes
|
||||
|
||||
####2.0
|
||||
* GUI! AppleScript is gone and Tk is used to provide cross-platform GUI support.
|
||||
####4.0.2:
|
||||
* Fixed some Windows and OSX specific bugs
|
||||
* Fixed problem with marigns when using HQ mode
|
||||
|
||||
####2.1
|
||||
* Added basic error reporting
|
||||
####4.0.1:
|
||||
* Fixed file lock problems that plagued some Windows users
|
||||
* Fixed content server failing to start on Windows
|
||||
* Improved performance of WebToon splitter
|
||||
* Tweaked margin color detection
|
||||
|
||||
#### 2.2:
|
||||
* Added (valid!) ePub 2.0 output
|
||||
* Rename .zip files to .cbz to avoid overwriting
|
||||
####4.0:
|
||||
* KCC now use Python 3.3 and Qt 5.2
|
||||
* Full UTF-8 awareness
|
||||
* CBZ output now support Manga mode
|
||||
* Improved Panel View support and margin color detection
|
||||
* Added drag&drop support
|
||||
* Output directory can be now selected
|
||||
* Windows release now have auto-updater
|
||||
* Names of chapters on Kindle should be now more user friendly
|
||||
* Fixed OSX file association support
|
||||
* Many extensive internal changes and tweaks
|
||||
|
||||
####2.3
|
||||
* Fixed win32 ePub generation, folder handling, filenames with spaces and subfolders
|
||||
####3.7.2:
|
||||
* Fixed problems with HQ mode
|
||||
|
||||
####2.4
|
||||
* Use temporary directory as workdir (fixes converting from external volumes and zipfiles renaming)
|
||||
* Fixed "add folders" from GUI.
|
||||
####3.7.1:
|
||||
* Hotfixed Kobo profiles
|
||||
|
||||
####2.5
|
||||
* Added --black-borders option to set added borders black when page's ratio is not the device's one (#11).
|
||||
* Fixes epub containing zipped itself (#10)
|
||||
####3.7:
|
||||
* Added profiles for KOBO devices
|
||||
* Improved Panel View support
|
||||
* Improved WebToon splitter
|
||||
* Improved margin color autodetection
|
||||
* Tweaked EPUB output
|
||||
* Fixed stretching option
|
||||
* GUI tweaks and minor bugfixes
|
||||
|
||||
####2.6
|
||||
* Added --rotate option to rotate landscape images instead of splitting them (#16, #24)
|
||||
* Added --output option to customize ePub output dir/file (#22)
|
||||
* Add rendition:layout and rendition:orientation ePub meta tags (supported by new kindlegen 2.8)
|
||||
* Fixed natural sorting for files (#18)
|
||||
####3.6.2:
|
||||
* Fixed previous PNG output fix
|
||||
* Fixed Panel View anomalies
|
||||
|
||||
####2.7
|
||||
* Lots of GUI improvements (#27, #13)
|
||||
* Added gamma support within --gamma option (defaults to profile-specified gamma) (#26, #27)
|
||||
* Added --nodithering option to prevent dithering optimizations (#27)
|
||||
* Epub margins support (#30)
|
||||
* Fixed no file added if file has no spaces on Windows (#25)
|
||||
* Gracefully exit if unrar missing (#15)
|
||||
* Do not call kindlegen if source epub is bigger than 320MB (#17)
|
||||
* Get filetype from magic number (#14)
|
||||
* PDF conversion works again
|
||||
####3.6.1:
|
||||
* Fixed PNG output
|
||||
|
||||
####2.8
|
||||
* Updated rarfile library
|
||||
* Panel View support + HQ support (#36) - new option: --nopanelviewhq
|
||||
* Split profiles for K4NT and K4T
|
||||
* Rewrite of Landscape Mode support (huge readability improvement for KPW)
|
||||
* Upscale use now BILINEAR method
|
||||
* Added generic CSS file
|
||||
* Optimized archive extraction for zip/rar files (#40)
|
||||
####3.6:
|
||||
* Increased quality of Panel View zoom
|
||||
* Creation of multipart MOBI output is now faster on machines with 4GB+ RAM
|
||||
* Automatic gamma correction now distinguishes color and grayscale images
|
||||
* Added ComicRack metadata parser
|
||||
* Implemented new method to detect border color in non-webtoon comics
|
||||
* Upscaling is now enabled by default for Kindle Fire HD/HDX
|
||||
* Windows nad Linux releases now have tray icon
|
||||
* Fixed Kindle Fire HDX 7" output
|
||||
* Increased target resolution for Kindle DX/DXG CBZ output
|
||||
|
||||
####2.9
|
||||
* Added support for generating a plain CBZ (skipping all the EPUB/Mobi generation) (#45)
|
||||
* Prevent output file overwriting the source one: if a duplicate name is detected, append _kcc to the name
|
||||
* Rarfile library updated to 2.6
|
||||
* Added GIF, TIFF and BMP to supported formats (#42)
|
||||
* Filenames slugifications (#28, #31, #9, #8)
|
||||
####3.5:
|
||||
* Added simple content server - Converted files can be now delivered wireless
|
||||
* Added proper Windows installer
|
||||
* Improved multiprocessing speed
|
||||
* GUI tweaks and minor bug fixes
|
||||
|
||||
####2.10:
|
||||
* Multiprocessing support
|
||||
* Kindle Fire support (color ePub/Mobi)
|
||||
* Panel View support for horizontal content
|
||||
* Fixed panel order for horizontal pages when --rotate is enabled
|
||||
* Disabled cropping and page number cutting for blank pages
|
||||
* Fixed some slugify issues with specific file naming conventions (#50, #51)
|
||||
|
||||
####3.0:
|
||||
* New QT GUI
|
||||
* Merge with AWKCC
|
||||
* Added ultra quality mode
|
||||
* Added support for custom width/height
|
||||
* Added option to disable color conversion
|
||||
|
||||
####3.1:
|
||||
* Added profile: Kindle for Android
|
||||
* Add file/directory dialogs now support multiselect
|
||||
* Many small fixes and tweaks
|
||||
|
||||
####3.2:
|
||||
* Too big EPUB files are now splitted before conversion to MOBI
|
||||
* Added experimental parser of manga webtoons
|
||||
* Improved error handling
|
||||
|
||||
####3.2.1:
|
||||
* Hotfixed crash occurring on OS with Russian locale
|
||||
####3.4:
|
||||
* Improved PNG output
|
||||
* Increased quality of upscaling
|
||||
* Added support of file association - KCC can now open CBZ, CBR, CB7, ZIP, RAR, 7Z and PDF files directly
|
||||
* Paths that contain UTF-8 characters are now supported
|
||||
* Migrated to new version of Pillow library
|
||||
* Merged DX and DXG profiles
|
||||
* Many other minor bug fixes and GUI tweaks
|
||||
|
||||
####3.3:
|
||||
* Margins are now automatically omitted in Panel View mode
|
||||
@@ -268,7 +296,117 @@ The app relies and includes the following scripts/binaries:
|
||||
* Windows release is now bundled with UnRAR and 7za
|
||||
* Small GUI tweaks
|
||||
|
||||
## COPYRIGHT
|
||||
####3.2:
|
||||
* Too big EPUB files are now splitted before conversion to MOBI
|
||||
* Added experimental parser of manga webtoons
|
||||
* Improved error handling
|
||||
|
||||
Copyright (c) 2012-2013 Ciro Mattia Gonano and Paweł Jastrzębski.
|
||||
####3.2.1:
|
||||
* Hotfixed crash occurring on OS with Russian locale
|
||||
|
||||
####3.1:
|
||||
* Added profile: Kindle for Android
|
||||
* Add file/directory dialogs now support multiselect
|
||||
* Many small fixes and tweaks
|
||||
|
||||
####3.0:
|
||||
* New QT GUI
|
||||
* Merge with AWKCC
|
||||
* Added ultra quality mode
|
||||
* Added support for custom width/height
|
||||
* Added option to disable color conversion
|
||||
|
||||
####2.10:
|
||||
* Multiprocessing support
|
||||
* Kindle Fire support (color EPUB/MOBI)
|
||||
* Panel View support for horizontal content
|
||||
* Fixed panel order for horizontal pages when --rotate is enabled
|
||||
* Disabled cropping and page number cutting for blank pages
|
||||
* Fixed some slugify issues with specific file naming conventions (#50, #51)
|
||||
|
||||
####2.9
|
||||
* Added support for generating a plain CBZ (skipping all the EPUB/MOBI generation) (#45)
|
||||
* Prevent output file overwriting the source one: if a duplicate name is detected, append _kcc to the name
|
||||
* Rarfile library updated to 2.6
|
||||
* Added GIF, TIFF and BMP to supported formats (#42)
|
||||
* Filenames slugifications (#28, #31, #9, #8)
|
||||
|
||||
####2.8
|
||||
* Updated rarfile library
|
||||
* Panel View support + HQ support (#36) - new option: --nopanelviewhq
|
||||
* Split profiles for K4NT and K4T
|
||||
* Rewrite of Landscape Mode support (huge readability improvement for KPW)
|
||||
* Upscale use now BILINEAR method
|
||||
* Added generic CSS file
|
||||
* Optimized archive extraction for zip/rar files (#40)
|
||||
|
||||
####2.7
|
||||
* Lots of GUI improvements (#27, #13)
|
||||
* Added gamma support within --gamma option (defaults to profile-specified gamma) (#26, #27)
|
||||
* Added --nodithering option to prevent dithering optimizations (#27)
|
||||
* EPUB margins support (#30)
|
||||
* Fixed no file added if file has no spaces on Windows (#25)
|
||||
* Gracefully exit if unrar missing (#15)
|
||||
* Do not call kindlegen if source EPUB is bigger than 320MB (#17)
|
||||
* Get filetype from magic number (#14)
|
||||
* PDF conversion works again
|
||||
|
||||
####2.6
|
||||
* Added --rotate option to rotate landscape images instead of splitting them (#16, #24)
|
||||
* Added --output option to customize EPUB output dir/file (#22)
|
||||
* Add rendition:layout and rendition:orientation EPUB meta tags (supported by new kindlegen 2.8)
|
||||
* Fixed natural sorting for files (#18)
|
||||
|
||||
####2.5
|
||||
* Added --black-borders option to set added borders black when page's ratio is not the device's one (#11).
|
||||
* Fixes EPUB containing zipped itself (#10)
|
||||
|
||||
####2.4
|
||||
* Use temporary directory as workdir (fixes converting from external volumes and zipfiles renaming)
|
||||
* Fixed "add folders" from GUI.
|
||||
|
||||
####2.3
|
||||
* Fixed win32 EPUB generation, folder handling, filenames with spaces and subfolders
|
||||
|
||||
####2.2:
|
||||
* Added (valid!) EPUB 2.0 output
|
||||
* Rename .zip files to .cbz to avoid overwriting
|
||||
|
||||
####2.1
|
||||
* Added basic error reporting
|
||||
|
||||
####2.0
|
||||
* GUI! AppleScript is gone and Tk is used to provide cross-platform GUI support.
|
||||
|
||||
####1.5
|
||||
* Added subfolder support for multiple chapters.
|
||||
|
||||
####1.4.1
|
||||
* Fixed a serious bug on resizing when img ratio was bigger than device one
|
||||
|
||||
####1.4
|
||||
* Added some options for controlling image optimization
|
||||
* Further optimization (ImageOps, page numbering cut, autocontrast)
|
||||
|
||||
####1.3
|
||||
* Fixed an issue in OPF generation for device resolution
|
||||
* Reworked options system (call with -h option to get the inline help)
|
||||
|
||||
####1.2
|
||||
* Comic optimizations! Split pages not target-oriented (landscape with portrait target or portrait with landscape target), add palette and other image optimizations from Mangle. WARNING: PIL is required for all image mangling!
|
||||
|
||||
####1.1.1
|
||||
* Added support for CBZ/CBR files in Kindle Comic Converter
|
||||
|
||||
####1.1
|
||||
* Added support for CBZ/CBR files in comic2ebook.py
|
||||
|
||||
####1.0
|
||||
* Initial version
|
||||
|
||||
## KNOWN ISSUES
|
||||
Please check [wiki page](https://github.com/ciromattia/kcc/wiki/Known-issues).
|
||||
|
||||
## COPYRIGHT
|
||||
Copyright (c) 2012-2015 Ciro Mattia Gonano and Paweł Jastrzębski.
|
||||
**KCC** is released under ISC LICENSE; see LICENSE.txt for further details.
|
||||
|
||||
@@ -7,19 +7,19 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>420</width>
|
||||
<height>380</height>
|
||||
<height>397</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>420</width>
|
||||
<height>380</height>
|
||||
<height>397</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>420</width>
|
||||
<height>380</height>
|
||||
<height>397</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
@@ -27,9 +27,6 @@
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Kindle Comic Converter</string>
|
||||
</property>
|
||||
@@ -74,7 +71,7 @@
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Disable image optimizations.</string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Disable image optimizations.<br/><span style=" font-weight:600;">Input images must be already resized.</span></p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>No optimisation</string>
|
||||
@@ -113,7 +110,7 @@
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Enable auto-splitting of webtoons like <span style=" font-style:italic;">Tower of God</span> or <span style=" font-style:italic;">Noblesse</span>.<br/>Pages with a low width, high height and vertical panel flow.</p></body></html></string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Enable special parsing mode for WebToons.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Webtoon mode</string>
|
||||
@@ -131,7 +128,7 @@
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Create PNG files instead JPEG.</p></body></html></string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Create PNG files instead JPEG.<br/>Quality increase is not noticeable on most of devices.<br/>Output files <span style=" font-weight:600;">might</span> be smaller.<br/><span style=" font-weight:600;">MOBI conversion will be much slower.</span></p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>PNG output</string>
|
||||
@@ -170,7 +167,7 @@
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Disable splitting and rotation.</p></body></html></string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Disable page splitting and rotation.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>No split/rotate</string>
|
||||
@@ -198,7 +195,7 @@
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Target device.</string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Target device.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="FormatBox">
|
||||
@@ -220,7 +217,7 @@
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Output format.</string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Output format.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="ConvertButton">
|
||||
@@ -243,6 +240,9 @@
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>Shift+Click to select the output directory.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Convert</string>
|
||||
</property>
|
||||
@@ -269,6 +269,9 @@
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>Add directory containing JPG, PNG or GIF files to queue.<br/><span style=" font-weight:600;">CBR, CBZ and CB7 files inside will not be processed!</span></p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add directory</string>
|
||||
</property>
|
||||
@@ -295,6 +298,9 @@
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>Add CBR, CBZ, CB7 or PDF file to queue.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add file</string>
|
||||
</property>
|
||||
@@ -362,7 +368,7 @@
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Enable right-to-left reading.</string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Enable right-to-left reading.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Manga mode</string>
|
||||
@@ -386,13 +392,7 @@
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'Sans'; font-size:9pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600; text-decoration: underline;">Unchecked - Normal quality mode<br /></span><span style=" font-family:'MS Shell Dlg 2'; font-style:italic;">Use it when Panel View support is not needed.</span><span style=" font-family:'MS Shell Dlg 2'; font-weight:600; text-decoration: underline;"><br /></span><span style=" font-family:'MS Shell Dlg 2';">- Maximum quality when zoom is not enabled.<br />- Poor quality when zoom is enabled.<br />- Lowest file size.</span></p>
|
||||
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600; text-decoration: underline;">Indeterminate - High quality mode<br /></span><span style=" font-family:'MS Shell Dlg 2'; font-style:italic;">Not zoomed image </span><span style=" font-family:'MS Shell Dlg 2'; font-weight:600; font-style:italic;">might </span><span style=" font-family:'MS Shell Dlg 2'; font-style:italic;">be a little blurry.</span><span style=" font-family:'MS Shell Dlg 2'; font-weight:600; text-decoration: underline;"><br /></span><span style=" font-family:'MS Shell Dlg 2';">- Medium/High quality when zoom is not enabled.<br />- Maximum quality when zoom is enabled.</span></p>
|
||||
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600; text-decoration: underline;">Checked - Ultra quality mode<br /></span><span style=" font-family:'MS Shell Dlg 2'; font-style:italic;">Maximum possible quality.</span><span style=" font-family:'MS Shell Dlg 2'; font-weight:600; text-decoration: underline;"><br /></span><span style=" font-family:'MS Shell Dlg 2';">- Maximum quality when zoom is not enabled.<br />- Maximum quality when zoom is enabled.<br />- Very high file size.</span></p></body></html></string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Quality of Panel View/zoom. Highly impact size of output file.<br/><span style=" font-weight:600;">This option control only quality of magnification!</span></p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>High/Ultra quality</string>
|
||||
@@ -419,7 +419,7 @@ p, li { white-space: pre-wrap; }
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Disable page spliting.<br/>They will be rotated instead.</p></body></html></string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Disable splitting of two-page spreads.<br/>They will be rotated instead.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Horizontal mode</string>
|
||||
@@ -448,6 +448,9 @@ p, li { white-space: pre-wrap; }
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QListWidget#JobList {background:#ffffff;background-image:url(:/Other/icons/list_background.png);background-position:center center;background-repeat:no-repeat;}QScrollBar:vertical{border:1px solid #999;background:#FFF;width:5px;margin:0}QScrollBar::handle:vertical{background:DarkGray;min-height:0}QScrollBar::add-line:vertical{height:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:vertical{height:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}QScrollBar:horizontal{border:1px solid #999;background:#FFF;height:5px;margin:0}QScrollBar::handle:horizontal{background:DarkGray;min-width:0}QScrollBar::add-line:horizontal{width:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:horizontal{width:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}</string>
|
||||
</property>
|
||||
<property name="showDropIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
@@ -466,7 +469,7 @@ p, li { white-space: pre-wrap; }
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>195</width>
|
||||
<width>141</width>
|
||||
<height>32</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -486,9 +489,9 @@ p, li { white-space: pre-wrap; }
|
||||
<widget class="QPushButton" name="AdvModeButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>217</x>
|
||||
<x>260</x>
|
||||
<y>10</y>
|
||||
<width>195</width>
|
||||
<width>151</width>
|
||||
<height>32</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -537,9 +540,6 @@ p, li { white-space: pre-wrap; }
|
||||
<family>DejaVu Sans</family>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>When converting color images setting this option to 1.0 <span style=" font-weight:600;">might</span> improve readability.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Gamma: Auto</string>
|
||||
</property>
|
||||
@@ -561,9 +561,6 @@ p, li { white-space: pre-wrap; }
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::ClickFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>When converting color images setting this option to 1.0 <span style=" font-weight:600;">might</span> improve readability.</p></body></html></string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>500</number>
|
||||
</property>
|
||||
@@ -635,7 +632,7 @@ p, li { white-space: pre-wrap; }
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Do not convert images to grayscale.</string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Don't convert images to grayscale.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Color mode</string>
|
||||
@@ -664,7 +661,7 @@ p, li { white-space: pre-wrap; }
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Resolution of target device.</string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Resolution of target device.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Custom width: </string>
|
||||
@@ -697,10 +694,10 @@ p, li { white-space: pre-wrap; }
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Resolution of target device.</string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Resolution of target device.</p></body></html></string>
|
||||
</property>
|
||||
<property name="inputMask">
|
||||
<string>0000; </string>
|
||||
<string>0000</string>
|
||||
</property>
|
||||
<property name="maxLength">
|
||||
<number>4</number>
|
||||
@@ -715,7 +712,7 @@ p, li { white-space: pre-wrap; }
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Resolution of target device.</string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Resolution of target device.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Custom height: </string>
|
||||
@@ -748,10 +745,10 @@ p, li { white-space: pre-wrap; }
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Resolution of target device.</string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Resolution of target device.</p></body></html></string>
|
||||
</property>
|
||||
<property name="inputMask">
|
||||
<string>0000; </string>
|
||||
<string>0000</string>
|
||||
</property>
|
||||
<property name="maxLength">
|
||||
<number>4</number>
|
||||
@@ -761,6 +758,32 @@ p, li { white-space: pre-wrap; }
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="EditorButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>160</x>
|
||||
<y>10</y>
|
||||
<width>91</width>
|
||||
<height>32</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>DejaVu Sans</family>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Editor</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Other/icons/editor.png</normaloff>:/Other/icons/editor.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
<zorder>OptionsAdvanced</zorder>
|
||||
<zorder>DeviceBox</zorder>
|
||||
<zorder>FormatBox</zorder>
|
||||
@@ -774,8 +797,20 @@ p, li { white-space: pre-wrap; }
|
||||
<zorder>AdvModeButton</zorder>
|
||||
<zorder>OptionsAdvancedGamma</zorder>
|
||||
<zorder>OptionsExpert</zorder>
|
||||
<zorder>EditorButton</zorder>
|
||||
<zorder>ProgressBar</zorder>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusBar">
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>DejaVu Sans</family>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="sizeGripEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<action name="ActionBasic">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
@@ -7,19 +7,19 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>420</width>
|
||||
<height>380</height>
|
||||
<height>397</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>420</width>
|
||||
<height>380</height>
|
||||
<height>397</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>420</width>
|
||||
<height>380</height>
|
||||
<height>397</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
@@ -27,9 +27,6 @@
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Kindle Comic Converter</string>
|
||||
</property>
|
||||
@@ -72,7 +69,7 @@
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p><span style=" font-size:12pt;">Disable image optimizations.</span></p></body></html></string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Disable image optimizations.<br/><span style=" font-weight:600;">Input images must be already resized.</span></p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>No optimisation</string>
|
||||
@@ -91,7 +88,7 @@
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p><span style=" font-size:12pt; font-weight:600; text-decoration: underline;">Unchecked - Nothing<br/></span><span style=" font-size:12pt;">Images smaller than device resolution will not be resized.</span></p><p><span style=" font-size:12pt; font-weight:600; text-decoration: underline;">Indeterminate - Stretching<br/></span><span style=" font-size:12pt;">Images smaller than device resolution will be resized. Aspect ratio will be not preserved.</span></p><p><span style=" font-size:12pt; font-weight:600; text-decoration: underline;">Checked - Upscaling<br/></span><span style=" font-size:12pt;">Images smaller than device resolution will be resized. Aspect ratio will be preserved.</span></p></body></html></string>
|
||||
<string><html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Unchecked - Nothing<br/></span>Images smaller than device resolution will not be resized.</p><p><span style=" font-weight:600; text-decoration: underline;">Indeterminate - Stretching<br/></span>Images smaller than device resolution will be resized. Aspect ratio will be not preserved.</p><p><span style=" font-weight:600; text-decoration: underline;">Checked - Upscaling<br/></span>Images smaller than device resolution will be resized. Aspect ratio will be preserved.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Stretch/Upscale</string>
|
||||
@@ -113,7 +110,7 @@
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p><span style=" font-size:12pt;">Enable auto-splitting of webtoons like </span><span style=" font-size:12pt; font-style:italic;">Tower of God</span><span style=" font-size:12pt;"> or </span><span style=" font-size:12pt; font-style:italic;">Noblesse</span><span style=" font-size:12pt;">.<br/>Pages with a low width, high height and vertical panel flow.</span></p></body></html></string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Enable special parsing mode for WebToons.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Webtoon mode</string>
|
||||
@@ -132,7 +129,7 @@
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p><span style=" font-size:12pt;">Create PNG files instead JPEG.</span></p></body></html></string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Create PNG files instead JPEG.<br/>Quality increase is not noticeable on most of devices.<br/>Output files <span style=" font-weight:600;">might</span> be smaller.<br/><span style=" font-weight:600;">MOBI conversion will be much slower.</span></p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>PNG output</string>
|
||||
@@ -151,7 +148,7 @@
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p><span style=" font-size:12pt; font-weight:600; text-decoration: underline;">Unchecked - Autodetection<br/></span><span style=" font-size:12pt;">Color of margins fill will be detected automatically.</span></p><p><span style=" font-size:12pt; font-weight:600; text-decoration: underline;">Indeterminate - White<br/></span><span style=" font-size:12pt;">Margins will be filled with white color.</span></p><p><span style=" font-size:12pt; font-weight:600; text-decoration: underline;">Checked - Black<br/></span><span style=" font-size:12pt;">Margins will be filled with black color.</span></p></body></html></string>
|
||||
<string><html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Unchecked - Autodetection<br/></span>Color of margins fill will be detected automatically.</p><p><span style=" font-weight:600; text-decoration: underline;">Indeterminate - White<br/></span>Margins will be filled with white color.</p><p><span style=" font-weight:600; text-decoration: underline;">Checked - Black<br/></span>Margins will be filled with black color.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>W/B margins</string>
|
||||
@@ -173,7 +170,7 @@
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p><span style=" font-size:12pt;">Disable splitting and rotation.</span></p></body></html></string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Disable page splitting and rotation.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>No split/rotate</string>
|
||||
@@ -186,7 +183,7 @@
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>8</x>
|
||||
<y>200</y>
|
||||
<y>201</y>
|
||||
<width>151</width>
|
||||
<height>34</height>
|
||||
</rect>
|
||||
@@ -201,14 +198,14 @@
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p><span style=" font-size:12pt;">Target device.</span></p></body></html></string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Target device.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="FormatBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>262</x>
|
||||
<y>200</y>
|
||||
<y>201</y>
|
||||
<width>152</width>
|
||||
<height>34</height>
|
||||
</rect>
|
||||
@@ -223,7 +220,7 @@
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p><span style=" font-size:12pt;">Output format.</span></p></body></html></string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Output format.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="ConvertButton">
|
||||
@@ -246,6 +243,9 @@
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>Shift+Click to select the output directory.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Convert</string>
|
||||
</property>
|
||||
@@ -272,6 +272,9 @@
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>Add directory containing JPG, PNG or GIF files to queue.<br/><span style=" font-weight:600;">CBR, CBZ and CB7 files inside will not be processed!</span></p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add directory</string>
|
||||
</property>
|
||||
@@ -298,6 +301,9 @@
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>Add CBR, CBZ, CB7 or PDF file to queue.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add file</string>
|
||||
</property>
|
||||
@@ -366,7 +372,7 @@
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p><span style=" font-size:12pt;">Enable right-to-left reading.</span></p></body></html></string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Enable right-to-left reading.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Manga mode</string>
|
||||
@@ -391,7 +397,7 @@
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p><span style="font-size:12pt; font-weight:600; text-decoration: underline;">Unchecked - Normal quality mode<br/></span><span style="font-size:12pt; font-style:italic;">Use it when Panel View support is not needed.</span><span style="font-size:12pt; font-weight:600; text-decoration: underline;"><br/></span><span style="font-size:12pt;">- Maximum quality when zoom is not enabled.<br/>- Poor quality when zoom is enabled.<br/>- Lowest file size.</span></p><p><span style="font-size:12pt; font-weight:600; text-decoration: underline;">Indeterminate - High quality mode<br/></span><span style="font-size:12pt; font-style:italic;">Not zoomed image </span><span style="font-size:12pt; font-weight:600; font-style:italic;">might </span><span style="font-size:12pt; font-style:italic;">be a little blurry.</span><span style="font-size:12pt; font-weight:600; text-decoration: underline;"><br/></span><span style="font-size:12pt;">- Medium/High quality when zoom is not enabled.<br/>- Maximum quality when zoom is enabled.</span></p><p><span style="font-size:12pt; font-weight:600; text-decoration: underline;">Checked - Ultra quality mode<br/></span><span style="font-size:12pt; font-style:italic;">Maximum possible quality.</span><span style="font-size:12pt; font-weight:600; text-decoration: underline;"><br/></span><span style="font-size:12pt;">- Maximum quality when zoom is not enabled.<br/>- Maximum quality when zoom is enabled.<br/>- Very high file size.</span></p></body></html></string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Quality of Panel View/zoom. Highly impact size of output file.<br/><span style=" font-weight:600;">This option control only quality of magnification!</span></p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>High/Ultra quality</string>
|
||||
@@ -419,7 +425,7 @@
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p><span style=" font-size:12pt;">Disable page spliting.<br/>They will be rotated instead.</span></p></body></html></string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Disable splitting of two-page spreads.<br/>They will be rotated instead.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Horizontal mode</string>
|
||||
@@ -447,6 +453,9 @@
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QListWidget#JobList {background:#ffffff;background-image:url(:/Other/icons/list_background.png);background-position:center center;background-repeat:no-repeat;}QScrollBar:vertical{border:1px solid #999;background:#FFF;width:5px;margin:0}QScrollBar::handle:vertical{background:DarkGray;min-height:0}QScrollBar::add-line:vertical{height:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:vertical{height:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}QScrollBar:horizontal{border:1px solid #999;background:#FFF;height:5px;margin:0}QScrollBar::handle:horizontal{background:DarkGray;min-width:0}QScrollBar::add-line:horizontal{width:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:horizontal{width:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}</string>
|
||||
</property>
|
||||
<property name="showDropIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
@@ -459,7 +468,7 @@
|
||||
<rect>
|
||||
<x>5</x>
|
||||
<y>10</y>
|
||||
<width>210</width>
|
||||
<width>156</width>
|
||||
<height>41</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -481,9 +490,9 @@
|
||||
<widget class="QPushButton" name="AdvModeButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>207</x>
|
||||
<x>260</x>
|
||||
<y>10</y>
|
||||
<width>210</width>
|
||||
<width>156</width>
|
||||
<height>41</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -537,9 +546,6 @@
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p><span style=" font-size:12pt;">When converting color images setting this option to 1.0 </span><span style=" font-size:12pt; font-weight:600;">might</span><span style=" font-size:12pt;"> improve readability.</span></p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Gamma: Auto</string>
|
||||
</property>
|
||||
@@ -561,9 +567,6 @@
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::ClickFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p><span style=" font-size:12pt;">When converting color images setting this option to 1.0 </span><span style=" font-size:12pt; font-weight:600;">might</span><span style=" font-size:12pt;"> improve readability.</span></p></body></html></string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>500</number>
|
||||
</property>
|
||||
@@ -581,7 +584,7 @@
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>401</width>
|
||||
<height>35</height>
|
||||
<height>29</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
@@ -592,9 +595,6 @@
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>0</number>
|
||||
</property>
|
||||
@@ -639,7 +639,7 @@
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p><span style=" font-size:12pt;">Do not convert images to grayscale.</span></p></body></html></string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Don't convert images to grayscale.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Color mode</string>
|
||||
@@ -671,7 +671,7 @@
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p><span style=" font-size:12pt;">Resolution of target device.</span></p></body></html></string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Resolution of target device.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Custom width: </string>
|
||||
@@ -705,10 +705,10 @@
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p><span style=" font-size:12pt;">Resolution of target device.</span></p></body></html></string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Resolution of target device.</p></body></html></string>
|
||||
</property>
|
||||
<property name="inputMask">
|
||||
<string>0000; </string>
|
||||
<string>0000</string>
|
||||
</property>
|
||||
<property name="maxLength">
|
||||
<number>4</number>
|
||||
@@ -726,7 +726,7 @@
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p><span style=" font-size:12pt;">Resolution of target device.</span></p></body></html></string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Resolution of target device.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Custom height: </string>
|
||||
@@ -760,10 +760,10 @@
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p><span style=" font-size:12pt;">Resolution of target device.</span></p></body></html></string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Resolution of target device.</p></body></html></string>
|
||||
</property>
|
||||
<property name="inputMask">
|
||||
<string>0000; </string>
|
||||
<string>0000</string>
|
||||
</property>
|
||||
<property name="maxLength">
|
||||
<number>4</number>
|
||||
@@ -773,9 +773,34 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="EditorButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>160</x>
|
||||
<y>10</y>
|
||||
<width>101</width>
|
||||
<height>41</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Lucida Grande</family>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Editor</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Other/icons/editor.png</normaloff>:/Other/icons/editor.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
<zorder>BasicModeButton</zorder>
|
||||
<zorder>AdvModeButton</zorder>
|
||||
<zorder>ProgressBar</zorder>
|
||||
<zorder>JobList</zorder>
|
||||
<zorder>OptionsAdvanced</zorder>
|
||||
<zorder>DeviceBox</zorder>
|
||||
@@ -787,6 +812,19 @@
|
||||
<zorder>OptionsBasic</zorder>
|
||||
<zorder>OptionsAdvancedGamma</zorder>
|
||||
<zorder>OptionsExpert</zorder>
|
||||
<zorder>EditorButton</zorder>
|
||||
<zorder>ProgressBar</zorder>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusBar">
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Aharoni</family>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="sizeGripEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<action name="ActionBasic">
|
||||
<property name="checkable">
|
||||
28
gui/KCC.qrc
Normal file
28
gui/KCC.qrc
Normal file
@@ -0,0 +1,28 @@
|
||||
<RCC>
|
||||
<qresource prefix="Icon">
|
||||
<file>../icons/comic2ebook.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="Devices">
|
||||
<file>../icons/Kobo.png</file>
|
||||
<file>../icons/Other.png</file>
|
||||
<file>../icons/Kindle.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="Formats">
|
||||
<file>../icons/CBZ.png</file>
|
||||
<file>../icons/EPUB.png</file>
|
||||
<file>../icons/MOBI.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="Status">
|
||||
<file>../icons/error.png</file>
|
||||
<file>../icons/info.png</file>
|
||||
<file>../icons/warning.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="Other">
|
||||
<file>../icons/editor.png</file>
|
||||
<file>../icons/list_background.png</file>
|
||||
<file>../icons/clear.png</file>
|
||||
<file>../icons/convert.png</file>
|
||||
<file>../icons/document_new.png</file>
|
||||
<file>../icons/folder_new.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -7,19 +7,19 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>420</width>
|
||||
<height>380</height>
|
||||
<height>397</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>420</width>
|
||||
<height>380</height>
|
||||
<height>397</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>420</width>
|
||||
<height>380</height>
|
||||
<height>397</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
@@ -27,9 +27,6 @@
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Kindle Comic Converter</string>
|
||||
</property>
|
||||
@@ -68,7 +65,7 @@
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Disable image optimizations.</string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Disable image optimizations.<br/><span style=" font-weight:600;">Input images must be already resized.</span></p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>No optimisation</string>
|
||||
@@ -97,7 +94,7 @@
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Enable auto-splitting of webtoons like <span style=" font-style:italic;">Tower of God</span> or <span style=" font-style:italic;">Noblesse</span>.<br/>Pages with a low width, high height and vertical panel flow.</p></body></html></string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Enable special parsing mode for WebToons.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Webtoon mode</string>
|
||||
@@ -110,7 +107,7 @@
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Create PNG files instead JPEG.</p></body></html></string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Create PNG files instead JPEG.<br/>Quality increase is not noticeable on most of devices.<br/>Output files <span style=" font-weight:600;">might</span> be smaller.<br/><span style=" font-weight:600;">MOBI conversion will be much slower.</span></p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>PNG output</string>
|
||||
@@ -139,7 +136,7 @@
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Disable splitting and rotation.</p></body></html></string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Disable page splitting and rotation.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>No split/rotate</string>
|
||||
@@ -166,7 +163,7 @@
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Target device.</string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Target device.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="FormatBox">
|
||||
@@ -187,7 +184,7 @@
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Output format.</string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Output format.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="ConvertButton">
|
||||
@@ -209,6 +206,9 @@
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>Shift+Click to select the output directory.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Convert</string>
|
||||
</property>
|
||||
@@ -234,6 +234,9 @@
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>Add directory containing JPG, PNG or GIF files to queue.<br/><span style=" font-weight:600;">CBR, CBZ and CB7 files inside will not be processed!</span></p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add directory</string>
|
||||
</property>
|
||||
@@ -259,6 +262,9 @@
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>Add CBR, CBZ, CB7 or PDF file to queue.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add file</string>
|
||||
</property>
|
||||
@@ -319,7 +325,7 @@
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Enable right-to-left reading.</string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Enable right-to-left reading.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Manga mode</string>
|
||||
@@ -338,13 +344,7 @@
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600; text-decoration: underline;">Unchecked - Normal quality mode<br /></span><span style=" font-style:italic;">Use it when Panel View support is not needed.</span><span style=" font-weight:600; text-decoration: underline;"><br /></span>- Maximum quality when zoom is not enabled.<br />- Poor quality when zoom is enabled.<br />- Lowest file size.</p>
|
||||
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600; text-decoration: underline;">Indeterminate - High quality mode<br /></span><span style=" font-style:italic;">Not zoomed image </span><span style=" font-weight:600; font-style:italic;">might </span><span style=" font-style:italic;">be </span><span style=" font-style:italic;">a little blurry.</span><span style=" font-weight:600; text-decoration: underline;"><br /></span>- Medium/High quality when zoom is not enabled.<br />- Maximum quality when zoom is enabled.</p>
|
||||
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600; text-decoration: underline;">Checked - Ultra quality mode<br /></span><span style=" font-style:italic;">Maximum possible quality.</span><span style=" font-weight:600; text-decoration: underline;"><br /></span>- Maximum quality when zoom is not enabled.<br />- Maximum quality when zoom is enabled.<br />- Very high file size.</p></body></html></string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Quality of Panel View/zoom. Highly impact size of output file.<br/><span style=" font-weight:600;">This option control only quality of magnification!</span></p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>High/Ultra quality</string>
|
||||
@@ -366,7 +366,7 @@ p, li { white-space: pre-wrap; }
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Disable page spliting.<br/>They will be rotated instead.</p></body></html></string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Disable splitting of two-page spreads.<br/>They will be rotated instead.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Horizontal mode</string>
|
||||
@@ -388,6 +388,9 @@ p, li { white-space: pre-wrap; }
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QListWidget#JobList {background:#ffffff;background-image:url(:/Other/icons/list_background.png);background-position:center center;background-repeat:no-repeat;}QScrollBar:vertical{border:1px solid #999;background:#FFF;width:5px;margin:0}QScrollBar::handle:vertical{background:DarkGray;min-height:0}QScrollBar::add-line:vertical{height:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:vertical{height:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}QScrollBar:horizontal{border:1px solid #999;background:#FFF;height:5px;margin:0}QScrollBar::handle:horizontal{background:DarkGray;min-width:0}QScrollBar::add-line:horizontal{width:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:horizontal{width:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}</string>
|
||||
</property>
|
||||
<property name="showDropIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
@@ -400,7 +403,7 @@ p, li { white-space: pre-wrap; }
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>195</width>
|
||||
<width>141</width>
|
||||
<height>32</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -419,9 +422,9 @@ p, li { white-space: pre-wrap; }
|
||||
<widget class="QPushButton" name="AdvModeButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>217</x>
|
||||
<x>261</x>
|
||||
<y>10</y>
|
||||
<width>195</width>
|
||||
<width>151</width>
|
||||
<height>32</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -463,9 +466,6 @@ p, li { white-space: pre-wrap; }
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>When converting color images setting this option to 1.0 MIGHT improve readability.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Gamma: Auto</string>
|
||||
</property>
|
||||
@@ -482,9 +482,6 @@ p, li { white-space: pre-wrap; }
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::ClickFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>When converting color images setting this option to 1.0 <span style=" font-weight:600;">might</span> improve readability.</p></body></html></string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>500</number>
|
||||
</property>
|
||||
@@ -549,7 +546,7 @@ p, li { white-space: pre-wrap; }
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Do not convert images to grayscale.</string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Don't convert images to grayscale.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Color mode</string>
|
||||
@@ -568,7 +565,7 @@ p, li { white-space: pre-wrap; }
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="wLabel">
|
||||
<property name="toolTip">
|
||||
<string>Resolution of target device.</string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Resolution of target device.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Custom width: </string>
|
||||
@@ -596,10 +593,10 @@ p, li { white-space: pre-wrap; }
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Resolution of target device.</string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Resolution of target device.</p></body></html></string>
|
||||
</property>
|
||||
<property name="inputMask">
|
||||
<string>0000; </string>
|
||||
<string>0000</string>
|
||||
</property>
|
||||
<property name="maxLength">
|
||||
<number>4</number>
|
||||
@@ -609,7 +606,7 @@ p, li { white-space: pre-wrap; }
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="hLabel">
|
||||
<property name="toolTip">
|
||||
<string>Resolution of target device.</string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Resolution of target device.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Custom height: </string>
|
||||
@@ -637,10 +634,10 @@ p, li { white-space: pre-wrap; }
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Resolution of target device.</string>
|
||||
<string><html><head/><body><p style='white-space:pre'>Resolution of target device.</p></body></html></string>
|
||||
</property>
|
||||
<property name="inputMask">
|
||||
<string>0000; </string>
|
||||
<string>0000</string>
|
||||
</property>
|
||||
<property name="maxLength">
|
||||
<number>4</number>
|
||||
@@ -650,6 +647,31 @@ p, li { white-space: pre-wrap; }
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="EditorButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>160</x>
|
||||
<y>10</y>
|
||||
<width>91</width>
|
||||
<height>32</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Editor</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Other/icons/editor.png</normaloff>:/Other/icons/editor.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
<zorder>OptionsAdvanced</zorder>
|
||||
<zorder>DeviceBox</zorder>
|
||||
<zorder>FormatBox</zorder>
|
||||
@@ -663,8 +685,20 @@ p, li { white-space: pre-wrap; }
|
||||
<zorder>AdvModeButton</zorder>
|
||||
<zorder>OptionsAdvancedGamma</zorder>
|
||||
<zorder>OptionsExpert</zorder>
|
||||
<zorder>EditorButton</zorder>
|
||||
<zorder>ProgressBar</zorder>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusBar">
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>MS Shell Dlg 2</family>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="sizeGripEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<action name="ActionBasic">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
226
gui/MetaEditor-Linux.ui
Normal file
226
gui/MetaEditor-Linux.ui
Normal file
@@ -0,0 +1,226 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MetaEditorDialog</class>
|
||||
<widget class="QDialog" name="MetaEditorDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>320</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>400</width>
|
||||
<height>320</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>400</width>
|
||||
<height>320</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Metadata editor</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Icon/icons/comic2ebook.png</normaloff>:/Icon/icons/comic2ebook.png</iconset>
|
||||
</property>
|
||||
<widget class="QWidget" name="horizontalLayoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>280</y>
|
||||
<width>381</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="StatusLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(255, 0, 0);</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="OKButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Other/icons/convert.png</normaloff>:/Other/icons/convert.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="CancelButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Cancel</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Other/icons/clear.png</normaloff>:/Other/icons/clear.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QFrame" name="EditorFrame">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>381</width>
|
||||
<height>271</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QWidget" name="formLayoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>381</width>
|
||||
<height>266</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Series:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="SeriesLine"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Volume:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="VolumeLine"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Number:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="NumberLine"/>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Writer:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLineEdit" name="WriterLine"/>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Penciller:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLineEdit" name="PencillerLine"/>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Inker:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QLineEdit" name="InkerLine"/>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Colorist:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QLineEdit" name="ColoristLine"/>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p><a href="https://github.com/ciromattia/kcc/wiki/Manga-Cover-Database-support"><span style=" text-decoration: underline; color:#0000ff;">MUid:</span></a></p></body></html></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QLineEdit" name="MUidLine"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<zorder>horizontalLayoutWidget</zorder>
|
||||
<zorder>EditorFrame</zorder>
|
||||
<zorder>StatusLabel</zorder>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="KCC.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
223
gui/MetaEditor-OSX.ui
Normal file
223
gui/MetaEditor-OSX.ui
Normal file
@@ -0,0 +1,223 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MetaEditorDialog</class>
|
||||
<widget class="QDialog" name="MetaEditorDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>295</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>400</width>
|
||||
<height>295</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>400</width>
|
||||
<height>295</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Metadata editor</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Icon/icons/comic2ebook.png</normaloff>:/Icon/icons/comic2ebook.png</iconset>
|
||||
</property>
|
||||
<widget class="QWidget" name="horizontalLayoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>260</y>
|
||||
<width>381</width>
|
||||
<height>32</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="StatusLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(255, 0, 0);</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="OKButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Other/icons/convert.png</normaloff>:/Other/icons/convert.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="CancelButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Cancel</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Other/icons/clear.png</normaloff>:/Other/icons/clear.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QFrame" name="EditorFrame">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>381</width>
|
||||
<height>251</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QWidget" name="formLayoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>381</width>
|
||||
<height>250</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Series:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="SeriesLine"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Volume:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="VolumeLine"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Number:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="NumberLine"/>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Writer:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLineEdit" name="WriterLine"/>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Penciller:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLineEdit" name="PencillerLine"/>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Inker:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QLineEdit" name="InkerLine"/>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Colorist:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QLineEdit" name="ColoristLine"/>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p><a href="https://github.com/ciromattia/kcc/wiki/Manga-Cover-Database-support"><span style=" text-decoration: underline; color:#0000ff;">MUid:</span></a></p></body></html></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QLineEdit" name="MUidLine"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="KCC.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
222
gui/MetaEditor.ui
Normal file
222
gui/MetaEditor.ui
Normal file
@@ -0,0 +1,222 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MetaEditorDialog</class>
|
||||
<widget class="QDialog" name="MetaEditorDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>260</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>400</width>
|
||||
<height>260</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>400</width>
|
||||
<height>260</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Metadata editor</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Icon/icons/comic2ebook.png</normaloff>:/Icon/icons/comic2ebook.png</iconset>
|
||||
</property>
|
||||
<widget class="QWidget" name="horizontalLayoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>220</y>
|
||||
<width>381</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="StatusLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(255, 0, 0);</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="OKButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Other/icons/convert.png</normaloff>:/Other/icons/convert.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="CancelButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Cancel</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Other/icons/clear.png</normaloff>:/Other/icons/clear.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QFrame" name="EditorFrame">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>381</width>
|
||||
<height>211</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QWidget" name="formLayoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>381</width>
|
||||
<height>211</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Series:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="SeriesLine"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Volume:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="VolumeLine"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Number:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="NumberLine"/>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Writer:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLineEdit" name="WriterLine"/>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Penciller:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLineEdit" name="PencillerLine"/>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Inker:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QLineEdit" name="InkerLine"/>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Colorist:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QLineEdit" name="ColoristLine"/>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p><a href="https://github.com/ciromattia/kcc/wiki/Manga-Cover-Database-support"><span style=" text-decoration: underline; color:#0000ff;">MUid:</span></a></p></body></html></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QLineEdit" name="MUidLine"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="KCC.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
BIN
icons/Kobo.png
Normal file
BIN
icons/Kobo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
BIN
icons/Wizard-Small.bmp
Normal file
BIN
icons/Wizard-Small.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
BIN
icons/Wizard.bmp
Normal file
BIN
icons/Wizard.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 201 KiB |
BIN
icons/editor.png
Normal file
BIN
icons/editor.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
BIN
icons/list_background.png
Normal file
BIN
icons/list_background.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.1 KiB |
BIN
icons/list_background.xcf
Normal file
BIN
icons/list_background.xcf
Normal file
Binary file not shown.
37
kcc-c2e.py
Executable file
37
kcc-c2e.py
Executable file
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
|
||||
# Copyright (c) 2013-2015 Pawel Jastrzebski <pawelj@iosphe.re>
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for
|
||||
# any purpose with or without fee is hereby granted, provided that the
|
||||
# above copyright notice and this permission notice appear in all
|
||||
# copies.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
# AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
|
||||
# OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
import sys
|
||||
if sys.version_info[0] != 3:
|
||||
print('ERROR: This is Python 3 script!')
|
||||
exit(1)
|
||||
|
||||
from kcc.shared import dependencyCheck
|
||||
dependencyCheck(2)
|
||||
|
||||
from multiprocessing import freeze_support
|
||||
from kcc import __version__
|
||||
from kcc.comic2ebook import main
|
||||
|
||||
if __name__ == "__main__":
|
||||
freeze_support()
|
||||
print('comic2ebook v' + __version__ + ' - Written by Ciro Mattia Gonano and Pawel Jastrzebski.')
|
||||
main(sys.argv[1:])
|
||||
sys.exit(0)
|
||||
37
kcc-c2p.py
Executable file
37
kcc-c2p.py
Executable file
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
|
||||
# Copyright (c) 2013-2015 Pawel Jastrzebski <pawelj@iosphe.re>
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for
|
||||
# any purpose with or without fee is hereby granted, provided that the
|
||||
# above copyright notice and this permission notice appear in all
|
||||
# copies.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
# AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
|
||||
# OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
import sys
|
||||
if sys.version_info[0] != 3:
|
||||
print('ERROR: This is Python 3 script!')
|
||||
exit(1)
|
||||
|
||||
from kcc.shared import dependencyCheck
|
||||
dependencyCheck(1)
|
||||
|
||||
from multiprocessing import freeze_support
|
||||
from kcc import __version__
|
||||
from kcc.comic2panel import main
|
||||
|
||||
if __name__ == "__main__":
|
||||
freeze_support()
|
||||
print('comic2panel v' + __version__ + ' - Written by Ciro Mattia Gonano and Pawel Jastrzebski.')
|
||||
main(sys.argv[1:])
|
||||
sys.exit(0)
|
||||
133
kcc.iss
Normal file
133
kcc.iss
Normal file
@@ -0,0 +1,133 @@
|
||||
#define MyAppName "Kindle Comic Converter"
|
||||
#define MyAppVersion "4.5"
|
||||
#define MyAppPublisher "Ciro Mattia Gonano, Paweł Jastrzębski"
|
||||
#define MyAppURL "http://kcc.iosphe.re/"
|
||||
#define MyAppExeName "KCC.exe"
|
||||
|
||||
[Setup]
|
||||
AppId={{7D279A59-C65E-4DA7-B165-56DD06596216}
|
||||
AppName={#MyAppName}
|
||||
AppVersion={#MyAppVersion}
|
||||
AppPublisher={#MyAppPublisher}
|
||||
AppPublisherURL={#MyAppURL}
|
||||
AppSupportURL={#MyAppURL}
|
||||
AppUpdatesURL={#MyAppURL}
|
||||
AppCopyright=Copyright (C) 2012-2015 Ciro Mattia Gonano and Paweł Jastrzębski
|
||||
DefaultDirName={pf}\{#MyAppName}
|
||||
DefaultGroupName={#MyAppName}
|
||||
AllowNoIcons=yes
|
||||
LicenseFile=LICENSE.txt
|
||||
OutputBaseFilename=KindleComicConverter_win_{#MyAppVersion}
|
||||
SetupIconFile=icons\comic2ebook.ico
|
||||
SolidCompression=yes
|
||||
ArchitecturesInstallIn64BitMode=x64
|
||||
ShowLanguageDialog=no
|
||||
LanguageDetectionMethod=none
|
||||
WizardImageFile=icons\Wizard.bmp
|
||||
WizardSmallImageFile=icons\Wizard-Small.bmp
|
||||
UninstallDisplayName={#MyAppName}
|
||||
UninstallDisplayIcon={app}\{#MyAppExeName}
|
||||
ChangesAssociations=True
|
||||
InfoAfterFile=other\InstallWarning.rtf
|
||||
SignTool=SignTool /d $q{#MyAppName}$q /du $q{#MyAppURL}$q $f
|
||||
MinVersion=0,6.0
|
||||
|
||||
[Languages]
|
||||
Name: "english"; MessagesFile: "compiler:Default.isl"
|
||||
|
||||
[Tasks]
|
||||
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
|
||||
Name: "CBZassociation"; Description: "CBZ"; GroupDescription: "File associations:"
|
||||
Name: "CBRassociation"; Description: "CBR"; GroupDescription: "File associations:"
|
||||
Name: "CB7association"; Description: "CB7"; GroupDescription: "File associations:"
|
||||
|
||||
[Files]
|
||||
; x64 files
|
||||
Source: "dist_64\platforms\*"; DestDir: "{app}\platforms\"; Flags: ignoreversion; Check: Is64BitInstallMode
|
||||
Source: "dist_64\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion; Check: Is64BitInstallMode
|
||||
Source: "dist_64\*.dll"; DestDir: "{app}"; Flags: ignoreversion; Check: Is64BitInstallMode
|
||||
Source: "other\vcredist_x64.exe"; DestDir: "{tmp}"; Flags: ignoreversion deleteafterinstall; Check: Is64BitInstallMode
|
||||
; x86 files
|
||||
Source: "dist\platforms\*"; DestDir: "{app}\platforms\"; Flags: ignoreversion; Check: not Is64BitInstallMode
|
||||
Source: "dist\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion; Check: not Is64BitInstallMode
|
||||
Source: "dist\*.dll"; DestDir: "{app}"; Flags: ignoreversion; Check: not Is64BitInstallMode
|
||||
Source: "other\vcredist_x86.exe"; DestDir: "{tmp}"; Flags: ignoreversion deleteafterinstall; Check: not Is64BitInstallMode
|
||||
; Common files
|
||||
Source: "LICENSE.txt"; DestDir: "{app}"; Flags: ignoreversion solidbreak
|
||||
Source: "other\Additional-LICENSE.txt"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "other\UnRAR.exe"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "other\7za.exe"; DestDir: "{app}"; Flags: ignoreversion
|
||||
|
||||
[Icons]
|
||||
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
|
||||
Name: "{group}\Readme"; Filename: "https://github.com/ciromattia/kcc#kcc"
|
||||
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
|
||||
|
||||
[Run]
|
||||
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall
|
||||
Filename: "{tmp}\vcredist_x64.exe"; Parameters: "/passive /Q:a /c:""msiexec /qb /i vcredist.msi"" "; StatusMsg: "Installing Microsoft Visual C++ 2010 Redistributable Package..."; Check: Is64BitInstallMode
|
||||
Filename: "{tmp}\vcredist_x86.exe"; Parameters: "/passive /Q:a /c:""msiexec /qb /i vcredist.msi"" "; StatusMsg: "Installing Microsoft Visual C++ 2010 Redistributable Package..."; Check: not Is64BitInstallMode
|
||||
|
||||
[Messages]
|
||||
WelcomeLabel1=Welcome to the KCC Setup Wizard
|
||||
FinishedHeadingLabel=Completing the KCC Setup Wizard
|
||||
|
||||
[Registry]
|
||||
Root: HKCR; SubKey: ".cbz"; ValueType: string; ValueData: "KCCZIP"; Flags: uninsdeletekey; Tasks: CBZassociation
|
||||
Root: HKCR; SubKey: "KCCZIP"; ValueType: string; ValueData: "KCC ZIP Archive"; Flags: uninsdeletekey; Tasks: CBZassociation
|
||||
Root: HKCR; SubKey: "KCCZIP\Shell\Open\Command"; ValueType: string; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Flags: uninsdeletekey; Tasks: CBZassociation
|
||||
Root: HKCR; Subkey: "KCCZIP\DefaultIcon"; ValueType: string; ValueData: "{app}\{#MyAppExeName},0"; Flags: uninsdeletevalue; Tasks: CBZassociation
|
||||
Root: HKCR; SubKey: ".cbr"; ValueType: string; ValueData: "KCCRAR"; Flags: uninsdeletekey; Tasks: CBRassociation
|
||||
Root: HKCR; SubKey: "KCCRAR"; ValueType: string; ValueData: "KCC RAR Archive"; Flags: uninsdeletekey; Tasks: CBRassociation
|
||||
Root: HKCR; SubKey: "KCCRAR\Shell\Open\Command"; ValueType: string; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Flags: uninsdeletekey; Tasks: CBRassociation
|
||||
Root: HKCR; Subkey: "KCCRAR\DefaultIcon"; ValueType: string; ValueData: "{app}\{#MyAppExeName},0"; Flags: uninsdeletevalue; Tasks: CBRassociation
|
||||
Root: HKCR; SubKey: ".cb7"; ValueType: string; ValueData: "KCCCB7"; Flags: uninsdeletekey; Tasks: CB7association
|
||||
Root: HKCR; SubKey: "KCCCB7"; ValueType: string; ValueData: "KCC 7z Archive"; Flags: uninsdeletekey; Tasks: CB7association
|
||||
Root: HKCR; SubKey: "KCCCB7\Shell\Open\Command"; ValueType: string; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Flags: uninsdeletekey; Tasks: CB7association
|
||||
Root: HKCR; Subkey: "KCCCB7\DefaultIcon"; ValueType: string; ValueData: "{app}\{#MyAppExeName},0"; Flags: uninsdeletevalue; Tasks: CB7association
|
||||
|
||||
[Code]
|
||||
function GetUninstallString(): String;
|
||||
var
|
||||
sUnInstPath: String;
|
||||
sUnInstallString: String;
|
||||
begin
|
||||
sUnInstPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{#emit SetupSetting("AppId")}_is1');
|
||||
sUnInstallString := '';
|
||||
if not RegQueryStringValue(HKLM, sUnInstPath, 'UninstallString', sUnInstallString) then
|
||||
RegQueryStringValue(HKCU, sUnInstPath, 'UninstallString', sUnInstallString);
|
||||
Result := sUnInstallString;
|
||||
end;
|
||||
|
||||
function IsUpgrade(): Boolean;
|
||||
begin
|
||||
Result := (GetUninstallString() <> '');
|
||||
end;
|
||||
|
||||
function UnInstallOldVersion(): Integer;
|
||||
var
|
||||
sUnInstallString: String;
|
||||
iResultCode: Integer;
|
||||
begin
|
||||
Result := 0;
|
||||
sUnInstallString := GetUninstallString();
|
||||
if sUnInstallString <> '' then begin
|
||||
sUnInstallString := RemoveQuotes(sUnInstallString);
|
||||
if Exec(sUnInstallString, '/SILENT /NORESTART /SUPPRESSMSGBOXES','', SW_HIDE, ewWaitUntilTerminated, iResultCode) then
|
||||
Result := 3
|
||||
else
|
||||
Result := 2;
|
||||
end else
|
||||
Result := 1;
|
||||
end;
|
||||
|
||||
procedure CurStepChanged(CurStep: TSetupStep);
|
||||
begin
|
||||
if (CurStep=ssInstall) then
|
||||
begin
|
||||
if (IsUpgrade()) then
|
||||
begin
|
||||
UnInstallOldVersion();
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
81
kcc.py
Normal file → Executable file
81
kcc.py
Normal file → Executable file
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2012-2013 Ciro Mattia Gonano <ciromattia@gmail.com>
|
||||
# Copyright (c) 2013 Pawel Jastrzebski <pawelj@vulturis.eu>
|
||||
# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
|
||||
# Copyright (c) 2013-2015 Pawel Jastrzebski <pawelj@iosphe.re>
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for
|
||||
# any purpose with or without fee is hereby granted, provided that the
|
||||
@@ -18,35 +18,52 @@
|
||||
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
__version__ = '3.3'
|
||||
__license__ = 'ISC'
|
||||
__copyright__ = '2012-2013, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import sys
|
||||
import os
|
||||
try:
|
||||
# noinspection PyUnresolvedReferences
|
||||
from PyQt4 import QtGui
|
||||
except ImportError:
|
||||
print "ERROR: PyQT4 is not installed!"
|
||||
if sys.version_info[0] != 3:
|
||||
print('ERROR: This is Python 3 script!')
|
||||
exit(1)
|
||||
from kcc import KCC_gui
|
||||
from multiprocessing import freeze_support
|
||||
if sys.platform.startswith('darwin'):
|
||||
from kcc import KCC_ui_osx as KCC_ui
|
||||
elif sys.platform.startswith('linux'):
|
||||
from kcc import KCC_ui_linux as KCC_ui
|
||||
else:
|
||||
from kcc import KCC_ui
|
||||
|
||||
freeze_support()
|
||||
APP = QtGui.QApplication(sys.argv)
|
||||
KCC = QtGui.QMainWindow()
|
||||
UI = KCC_ui.Ui_KCC()
|
||||
UI.setupUi(KCC)
|
||||
GUI = KCC_gui.Ui_KCC(UI, KCC)
|
||||
KCC.setWindowTitle("Kindle Comic Converter " + __version__)
|
||||
KCC.show()
|
||||
KCC.raise_()
|
||||
sys.exit(APP.exec_())
|
||||
# OS specific PATH variable workarounds
|
||||
import os
|
||||
if sys.platform.startswith('darwin'):
|
||||
if 'RESOURCEPATH' not in os.environ:
|
||||
os.environ['PATH'] = os.path.dirname(os.path.abspath(__file__)) + '/other/:' + os.environ['PATH']
|
||||
else:
|
||||
os.environ['PATH'] = './../Resources:/usr/local/bin:/usr/bin:/bin'
|
||||
elif sys.platform.startswith('win'):
|
||||
if getattr(sys, 'frozen', False):
|
||||
os.chdir(os.path.dirname(os.path.abspath(sys.executable)))
|
||||
|
||||
# Implementing dummy stdout and stderr for frozen Windows release
|
||||
class FakeSTD(object):
|
||||
def write(self, string):
|
||||
pass
|
||||
|
||||
def flush(self):
|
||||
pass
|
||||
sys.stdout = FakeSTD()
|
||||
sys.stderr = FakeSTD()
|
||||
else:
|
||||
os.environ['PATH'] = os.path.dirname(os.path.abspath(__file__)) + '/other/;' + os.environ['PATH']
|
||||
os.chdir(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
from kcc.shared import dependencyCheck
|
||||
dependencyCheck(3)
|
||||
|
||||
from multiprocessing import freeze_support
|
||||
from kcc import KCC_gui
|
||||
|
||||
if __name__ == "__main__":
|
||||
freeze_support()
|
||||
KCCAplication = KCC_gui.QApplicationMessaging(sys.argv)
|
||||
if KCCAplication.isRunning():
|
||||
if len(sys.argv) > 1:
|
||||
KCCAplication.sendMessage(sys.argv[1])
|
||||
else:
|
||||
KCCAplication.sendMessage('ARISE')
|
||||
else:
|
||||
KCCWindow = KCC_gui.QMainWindowKCC()
|
||||
KCCUI = KCC_gui.KCCGUI(KCCAplication, KCCWindow)
|
||||
if len(sys.argv) > 1:
|
||||
KCCUI.handleMessage(sys.argv[1])
|
||||
sys.exit(KCCAplication.exec_())
|
||||
|
||||
147
kcc/KCC_MetaEditor_ui.py
Normal file
147
kcc/KCC_MetaEditor_ui.py
Normal file
@@ -0,0 +1,147 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'MetaEditor.ui'
|
||||
#
|
||||
# Created: Sun Feb 8 11:52:00 2015
|
||||
# by: PyQt5 UI code generator 5.4
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
class Ui_MetaEditorDialog(object):
|
||||
def setupUi(self, MetaEditorDialog):
|
||||
MetaEditorDialog.setObjectName("MetaEditorDialog")
|
||||
MetaEditorDialog.resize(400, 260)
|
||||
MetaEditorDialog.setMinimumSize(QtCore.QSize(400, 260))
|
||||
MetaEditorDialog.setMaximumSize(QtCore.QSize(400, 260))
|
||||
icon = QtGui.QIcon()
|
||||
icon.addPixmap(QtGui.QPixmap(":/Icon/icons/comic2ebook.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
MetaEditorDialog.setWindowIcon(icon)
|
||||
self.horizontalLayoutWidget = QtWidgets.QWidget(MetaEditorDialog)
|
||||
self.horizontalLayoutWidget.setGeometry(QtCore.QRect(10, 220, 381, 31))
|
||||
self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
|
||||
self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
|
||||
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||
self.StatusLabel = QtWidgets.QLabel(self.horizontalLayoutWidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.StatusLabel.sizePolicy().hasHeightForWidth())
|
||||
self.StatusLabel.setSizePolicy(sizePolicy)
|
||||
font = QtGui.QFont()
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.StatusLabel.setFont(font)
|
||||
self.StatusLabel.setStyleSheet("color: rgb(255, 0, 0);")
|
||||
self.StatusLabel.setObjectName("StatusLabel")
|
||||
self.horizontalLayout.addWidget(self.StatusLabel)
|
||||
self.OKButton = QtWidgets.QPushButton(self.horizontalLayoutWidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.OKButton.sizePolicy().hasHeightForWidth())
|
||||
self.OKButton.setSizePolicy(sizePolicy)
|
||||
font = QtGui.QFont()
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.OKButton.setFont(font)
|
||||
icon1 = QtGui.QIcon()
|
||||
icon1.addPixmap(QtGui.QPixmap(":/Other/icons/convert.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.OKButton.setIcon(icon1)
|
||||
self.OKButton.setObjectName("OKButton")
|
||||
self.horizontalLayout.addWidget(self.OKButton)
|
||||
self.CancelButton = QtWidgets.QPushButton(self.horizontalLayoutWidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.CancelButton.sizePolicy().hasHeightForWidth())
|
||||
self.CancelButton.setSizePolicy(sizePolicy)
|
||||
font = QtGui.QFont()
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.CancelButton.setFont(font)
|
||||
icon2 = QtGui.QIcon()
|
||||
icon2.addPixmap(QtGui.QPixmap(":/Other/icons/clear.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.CancelButton.setIcon(icon2)
|
||||
self.CancelButton.setObjectName("CancelButton")
|
||||
self.horizontalLayout.addWidget(self.CancelButton)
|
||||
self.EditorFrame = QtWidgets.QFrame(MetaEditorDialog)
|
||||
self.EditorFrame.setGeometry(QtCore.QRect(10, 10, 381, 211))
|
||||
self.EditorFrame.setObjectName("EditorFrame")
|
||||
self.formLayoutWidget = QtWidgets.QWidget(self.EditorFrame)
|
||||
self.formLayoutWidget.setGeometry(QtCore.QRect(0, 0, 381, 211))
|
||||
self.formLayoutWidget.setObjectName("formLayoutWidget")
|
||||
self.formLayout = QtWidgets.QFormLayout(self.formLayoutWidget)
|
||||
self.formLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.formLayout.setObjectName("formLayout")
|
||||
self.label = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label.setObjectName("label")
|
||||
self.formLayout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label)
|
||||
self.SeriesLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.SeriesLine.setObjectName("SeriesLine")
|
||||
self.formLayout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.SeriesLine)
|
||||
self.label_2 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_2.setObjectName("label_2")
|
||||
self.formLayout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.label_2)
|
||||
self.VolumeLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.VolumeLine.setObjectName("VolumeLine")
|
||||
self.formLayout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.VolumeLine)
|
||||
self.label_3 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_3.setObjectName("label_3")
|
||||
self.formLayout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.label_3)
|
||||
self.NumberLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.NumberLine.setObjectName("NumberLine")
|
||||
self.formLayout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.NumberLine)
|
||||
self.label_4 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_4.setObjectName("label_4")
|
||||
self.formLayout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.label_4)
|
||||
self.WriterLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.WriterLine.setObjectName("WriterLine")
|
||||
self.formLayout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.WriterLine)
|
||||
self.label_5 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_5.setObjectName("label_5")
|
||||
self.formLayout.setWidget(5, QtWidgets.QFormLayout.LabelRole, self.label_5)
|
||||
self.PencillerLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.PencillerLine.setObjectName("PencillerLine")
|
||||
self.formLayout.setWidget(5, QtWidgets.QFormLayout.FieldRole, self.PencillerLine)
|
||||
self.label_6 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_6.setObjectName("label_6")
|
||||
self.formLayout.setWidget(6, QtWidgets.QFormLayout.LabelRole, self.label_6)
|
||||
self.InkerLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.InkerLine.setObjectName("InkerLine")
|
||||
self.formLayout.setWidget(6, QtWidgets.QFormLayout.FieldRole, self.InkerLine)
|
||||
self.label_7 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_7.setObjectName("label_7")
|
||||
self.formLayout.setWidget(7, QtWidgets.QFormLayout.LabelRole, self.label_7)
|
||||
self.ColoristLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.ColoristLine.setObjectName("ColoristLine")
|
||||
self.formLayout.setWidget(7, QtWidgets.QFormLayout.FieldRole, self.ColoristLine)
|
||||
self.label_8 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_8.setTextFormat(QtCore.Qt.RichText)
|
||||
self.label_8.setOpenExternalLinks(True)
|
||||
self.label_8.setObjectName("label_8")
|
||||
self.formLayout.setWidget(8, QtWidgets.QFormLayout.LabelRole, self.label_8)
|
||||
self.MUidLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.MUidLine.setObjectName("MUidLine")
|
||||
self.formLayout.setWidget(8, QtWidgets.QFormLayout.FieldRole, self.MUidLine)
|
||||
|
||||
self.retranslateUi(MetaEditorDialog)
|
||||
QtCore.QMetaObject.connectSlotsByName(MetaEditorDialog)
|
||||
|
||||
def retranslateUi(self, MetaEditorDialog):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
MetaEditorDialog.setWindowTitle(_translate("MetaEditorDialog", "Metadata editor"))
|
||||
self.OKButton.setText(_translate("MetaEditorDialog", "Save"))
|
||||
self.CancelButton.setText(_translate("MetaEditorDialog", "Cancel"))
|
||||
self.label.setText(_translate("MetaEditorDialog", "Series:"))
|
||||
self.label_2.setText(_translate("MetaEditorDialog", "Volume:"))
|
||||
self.label_3.setText(_translate("MetaEditorDialog", "Number:"))
|
||||
self.label_4.setText(_translate("MetaEditorDialog", "Writer:"))
|
||||
self.label_5.setText(_translate("MetaEditorDialog", "Penciller:"))
|
||||
self.label_6.setText(_translate("MetaEditorDialog", "Inker:"))
|
||||
self.label_7.setText(_translate("MetaEditorDialog", "Colorist:"))
|
||||
self.label_8.setText(_translate("MetaEditorDialog", "<html><head/><body><p><a href=\"https://github.com/ciromattia/kcc/wiki/Manga-Cover-Database-support\"><span style=\" text-decoration: underline; color:#0000ff;\">MUid:</span></a></p></body></html>"))
|
||||
|
||||
from . import KCC_rc
|
||||
148
kcc/KCC_MetaEditor_ui_linux.py
Normal file
148
kcc/KCC_MetaEditor_ui_linux.py
Normal file
@@ -0,0 +1,148 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'gui/MetaEditor.ui'
|
||||
#
|
||||
# Created: Sun Feb 8 03:24:23 2015
|
||||
# by: PyQt5 UI code generator 5.2.1
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
class Ui_MetaEditorDialog(object):
|
||||
def setupUi(self, MetaEditorDialog):
|
||||
MetaEditorDialog.setObjectName("MetaEditorDialog")
|
||||
MetaEditorDialog.resize(400, 320)
|
||||
MetaEditorDialog.setMinimumSize(QtCore.QSize(400, 320))
|
||||
MetaEditorDialog.setMaximumSize(QtCore.QSize(400, 320))
|
||||
icon = QtGui.QIcon()
|
||||
icon.addPixmap(QtGui.QPixmap(":/Icon/icons/comic2ebook.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
MetaEditorDialog.setWindowIcon(icon)
|
||||
self.horizontalLayoutWidget = QtWidgets.QWidget(MetaEditorDialog)
|
||||
self.horizontalLayoutWidget.setGeometry(QtCore.QRect(10, 280, 381, 31))
|
||||
self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
|
||||
self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
|
||||
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||
self.StatusLabel = QtWidgets.QLabel(self.horizontalLayoutWidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.StatusLabel.sizePolicy().hasHeightForWidth())
|
||||
self.StatusLabel.setSizePolicy(sizePolicy)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.StatusLabel.setFont(font)
|
||||
self.StatusLabel.setStyleSheet("color: rgb(255, 0, 0);")
|
||||
self.StatusLabel.setObjectName("StatusLabel")
|
||||
self.horizontalLayout.addWidget(self.StatusLabel)
|
||||
self.OKButton = QtWidgets.QPushButton(self.horizontalLayoutWidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.OKButton.sizePolicy().hasHeightForWidth())
|
||||
self.OKButton.setSizePolicy(sizePolicy)
|
||||
font = QtGui.QFont()
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.OKButton.setFont(font)
|
||||
icon1 = QtGui.QIcon()
|
||||
icon1.addPixmap(QtGui.QPixmap(":/Other/icons/convert.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.OKButton.setIcon(icon1)
|
||||
self.OKButton.setObjectName("OKButton")
|
||||
self.horizontalLayout.addWidget(self.OKButton)
|
||||
self.CancelButton = QtWidgets.QPushButton(self.horizontalLayoutWidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.CancelButton.sizePolicy().hasHeightForWidth())
|
||||
self.CancelButton.setSizePolicy(sizePolicy)
|
||||
font = QtGui.QFont()
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.CancelButton.setFont(font)
|
||||
icon2 = QtGui.QIcon()
|
||||
icon2.addPixmap(QtGui.QPixmap(":/Other/icons/clear.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.CancelButton.setIcon(icon2)
|
||||
self.CancelButton.setObjectName("CancelButton")
|
||||
self.horizontalLayout.addWidget(self.CancelButton)
|
||||
self.EditorFrame = QtWidgets.QFrame(MetaEditorDialog)
|
||||
self.EditorFrame.setGeometry(QtCore.QRect(10, 10, 381, 271))
|
||||
self.EditorFrame.setObjectName("EditorFrame")
|
||||
self.formLayoutWidget = QtWidgets.QWidget(self.EditorFrame)
|
||||
self.formLayoutWidget.setGeometry(QtCore.QRect(0, 0, 381, 266))
|
||||
self.formLayoutWidget.setObjectName("formLayoutWidget")
|
||||
self.formLayout = QtWidgets.QFormLayout(self.formLayoutWidget)
|
||||
self.formLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.formLayout.setObjectName("formLayout")
|
||||
self.label = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label.setObjectName("label")
|
||||
self.formLayout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label)
|
||||
self.SeriesLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.SeriesLine.setObjectName("SeriesLine")
|
||||
self.formLayout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.SeriesLine)
|
||||
self.label_2 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_2.setObjectName("label_2")
|
||||
self.formLayout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.label_2)
|
||||
self.VolumeLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.VolumeLine.setObjectName("VolumeLine")
|
||||
self.formLayout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.VolumeLine)
|
||||
self.label_3 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_3.setObjectName("label_3")
|
||||
self.formLayout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.label_3)
|
||||
self.NumberLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.NumberLine.setObjectName("NumberLine")
|
||||
self.formLayout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.NumberLine)
|
||||
self.label_4 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_4.setObjectName("label_4")
|
||||
self.formLayout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.label_4)
|
||||
self.WriterLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.WriterLine.setObjectName("WriterLine")
|
||||
self.formLayout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.WriterLine)
|
||||
self.label_5 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_5.setObjectName("label_5")
|
||||
self.formLayout.setWidget(5, QtWidgets.QFormLayout.LabelRole, self.label_5)
|
||||
self.PencillerLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.PencillerLine.setObjectName("PencillerLine")
|
||||
self.formLayout.setWidget(5, QtWidgets.QFormLayout.FieldRole, self.PencillerLine)
|
||||
self.label_6 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_6.setObjectName("label_6")
|
||||
self.formLayout.setWidget(6, QtWidgets.QFormLayout.LabelRole, self.label_6)
|
||||
self.InkerLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.InkerLine.setObjectName("InkerLine")
|
||||
self.formLayout.setWidget(6, QtWidgets.QFormLayout.FieldRole, self.InkerLine)
|
||||
self.label_7 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_7.setObjectName("label_7")
|
||||
self.formLayout.setWidget(7, QtWidgets.QFormLayout.LabelRole, self.label_7)
|
||||
self.ColoristLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.ColoristLine.setObjectName("ColoristLine")
|
||||
self.formLayout.setWidget(7, QtWidgets.QFormLayout.FieldRole, self.ColoristLine)
|
||||
self.label_8 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_8.setTextFormat(QtCore.Qt.RichText)
|
||||
self.label_8.setOpenExternalLinks(True)
|
||||
self.label_8.setObjectName("label_8")
|
||||
self.formLayout.setWidget(8, QtWidgets.QFormLayout.LabelRole, self.label_8)
|
||||
self.MUidLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.MUidLine.setObjectName("MUidLine")
|
||||
self.formLayout.setWidget(8, QtWidgets.QFormLayout.FieldRole, self.MUidLine)
|
||||
|
||||
self.retranslateUi(MetaEditorDialog)
|
||||
QtCore.QMetaObject.connectSlotsByName(MetaEditorDialog)
|
||||
|
||||
def retranslateUi(self, MetaEditorDialog):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
MetaEditorDialog.setWindowTitle(_translate("MetaEditorDialog", "Metadata editor"))
|
||||
self.OKButton.setText(_translate("MetaEditorDialog", "Save"))
|
||||
self.CancelButton.setText(_translate("MetaEditorDialog", "Cancel"))
|
||||
self.label.setText(_translate("MetaEditorDialog", "Series:"))
|
||||
self.label_2.setText(_translate("MetaEditorDialog", "Volume:"))
|
||||
self.label_3.setText(_translate("MetaEditorDialog", "Number:"))
|
||||
self.label_4.setText(_translate("MetaEditorDialog", "Writer:"))
|
||||
self.label_5.setText(_translate("MetaEditorDialog", "Penciller:"))
|
||||
self.label_6.setText(_translate("MetaEditorDialog", "Inker:"))
|
||||
self.label_7.setText(_translate("MetaEditorDialog", "Colorist:"))
|
||||
self.label_8.setText(_translate("MetaEditorDialog", "<html><head/><body><p><a href=\"https://github.com/ciromattia/kcc/wiki/Manga-Cover-Database-support\"><span style=\" text-decoration: underline; color:#0000ff;\">MUid:</span></a></p></body></html>"))
|
||||
|
||||
from . import KCC_rc
|
||||
148
kcc/KCC_MetaEditor_ui_osx.py
Normal file
148
kcc/KCC_MetaEditor_ui_osx.py
Normal file
@@ -0,0 +1,148 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file '/Users/pawelj/Documents/KCC/gui/MetaEditor.ui'
|
||||
#
|
||||
# Created: Sun Feb 8 12:47:09 2015
|
||||
# by: PyQt5 UI code generator 5.4
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
class Ui_MetaEditorDialog(object):
|
||||
def setupUi(self, MetaEditorDialog):
|
||||
MetaEditorDialog.setObjectName("MetaEditorDialog")
|
||||
MetaEditorDialog.resize(400, 295)
|
||||
MetaEditorDialog.setMinimumSize(QtCore.QSize(400, 295))
|
||||
MetaEditorDialog.setMaximumSize(QtCore.QSize(400, 295))
|
||||
icon = QtGui.QIcon()
|
||||
icon.addPixmap(QtGui.QPixmap(":/Icon/icons/comic2ebook.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
MetaEditorDialog.setWindowIcon(icon)
|
||||
self.horizontalLayoutWidget = QtWidgets.QWidget(MetaEditorDialog)
|
||||
self.horizontalLayoutWidget.setGeometry(QtCore.QRect(10, 260, 381, 32))
|
||||
self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
|
||||
self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
|
||||
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||
self.StatusLabel = QtWidgets.QLabel(self.horizontalLayoutWidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.StatusLabel.sizePolicy().hasHeightForWidth())
|
||||
self.StatusLabel.setSizePolicy(sizePolicy)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.StatusLabel.setFont(font)
|
||||
self.StatusLabel.setStyleSheet("color: rgb(255, 0, 0);")
|
||||
self.StatusLabel.setObjectName("StatusLabel")
|
||||
self.horizontalLayout.addWidget(self.StatusLabel)
|
||||
self.OKButton = QtWidgets.QPushButton(self.horizontalLayoutWidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.OKButton.sizePolicy().hasHeightForWidth())
|
||||
self.OKButton.setSizePolicy(sizePolicy)
|
||||
font = QtGui.QFont()
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.OKButton.setFont(font)
|
||||
icon1 = QtGui.QIcon()
|
||||
icon1.addPixmap(QtGui.QPixmap(":/Other/icons/convert.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.OKButton.setIcon(icon1)
|
||||
self.OKButton.setObjectName("OKButton")
|
||||
self.horizontalLayout.addWidget(self.OKButton)
|
||||
self.CancelButton = QtWidgets.QPushButton(self.horizontalLayoutWidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.CancelButton.sizePolicy().hasHeightForWidth())
|
||||
self.CancelButton.setSizePolicy(sizePolicy)
|
||||
font = QtGui.QFont()
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.CancelButton.setFont(font)
|
||||
icon2 = QtGui.QIcon()
|
||||
icon2.addPixmap(QtGui.QPixmap(":/Other/icons/clear.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.CancelButton.setIcon(icon2)
|
||||
self.CancelButton.setObjectName("CancelButton")
|
||||
self.horizontalLayout.addWidget(self.CancelButton)
|
||||
self.EditorFrame = QtWidgets.QFrame(MetaEditorDialog)
|
||||
self.EditorFrame.setGeometry(QtCore.QRect(10, 10, 381, 251))
|
||||
self.EditorFrame.setObjectName("EditorFrame")
|
||||
self.formLayoutWidget = QtWidgets.QWidget(self.EditorFrame)
|
||||
self.formLayoutWidget.setGeometry(QtCore.QRect(0, 0, 381, 250))
|
||||
self.formLayoutWidget.setObjectName("formLayoutWidget")
|
||||
self.formLayout = QtWidgets.QFormLayout(self.formLayoutWidget)
|
||||
self.formLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.formLayout.setObjectName("formLayout")
|
||||
self.label = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label.setObjectName("label")
|
||||
self.formLayout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label)
|
||||
self.SeriesLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.SeriesLine.setObjectName("SeriesLine")
|
||||
self.formLayout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.SeriesLine)
|
||||
self.label_2 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_2.setObjectName("label_2")
|
||||
self.formLayout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.label_2)
|
||||
self.VolumeLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.VolumeLine.setObjectName("VolumeLine")
|
||||
self.formLayout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.VolumeLine)
|
||||
self.label_3 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_3.setObjectName("label_3")
|
||||
self.formLayout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.label_3)
|
||||
self.NumberLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.NumberLine.setObjectName("NumberLine")
|
||||
self.formLayout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.NumberLine)
|
||||
self.label_4 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_4.setObjectName("label_4")
|
||||
self.formLayout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.label_4)
|
||||
self.WriterLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.WriterLine.setObjectName("WriterLine")
|
||||
self.formLayout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.WriterLine)
|
||||
self.label_5 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_5.setObjectName("label_5")
|
||||
self.formLayout.setWidget(5, QtWidgets.QFormLayout.LabelRole, self.label_5)
|
||||
self.PencillerLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.PencillerLine.setObjectName("PencillerLine")
|
||||
self.formLayout.setWidget(5, QtWidgets.QFormLayout.FieldRole, self.PencillerLine)
|
||||
self.label_6 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_6.setObjectName("label_6")
|
||||
self.formLayout.setWidget(6, QtWidgets.QFormLayout.LabelRole, self.label_6)
|
||||
self.InkerLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.InkerLine.setObjectName("InkerLine")
|
||||
self.formLayout.setWidget(6, QtWidgets.QFormLayout.FieldRole, self.InkerLine)
|
||||
self.label_7 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_7.setObjectName("label_7")
|
||||
self.formLayout.setWidget(7, QtWidgets.QFormLayout.LabelRole, self.label_7)
|
||||
self.ColoristLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.ColoristLine.setObjectName("ColoristLine")
|
||||
self.formLayout.setWidget(7, QtWidgets.QFormLayout.FieldRole, self.ColoristLine)
|
||||
self.label_8 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_8.setTextFormat(QtCore.Qt.RichText)
|
||||
self.label_8.setOpenExternalLinks(True)
|
||||
self.label_8.setObjectName("label_8")
|
||||
self.formLayout.setWidget(8, QtWidgets.QFormLayout.LabelRole, self.label_8)
|
||||
self.MUidLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.MUidLine.setObjectName("MUidLine")
|
||||
self.formLayout.setWidget(8, QtWidgets.QFormLayout.FieldRole, self.MUidLine)
|
||||
|
||||
self.retranslateUi(MetaEditorDialog)
|
||||
QtCore.QMetaObject.connectSlotsByName(MetaEditorDialog)
|
||||
|
||||
def retranslateUi(self, MetaEditorDialog):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
MetaEditorDialog.setWindowTitle(_translate("MetaEditorDialog", "Metadata editor"))
|
||||
self.OKButton.setText(_translate("MetaEditorDialog", "Save"))
|
||||
self.CancelButton.setText(_translate("MetaEditorDialog", "Cancel"))
|
||||
self.label.setText(_translate("MetaEditorDialog", "Series:"))
|
||||
self.label_2.setText(_translate("MetaEditorDialog", "Volume:"))
|
||||
self.label_3.setText(_translate("MetaEditorDialog", "Number:"))
|
||||
self.label_4.setText(_translate("MetaEditorDialog", "Writer:"))
|
||||
self.label_5.setText(_translate("MetaEditorDialog", "Penciller:"))
|
||||
self.label_6.setText(_translate("MetaEditorDialog", "Inker:"))
|
||||
self.label_7.setText(_translate("MetaEditorDialog", "Colorist:"))
|
||||
self.label_8.setText(_translate("MetaEditorDialog", "<html><head/><body><p><a href=\"https://github.com/ciromattia/kcc/wiki/Manga-Cover-Database-support\"><span style=\" text-decoration: underline; color:#0000ff;\">MUid:</span></a></p></body></html>"))
|
||||
|
||||
from . import KCC_rc
|
||||
1485
kcc/KCC_gui.py
1485
kcc/KCC_gui.py
File diff suppressed because it is too large
Load Diff
4661
kcc/KCC_rc.py
4661
kcc/KCC_rc.py
File diff suppressed because it is too large
Load Diff
225
kcc/KCC_rc_web.py
Normal file
225
kcc/KCC_rc_web.py
Normal file
@@ -0,0 +1,225 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Resources used by content server
|
||||
|
||||
|
||||
class WebContent:
|
||||
def __init__(self):
|
||||
self.favicon = 'data:image/x-icon;base64,AAABAAEAEBAAAAAAAABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAAAAAAAA' \
|
||||
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACalpVpycW64O7q20wAAAAAAAAAAAA' \
|
||||
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVlNNSJiWj//i39b11dHDKAAAAAAAAAAAAAA' \
|
||||
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEpGP0eKh4L/19fU/9DLvo4AAAAAAAAAAAAAAAAAAAA' \
|
||||
'AAAAAAJCOdiqRkIprr6yhfrSxpom4tauRu7mvl8C+s52opJvFvLu3/6nq7v/P087i0c7AVtLPwi4AAAAAAAAAALm1hTK' \
|
||||
'NinTvv723/9rZ0P/g3NH/39rT/+Db1//e3Nr/497b/8Tb3/8s4/z/yObp/9zRy//R0MnnAAAAAAAAAAC4tImElJGF/9v' \
|
||||
'b0/+8udn/bpnl/2ax+v9Rru//OMTi/zXc9v8i5///AOD//1Tf9P/W5ez/2dXS8AAAAAAAAAAAubSOprayqf/p5tv/dI3' \
|
||||
'g/wNh2/8Rd+f/Dn7d/waO2/8AxOj/AKvW/wC+4P8Akdb/oMzt/+fg2e0AAAAAAAAAAKymhr3Bvrf/6Ojj/z5F0P8DH8H' \
|
||||
'/GG/a/yKQ//8RleT/FInf/xuD6f8QfMf/EpL//4Kx5P/m4NftAAAAAAAAAACinIPK0c/F/9jX6f8ZIuz/BinM/xFQ2/8' \
|
||||
'il///IIz4/yKP//8fivf/IIr7/xN+8P9ff7D/49/Y7QAAAAAAAAAAnJaB1OLh1P+6uuf/AQLt/wEH+v8bffv/G3jf/w5' \
|
||||
'Gxv8eifP/CSzL/xp35P8HReH/TVKz/+Ti1+0AAAAAAAAAAJeRgdzw7+D/nJ3f/wAA+f8FGuT/Ci/F/wAD3P8FGtj/CS7' \
|
||||
'd/wAA8P8NQMX/AA7//01Lxv/o6NftAAAAAAAAAACTjYHj+/rm/3t89/8AAO7/AAC8/wAA9P8AAP//AADz/wAA/f8AAP/' \
|
||||
'/AAPi/wAA9v9aWrz/7e3e7QAAAAAAAAAAk42D5/v68f+op9b/NTVx/w8PkP8AAPz/AADU/wAA8v8AAP//AADn/wAA//8' \
|
||||
'AAJb/cnKP//X07e0AAAAAAAAAAJmUi+/5+Pj//f72//f37v/b2/T/t7bw/5GRv/9ycvT/Xl7v/1NTu/9QUPX/VlaJ/8D' \
|
||||
'Avv/z8vDuAAAAAAAAAAB7dGrWqKSe/83Kx//l5OL/9/fx////+P/////////7////+v////v////3/////f/9/fz/8/L' \
|
||||
'x9gAAAAAAAAAAbGVaGmhhVWBsZVqTd3FmtYmDesublo7YrKih4rq3sebFwr3nzMnE5M7MyN7PzMjUxsO/xNzb2IEAAAA' \
|
||||
'A/98AAP/PAAD/xwAA+AcAAMABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAA4AEAAA%3D%3D'
|
||||
self.logo = 'data:image/jpeg;base64,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' \
|
||||
'ruooAoSOUAUAUAUAUAUB/9k%3D'
|
||||
309
kcc/KCC_ui.py
309
kcc/KCC_ui.py
@@ -2,94 +2,79 @@
|
||||
|
||||
# Form implementation generated from reading ui file 'KCC.ui'
|
||||
#
|
||||
# Created: Wed Sep 18 12:12:45 2013
|
||||
# by: PyQt4 UI code generator 4.10.3
|
||||
# Created: Sun Feb 8 09:50:43 2015
|
||||
# by: PyQt5 UI code generator 5.4
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
try:
|
||||
_fromUtf8 = QtCore.QString.fromUtf8
|
||||
except AttributeError:
|
||||
def _fromUtf8(s):
|
||||
return s
|
||||
|
||||
try:
|
||||
_encoding = QtGui.QApplication.UnicodeUTF8
|
||||
def _translate(context, text, disambig):
|
||||
return QtGui.QApplication.translate(context, text, disambig, _encoding)
|
||||
except AttributeError:
|
||||
def _translate(context, text, disambig):
|
||||
return QtGui.QApplication.translate(context, text, disambig)
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
class Ui_KCC(object):
|
||||
def setupUi(self, KCC):
|
||||
KCC.setObjectName(_fromUtf8("KCC"))
|
||||
KCC.resize(420, 380)
|
||||
KCC.setMinimumSize(QtCore.QSize(420, 380))
|
||||
KCC.setMaximumSize(QtCore.QSize(420, 380))
|
||||
KCC.setObjectName("KCC")
|
||||
KCC.resize(420, 397)
|
||||
KCC.setMinimumSize(QtCore.QSize(420, 397))
|
||||
KCC.setMaximumSize(QtCore.QSize(420, 397))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
KCC.setFont(font)
|
||||
KCC.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon = QtGui.QIcon()
|
||||
icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/Icon/icons/comic2ebook.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon.addPixmap(QtGui.QPixmap(":/Icon/icons/comic2ebook.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
KCC.setWindowIcon(icon)
|
||||
KCC.setLocale(QtCore.QLocale(QtCore.QLocale.C, QtCore.QLocale.AnyCountry))
|
||||
self.Form = QtGui.QWidget(KCC)
|
||||
self.Form.setObjectName(_fromUtf8("Form"))
|
||||
self.OptionsAdvanced = QtGui.QFrame(self.Form)
|
||||
self.Form = QtWidgets.QWidget(KCC)
|
||||
self.Form.setObjectName("Form")
|
||||
self.OptionsAdvanced = QtWidgets.QFrame(self.Form)
|
||||
self.OptionsAdvanced.setEnabled(True)
|
||||
self.OptionsAdvanced.setGeometry(QtCore.QRect(10, 254, 421, 61))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
self.OptionsAdvanced.setFont(font)
|
||||
self.OptionsAdvanced.setObjectName(_fromUtf8("OptionsAdvanced"))
|
||||
self.gridLayout = QtGui.QGridLayout(self.OptionsAdvanced)
|
||||
self.OptionsAdvanced.setObjectName("OptionsAdvanced")
|
||||
self.gridLayout = QtWidgets.QGridLayout(self.OptionsAdvanced)
|
||||
self.gridLayout.setContentsMargins(9, -1, -1, -1)
|
||||
self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
|
||||
self.ProcessingBox = QtGui.QCheckBox(self.OptionsAdvanced)
|
||||
self.gridLayout.setObjectName("gridLayout")
|
||||
self.ProcessingBox = QtWidgets.QCheckBox(self.OptionsAdvanced)
|
||||
self.ProcessingBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.ProcessingBox.setObjectName(_fromUtf8("ProcessingBox"))
|
||||
self.ProcessingBox.setObjectName("ProcessingBox")
|
||||
self.gridLayout.addWidget(self.ProcessingBox, 1, 0, 1, 1)
|
||||
self.UpscaleBox = QtGui.QCheckBox(self.OptionsAdvanced)
|
||||
self.UpscaleBox = QtWidgets.QCheckBox(self.OptionsAdvanced)
|
||||
self.UpscaleBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.UpscaleBox.setTristate(True)
|
||||
self.UpscaleBox.setObjectName(_fromUtf8("UpscaleBox"))
|
||||
self.UpscaleBox.setObjectName("UpscaleBox")
|
||||
self.gridLayout.addWidget(self.UpscaleBox, 1, 1, 1, 1)
|
||||
self.WebtoonBox = QtGui.QCheckBox(self.OptionsAdvanced)
|
||||
self.WebtoonBox = QtWidgets.QCheckBox(self.OptionsAdvanced)
|
||||
self.WebtoonBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.WebtoonBox.setObjectName(_fromUtf8("WebtoonBox"))
|
||||
self.WebtoonBox.setObjectName("WebtoonBox")
|
||||
self.gridLayout.addWidget(self.WebtoonBox, 3, 1, 1, 1)
|
||||
self.NoDitheringBox = QtGui.QCheckBox(self.OptionsAdvanced)
|
||||
self.NoDitheringBox = QtWidgets.QCheckBox(self.OptionsAdvanced)
|
||||
self.NoDitheringBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.NoDitheringBox.setObjectName(_fromUtf8("NoDitheringBox"))
|
||||
self.NoDitheringBox.setObjectName("NoDitheringBox")
|
||||
self.gridLayout.addWidget(self.NoDitheringBox, 3, 2, 1, 1)
|
||||
self.BorderBox = QtGui.QCheckBox(self.OptionsAdvanced)
|
||||
self.BorderBox = QtWidgets.QCheckBox(self.OptionsAdvanced)
|
||||
self.BorderBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.BorderBox.setTristate(True)
|
||||
self.BorderBox.setObjectName(_fromUtf8("BorderBox"))
|
||||
self.BorderBox.setObjectName("BorderBox")
|
||||
self.gridLayout.addWidget(self.BorderBox, 3, 0, 1, 1)
|
||||
self.NoRotateBox = QtGui.QCheckBox(self.OptionsAdvanced)
|
||||
self.NoRotateBox = QtWidgets.QCheckBox(self.OptionsAdvanced)
|
||||
self.NoRotateBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.NoRotateBox.setObjectName(_fromUtf8("NoRotateBox"))
|
||||
self.NoRotateBox.setObjectName("NoRotateBox")
|
||||
self.gridLayout.addWidget(self.NoRotateBox, 1, 2, 1, 1)
|
||||
self.DeviceBox = QtGui.QComboBox(self.Form)
|
||||
self.DeviceBox = QtWidgets.QComboBox(self.Form)
|
||||
self.DeviceBox.setGeometry(QtCore.QRect(10, 200, 141, 31))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(8)
|
||||
self.DeviceBox.setFont(font)
|
||||
self.DeviceBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.DeviceBox.setObjectName(_fromUtf8("DeviceBox"))
|
||||
self.FormatBox = QtGui.QComboBox(self.Form)
|
||||
self.DeviceBox.setObjectName("DeviceBox")
|
||||
self.FormatBox = QtWidgets.QComboBox(self.Form)
|
||||
self.FormatBox.setGeometry(QtCore.QRect(260, 200, 151, 31))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(8)
|
||||
self.FormatBox.setFont(font)
|
||||
self.FormatBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.FormatBox.setObjectName(_fromUtf8("FormatBox"))
|
||||
self.ConvertButton = QtGui.QPushButton(self.Form)
|
||||
self.FormatBox.setObjectName("FormatBox")
|
||||
self.ConvertButton = QtWidgets.QPushButton(self.Form)
|
||||
self.ConvertButton.setGeometry(QtCore.QRect(160, 200, 91, 32))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
@@ -98,96 +83,97 @@ class Ui_KCC(object):
|
||||
self.ConvertButton.setFont(font)
|
||||
self.ConvertButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon1 = QtGui.QIcon()
|
||||
icon1.addPixmap(QtGui.QPixmap(_fromUtf8(":/Other/icons/convert.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon1.addPixmap(QtGui.QPixmap(":/Other/icons/convert.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.ConvertButton.setIcon(icon1)
|
||||
self.ConvertButton.setObjectName(_fromUtf8("ConvertButton"))
|
||||
self.DirectoryButton = QtGui.QPushButton(self.Form)
|
||||
self.ConvertButton.setObjectName("ConvertButton")
|
||||
self.DirectoryButton = QtWidgets.QPushButton(self.Form)
|
||||
self.DirectoryButton.setGeometry(QtCore.QRect(10, 160, 141, 32))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(8)
|
||||
self.DirectoryButton.setFont(font)
|
||||
self.DirectoryButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon2 = QtGui.QIcon()
|
||||
icon2.addPixmap(QtGui.QPixmap(_fromUtf8(":/Other/icons/folder_new.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon2.addPixmap(QtGui.QPixmap(":/Other/icons/folder_new.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.DirectoryButton.setIcon(icon2)
|
||||
self.DirectoryButton.setObjectName(_fromUtf8("DirectoryButton"))
|
||||
self.FileButton = QtGui.QPushButton(self.Form)
|
||||
self.DirectoryButton.setObjectName("DirectoryButton")
|
||||
self.FileButton = QtWidgets.QPushButton(self.Form)
|
||||
self.FileButton.setGeometry(QtCore.QRect(260, 160, 151, 32))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(8)
|
||||
self.FileButton.setFont(font)
|
||||
self.FileButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon3 = QtGui.QIcon()
|
||||
icon3.addPixmap(QtGui.QPixmap(_fromUtf8(":/Other/icons/document_new.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon3.addPixmap(QtGui.QPixmap(":/Other/icons/document_new.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.FileButton.setIcon(icon3)
|
||||
self.FileButton.setObjectName(_fromUtf8("FileButton"))
|
||||
self.ClearButton = QtGui.QPushButton(self.Form)
|
||||
self.FileButton.setObjectName("FileButton")
|
||||
self.ClearButton = QtWidgets.QPushButton(self.Form)
|
||||
self.ClearButton.setGeometry(QtCore.QRect(160, 160, 91, 32))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(8)
|
||||
self.ClearButton.setFont(font)
|
||||
self.ClearButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon4 = QtGui.QIcon()
|
||||
icon4.addPixmap(QtGui.QPixmap(_fromUtf8(":/Other/icons/clear.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon4.addPixmap(QtGui.QPixmap(":/Other/icons/clear.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.ClearButton.setIcon(icon4)
|
||||
self.ClearButton.setObjectName(_fromUtf8("ClearButton"))
|
||||
self.OptionsBasic = QtGui.QFrame(self.Form)
|
||||
self.ClearButton.setObjectName("ClearButton")
|
||||
self.OptionsBasic = QtWidgets.QFrame(self.Form)
|
||||
self.OptionsBasic.setGeometry(QtCore.QRect(10, 230, 421, 41))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
self.OptionsBasic.setFont(font)
|
||||
self.OptionsBasic.setObjectName(_fromUtf8("OptionsBasic"))
|
||||
self.MangaBox = QtGui.QCheckBox(self.OptionsBasic)
|
||||
self.OptionsBasic.setObjectName("OptionsBasic")
|
||||
self.MangaBox = QtWidgets.QCheckBox(self.OptionsBasic)
|
||||
self.MangaBox.setGeometry(QtCore.QRect(9, 10, 130, 18))
|
||||
self.MangaBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.MangaBox.setObjectName(_fromUtf8("MangaBox"))
|
||||
self.QualityBox = QtGui.QCheckBox(self.OptionsBasic)
|
||||
self.MangaBox.setObjectName("MangaBox")
|
||||
self.QualityBox = QtWidgets.QCheckBox(self.OptionsBasic)
|
||||
self.QualityBox.setGeometry(QtCore.QRect(282, 10, 130, 18))
|
||||
self.QualityBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.QualityBox.setTristate(True)
|
||||
self.QualityBox.setObjectName(_fromUtf8("QualityBox"))
|
||||
self.RotateBox = QtGui.QCheckBox(self.OptionsBasic)
|
||||
self.QualityBox.setObjectName("QualityBox")
|
||||
self.RotateBox = QtWidgets.QCheckBox(self.OptionsBasic)
|
||||
self.RotateBox.setGeometry(QtCore.QRect(145, 10, 130, 18))
|
||||
self.RotateBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.RotateBox.setObjectName(_fromUtf8("RotateBox"))
|
||||
self.JobList = QtGui.QListWidget(self.Form)
|
||||
self.RotateBox.setObjectName("RotateBox")
|
||||
self.JobList = QtWidgets.QListWidget(self.Form)
|
||||
self.JobList.setGeometry(QtCore.QRect(10, 50, 401, 101))
|
||||
self.JobList.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.JobList.setStyleSheet("QListWidget#JobList {background:#ffffff;background-image:url(:/Other/icons/list_background.png);background-position:center center;background-repeat:no-repeat;}QScrollBar:vertical{border:1px solid #999;background:#FFF;width:5px;margin:0}QScrollBar::handle:vertical{background:DarkGray;min-height:0}QScrollBar::add-line:vertical{height:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:vertical{height:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}QScrollBar:horizontal{border:1px solid #999;background:#FFF;height:5px;margin:0}QScrollBar::handle:horizontal{background:DarkGray;min-width:0}QScrollBar::add-line:horizontal{width:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:horizontal{width:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}")
|
||||
self.JobList.setProperty("showDropIndicator", False)
|
||||
self.JobList.setSelectionMode(QtGui.QAbstractItemView.NoSelection)
|
||||
self.JobList.setObjectName(_fromUtf8("JobList"))
|
||||
self.BasicModeButton = QtGui.QPushButton(self.Form)
|
||||
self.BasicModeButton.setGeometry(QtCore.QRect(10, 10, 195, 32))
|
||||
self.JobList.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
|
||||
self.JobList.setObjectName("JobList")
|
||||
self.BasicModeButton = QtWidgets.QPushButton(self.Form)
|
||||
self.BasicModeButton.setGeometry(QtCore.QRect(10, 10, 141, 32))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
self.BasicModeButton.setFont(font)
|
||||
self.BasicModeButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.BasicModeButton.setObjectName(_fromUtf8("BasicModeButton"))
|
||||
self.AdvModeButton = QtGui.QPushButton(self.Form)
|
||||
self.AdvModeButton.setGeometry(QtCore.QRect(217, 10, 195, 32))
|
||||
self.BasicModeButton.setObjectName("BasicModeButton")
|
||||
self.AdvModeButton = QtWidgets.QPushButton(self.Form)
|
||||
self.AdvModeButton.setGeometry(QtCore.QRect(261, 10, 151, 32))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
self.AdvModeButton.setFont(font)
|
||||
self.AdvModeButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.AdvModeButton.setObjectName(_fromUtf8("AdvModeButton"))
|
||||
self.OptionsAdvancedGamma = QtGui.QFrame(self.Form)
|
||||
self.AdvModeButton.setObjectName("AdvModeButton")
|
||||
self.OptionsAdvancedGamma = QtWidgets.QFrame(self.Form)
|
||||
self.OptionsAdvancedGamma.setEnabled(True)
|
||||
self.OptionsAdvancedGamma.setGeometry(QtCore.QRect(10, 305, 401, 41))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
self.OptionsAdvancedGamma.setFont(font)
|
||||
self.OptionsAdvancedGamma.setObjectName(_fromUtf8("OptionsAdvancedGamma"))
|
||||
self.GammaLabel = QtGui.QLabel(self.OptionsAdvancedGamma)
|
||||
self.OptionsAdvancedGamma.setObjectName("OptionsAdvancedGamma")
|
||||
self.GammaLabel = QtWidgets.QLabel(self.OptionsAdvancedGamma)
|
||||
self.GammaLabel.setGeometry(QtCore.QRect(15, 0, 100, 40))
|
||||
self.GammaLabel.setObjectName(_fromUtf8("GammaLabel"))
|
||||
self.GammaSlider = QtGui.QSlider(self.OptionsAdvancedGamma)
|
||||
self.GammaLabel.setObjectName("GammaLabel")
|
||||
self.GammaSlider = QtWidgets.QSlider(self.OptionsAdvancedGamma)
|
||||
self.GammaSlider.setGeometry(QtCore.QRect(110, 10, 270, 22))
|
||||
self.GammaSlider.setFocusPolicy(QtCore.Qt.ClickFocus)
|
||||
self.GammaSlider.setMaximum(500)
|
||||
self.GammaSlider.setSingleStep(5)
|
||||
self.GammaSlider.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.GammaSlider.setObjectName(_fromUtf8("GammaSlider"))
|
||||
self.ProgressBar = QtGui.QProgressBar(self.Form)
|
||||
self.GammaSlider.setObjectName("GammaSlider")
|
||||
self.ProgressBar = QtWidgets.QProgressBar(self.Form)
|
||||
self.ProgressBar.setGeometry(QtCore.QRect(10, 10, 401, 31))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
@@ -196,28 +182,28 @@ class Ui_KCC(object):
|
||||
self.ProgressBar.setFont(font)
|
||||
self.ProgressBar.setProperty("value", 0)
|
||||
self.ProgressBar.setAlignment(QtCore.Qt.AlignJustify|QtCore.Qt.AlignVCenter)
|
||||
self.ProgressBar.setFormat(_fromUtf8(""))
|
||||
self.ProgressBar.setObjectName(_fromUtf8("ProgressBar"))
|
||||
self.OptionsExpert = QtGui.QFrame(self.Form)
|
||||
self.ProgressBar.setFormat("")
|
||||
self.ProgressBar.setObjectName("ProgressBar")
|
||||
self.OptionsExpert = QtWidgets.QFrame(self.Form)
|
||||
self.OptionsExpert.setGeometry(QtCore.QRect(10, 337, 421, 41))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
self.OptionsExpert.setFont(font)
|
||||
self.OptionsExpert.setObjectName(_fromUtf8("OptionsExpert"))
|
||||
self.ColorBox = QtGui.QCheckBox(self.OptionsExpert)
|
||||
self.OptionsExpert.setObjectName("OptionsExpert")
|
||||
self.ColorBox = QtWidgets.QCheckBox(self.OptionsExpert)
|
||||
self.ColorBox.setGeometry(QtCore.QRect(9, 11, 130, 18))
|
||||
self.ColorBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.ColorBox.setObjectName(_fromUtf8("ColorBox"))
|
||||
self.OptionsExpertInternal = QtGui.QFrame(self.OptionsExpert)
|
||||
self.ColorBox.setObjectName("ColorBox")
|
||||
self.OptionsExpertInternal = QtWidgets.QFrame(self.OptionsExpert)
|
||||
self.OptionsExpertInternal.setGeometry(QtCore.QRect(100, 0, 295, 40))
|
||||
self.OptionsExpertInternal.setObjectName(_fromUtf8("OptionsExpertInternal"))
|
||||
self.gridLayout_2 = QtGui.QGridLayout(self.OptionsExpertInternal)
|
||||
self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2"))
|
||||
self.wLabel = QtGui.QLabel(self.OptionsExpertInternal)
|
||||
self.wLabel.setObjectName(_fromUtf8("wLabel"))
|
||||
self.OptionsExpertInternal.setObjectName("OptionsExpertInternal")
|
||||
self.gridLayout_2 = QtWidgets.QGridLayout(self.OptionsExpertInternal)
|
||||
self.gridLayout_2.setObjectName("gridLayout_2")
|
||||
self.wLabel = QtWidgets.QLabel(self.OptionsExpertInternal)
|
||||
self.wLabel.setObjectName("wLabel")
|
||||
self.gridLayout_2.addWidget(self.wLabel, 0, 0, 1, 1)
|
||||
self.customWidth = QtGui.QLineEdit(self.OptionsExpertInternal)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
|
||||
self.customWidth = QtWidgets.QLineEdit(self.OptionsExpertInternal)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.customWidth.sizePolicy().hasHeightForWidth())
|
||||
@@ -226,13 +212,13 @@ class Ui_KCC(object):
|
||||
self.customWidth.setFocusPolicy(QtCore.Qt.ClickFocus)
|
||||
self.customWidth.setAcceptDrops(False)
|
||||
self.customWidth.setMaxLength(4)
|
||||
self.customWidth.setObjectName(_fromUtf8("customWidth"))
|
||||
self.customWidth.setObjectName("customWidth")
|
||||
self.gridLayout_2.addWidget(self.customWidth, 0, 1, 1, 1)
|
||||
self.hLabel = QtGui.QLabel(self.OptionsExpertInternal)
|
||||
self.hLabel.setObjectName(_fromUtf8("hLabel"))
|
||||
self.hLabel = QtWidgets.QLabel(self.OptionsExpertInternal)
|
||||
self.hLabel.setObjectName("hLabel")
|
||||
self.gridLayout_2.addWidget(self.hLabel, 0, 2, 1, 1)
|
||||
self.customHeight = QtGui.QLineEdit(self.OptionsExpertInternal)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
|
||||
self.customHeight = QtWidgets.QLineEdit(self.OptionsExpertInternal)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.customHeight.sizePolicy().hasHeightForWidth())
|
||||
@@ -241,19 +227,37 @@ class Ui_KCC(object):
|
||||
self.customHeight.setFocusPolicy(QtCore.Qt.ClickFocus)
|
||||
self.customHeight.setAcceptDrops(False)
|
||||
self.customHeight.setMaxLength(4)
|
||||
self.customHeight.setObjectName(_fromUtf8("customHeight"))
|
||||
self.customHeight.setObjectName("customHeight")
|
||||
self.gridLayout_2.addWidget(self.customHeight, 0, 3, 1, 1)
|
||||
self.EditorButton = QtWidgets.QPushButton(self.Form)
|
||||
self.EditorButton.setGeometry(QtCore.QRect(160, 10, 91, 32))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
self.EditorButton.setFont(font)
|
||||
self.EditorButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon5 = QtGui.QIcon()
|
||||
icon5.addPixmap(QtGui.QPixmap(":/Other/icons/editor.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.EditorButton.setIcon(icon5)
|
||||
self.EditorButton.setObjectName("EditorButton")
|
||||
KCC.setCentralWidget(self.Form)
|
||||
self.ActionBasic = QtGui.QAction(KCC)
|
||||
self.statusBar = QtWidgets.QStatusBar(KCC)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily("MS Shell Dlg 2")
|
||||
font.setPointSize(8)
|
||||
self.statusBar.setFont(font)
|
||||
self.statusBar.setSizeGripEnabled(False)
|
||||
self.statusBar.setObjectName("statusBar")
|
||||
KCC.setStatusBar(self.statusBar)
|
||||
self.ActionBasic = QtWidgets.QAction(KCC)
|
||||
self.ActionBasic.setCheckable(True)
|
||||
self.ActionBasic.setChecked(False)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
self.ActionBasic.setFont(font)
|
||||
self.ActionBasic.setObjectName(_fromUtf8("ActionBasic"))
|
||||
self.ActionAdvanced = QtGui.QAction(KCC)
|
||||
self.ActionBasic.setObjectName("ActionBasic")
|
||||
self.ActionAdvanced = QtWidgets.QAction(KCC)
|
||||
self.ActionAdvanced.setCheckable(True)
|
||||
self.ActionAdvanced.setObjectName(_fromUtf8("ActionAdvanced"))
|
||||
self.ActionAdvanced.setObjectName("ActionAdvanced")
|
||||
|
||||
self.retranslateUi(KCC)
|
||||
QtCore.QMetaObject.connectSlotsByName(KCC)
|
||||
@@ -262,53 +266,50 @@ class Ui_KCC(object):
|
||||
KCC.setTabOrder(self.ConvertButton, self.ClearButton)
|
||||
|
||||
def retranslateUi(self, KCC):
|
||||
KCC.setWindowTitle(_translate("KCC", "Kindle Comic Converter", None))
|
||||
self.ProcessingBox.setToolTip(_translate("KCC", "Disable image optimizations.", None))
|
||||
self.ProcessingBox.setText(_translate("KCC", "No optimisation", None))
|
||||
self.UpscaleBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - Nothing<br/></span>Images smaller than device resolution will not be resized.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Indeterminate - Stretching<br/></span>Images smaller than device resolution will be resized. Aspect ratio will be not preserved.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - Upscaling<br/></span>Images smaller than device resolution will be resized. Aspect ratio will be preserved.</p></body></html>", None))
|
||||
self.UpscaleBox.setText(_translate("KCC", "Stretch/Upscale", None))
|
||||
self.WebtoonBox.setToolTip(_translate("KCC", "<html><head/><body><p>Enable auto-splitting of webtoons like <span style=\" font-style:italic;\">Tower of God</span> or <span style=\" font-style:italic;\">Noblesse</span>.<br/>Pages with a low width, high height and vertical panel flow.</p></body></html>", None))
|
||||
self.WebtoonBox.setText(_translate("KCC", "Webtoon mode", None))
|
||||
self.NoDitheringBox.setToolTip(_translate("KCC", "<html><head/><body><p>Create PNG files instead JPEG.</p></body></html>", None))
|
||||
self.NoDitheringBox.setText(_translate("KCC", "PNG output", None))
|
||||
self.BorderBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - Autodetection<br/></span>Color of margins fill will be detected automatically.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Indeterminate - White<br/></span>Margins will be filled with white color.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - Black<br/></span>Margins will be filled with black color.</p></body></html>", None))
|
||||
self.BorderBox.setText(_translate("KCC", "W/B margins", None))
|
||||
self.NoRotateBox.setToolTip(_translate("KCC", "<html><head/><body><p>Disable splitting and rotation.</p></body></html>", None))
|
||||
self.NoRotateBox.setText(_translate("KCC", "No split/rotate", None))
|
||||
self.DeviceBox.setToolTip(_translate("KCC", "Target device.", None))
|
||||
self.FormatBox.setToolTip(_translate("KCC", "Output format.", None))
|
||||
self.ConvertButton.setText(_translate("KCC", "Convert", None))
|
||||
self.DirectoryButton.setText(_translate("KCC", "Add directory", None))
|
||||
self.FileButton.setText(_translate("KCC", "Add file", None))
|
||||
self.ClearButton.setText(_translate("KCC", "Clear list", None))
|
||||
self.MangaBox.setToolTip(_translate("KCC", "Enable right-to-left reading.", None))
|
||||
self.MangaBox.setText(_translate("KCC", "Manga mode", None))
|
||||
self.QualityBox.setToolTip(_translate("KCC", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
|
||||
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
|
||||
"p, li { white-space: pre-wrap; }\n"
|
||||
"</style></head><body style=\" font-family:\'MS Shell Dlg 2\'; font-size:8pt; font-weight:400; font-style:normal;\">\n"
|
||||
"<p style=\" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - Normal quality mode<br /></span><span style=\" font-style:italic;\">Use it when Panel View support is not needed.</span><span style=\" font-weight:600; text-decoration: underline;\"><br /></span>- Maximum quality when zoom is not enabled.<br />- Poor quality when zoom is enabled.<br />- Lowest file size.</p>\n"
|
||||
"<p style=\" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-weight:600; text-decoration: underline;\">Indeterminate - High quality mode<br /></span><span style=\" font-style:italic;\">Not zoomed image </span><span style=\" font-weight:600; font-style:italic;\">might </span><span style=\" font-style:italic;\">be </span><span style=\" font-style:italic;\">a little blurry.</span><span style=\" font-weight:600; text-decoration: underline;\"><br /></span>- Medium/High quality when zoom is not enabled.<br />- Maximum quality when zoom is enabled.</p>\n"
|
||||
"<p style=\" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-weight:600; text-decoration: underline;\">Checked - Ultra quality mode<br /></span><span style=\" font-style:italic;\">Maximum possible quality.</span><span style=\" font-weight:600; text-decoration: underline;\"><br /></span>- Maximum quality when zoom is not enabled.<br />- Maximum quality when zoom is enabled.<br />- Very high file size.</p></body></html>", None))
|
||||
self.QualityBox.setText(_translate("KCC", "High/Ultra quality", None))
|
||||
self.RotateBox.setToolTip(_translate("KCC", "<html><head/><body><p>Disable page spliting.<br/>They will be rotated instead.</p></body></html>", None))
|
||||
self.RotateBox.setText(_translate("KCC", "Horizontal mode", None))
|
||||
self.BasicModeButton.setText(_translate("KCC", "Basic", None))
|
||||
self.AdvModeButton.setText(_translate("KCC", "Advanced", None))
|
||||
self.GammaLabel.setToolTip(_translate("KCC", "When converting color images setting this option to 1.0 MIGHT improve readability.", None))
|
||||
self.GammaLabel.setText(_translate("KCC", "Gamma: Auto", None))
|
||||
self.GammaSlider.setToolTip(_translate("KCC", "<html><head/><body><p>When converting color images setting this option to 1.0 <span style=\" font-weight:600;\">might</span> improve readability.</p></body></html>", None))
|
||||
self.ColorBox.setToolTip(_translate("KCC", "Do not convert images to grayscale.", None))
|
||||
self.ColorBox.setText(_translate("KCC", "Color mode", None))
|
||||
self.wLabel.setToolTip(_translate("KCC", "Resolution of target device.", None))
|
||||
self.wLabel.setText(_translate("KCC", "Custom width: ", None))
|
||||
self.customWidth.setToolTip(_translate("KCC", "Resolution of target device.", None))
|
||||
self.customWidth.setInputMask(_translate("KCC", "0000; ", None))
|
||||
self.hLabel.setToolTip(_translate("KCC", "Resolution of target device.", None))
|
||||
self.hLabel.setText(_translate("KCC", "Custom height: ", None))
|
||||
self.customHeight.setToolTip(_translate("KCC", "Resolution of target device.", None))
|
||||
self.customHeight.setInputMask(_translate("KCC", "0000; ", None))
|
||||
self.ActionBasic.setText(_translate("KCC", "Basic", None))
|
||||
self.ActionAdvanced.setText(_translate("KCC", "Advanced", None))
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
KCC.setWindowTitle(_translate("KCC", "Kindle Comic Converter"))
|
||||
self.ProcessingBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Disable image optimizations.<br/><span style=\" font-weight:600;\">Input images must be already resized.</span></p></body></html>"))
|
||||
self.ProcessingBox.setText(_translate("KCC", "No optimisation"))
|
||||
self.UpscaleBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - Nothing<br/></span>Images smaller than device resolution will not be resized.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Indeterminate - Stretching<br/></span>Images smaller than device resolution will be resized. Aspect ratio will be not preserved.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - Upscaling<br/></span>Images smaller than device resolution will be resized. Aspect ratio will be preserved.</p></body></html>"))
|
||||
self.UpscaleBox.setText(_translate("KCC", "Stretch/Upscale"))
|
||||
self.WebtoonBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Enable special parsing mode for WebToons.</p></body></html>"))
|
||||
self.WebtoonBox.setText(_translate("KCC", "Webtoon mode"))
|
||||
self.NoDitheringBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Create PNG files instead JPEG.<br/>Quality increase is not noticeable on most of devices.<br/>Output files <span style=\" font-weight:600;\">might</span> be smaller.<br/><span style=\" font-weight:600;\">MOBI conversion will be much slower.</span></p></body></html>"))
|
||||
self.NoDitheringBox.setText(_translate("KCC", "PNG output"))
|
||||
self.BorderBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - Autodetection<br/></span>Color of margins fill will be detected automatically.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Indeterminate - White<br/></span>Margins will be filled with white color.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - Black<br/></span>Margins will be filled with black color.</p></body></html>"))
|
||||
self.BorderBox.setText(_translate("KCC", "W/B margins"))
|
||||
self.NoRotateBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Disable page splitting and rotation.</p></body></html>"))
|
||||
self.NoRotateBox.setText(_translate("KCC", "No split/rotate"))
|
||||
self.DeviceBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Target device.</p></body></html>"))
|
||||
self.FormatBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Output format.</p></body></html>"))
|
||||
self.ConvertButton.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Shift+Click to select the output directory.</p></body></html>"))
|
||||
self.ConvertButton.setText(_translate("KCC", "Convert"))
|
||||
self.DirectoryButton.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Add directory containing JPG, PNG or GIF files to queue.<br/><span style=\" font-weight:600;\">CBR, CBZ and CB7 files inside will not be processed!</span></p></body></html>"))
|
||||
self.DirectoryButton.setText(_translate("KCC", "Add directory"))
|
||||
self.FileButton.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Add CBR, CBZ, CB7 or PDF file to queue.</p></body></html>"))
|
||||
self.FileButton.setText(_translate("KCC", "Add file"))
|
||||
self.ClearButton.setText(_translate("KCC", "Clear list"))
|
||||
self.MangaBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Enable right-to-left reading.</p></body></html>"))
|
||||
self.MangaBox.setText(_translate("KCC", "Manga mode"))
|
||||
self.QualityBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Quality of Panel View/zoom. Highly impact size of output file.<br/><span style=\" font-weight:600;\">This option control only quality of magnification!</span></p></body></html>"))
|
||||
self.QualityBox.setText(_translate("KCC", "High/Ultra quality"))
|
||||
self.RotateBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Disable splitting of two-page spreads.<br/>They will be rotated instead.</p></body></html>"))
|
||||
self.RotateBox.setText(_translate("KCC", "Horizontal mode"))
|
||||
self.BasicModeButton.setText(_translate("KCC", "Basic"))
|
||||
self.AdvModeButton.setText(_translate("KCC", "Advanced"))
|
||||
self.GammaLabel.setText(_translate("KCC", "Gamma: Auto"))
|
||||
self.ColorBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Don\'t convert images to grayscale.</p></body></html>"))
|
||||
self.ColorBox.setText(_translate("KCC", "Color mode"))
|
||||
self.wLabel.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Resolution of target device.</p></body></html>"))
|
||||
self.wLabel.setText(_translate("KCC", "Custom width: "))
|
||||
self.customWidth.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Resolution of target device.</p></body></html>"))
|
||||
self.customWidth.setInputMask(_translate("KCC", "0000"))
|
||||
self.hLabel.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Resolution of target device.</p></body></html>"))
|
||||
self.hLabel.setText(_translate("KCC", "Custom height: "))
|
||||
self.customHeight.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Resolution of target device.</p></body></html>"))
|
||||
self.customHeight.setInputMask(_translate("KCC", "0000"))
|
||||
self.EditorButton.setText(_translate("KCC", "Editor"))
|
||||
self.ActionBasic.setText(_translate("KCC", "Basic"))
|
||||
self.ActionAdvanced.setText(_translate("KCC", "Advanced"))
|
||||
|
||||
import KCC_rc
|
||||
from . import KCC_rc
|
||||
|
||||
@@ -1,328 +1,333 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'KCC-Linux.ui'
|
||||
# Form implementation generated from reading ui file 'gui/KCC-Linux.ui'
|
||||
#
|
||||
# Created: Fri Sep 20 10:25:30 2013
|
||||
# by: PyQt4 UI code generator 4.10
|
||||
# Created: Sun Feb 8 03:10:09 2015
|
||||
# by: PyQt5 UI code generator 5.2.1
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
try:
|
||||
_fromUtf8 = QtCore.QString.fromUtf8
|
||||
except AttributeError:
|
||||
def _fromUtf8(s):
|
||||
return s
|
||||
|
||||
try:
|
||||
_encoding = QtGui.QApplication.UnicodeUTF8
|
||||
def _translate(context, text, disambig):
|
||||
return QtGui.QApplication.translate(context, text, disambig, _encoding)
|
||||
except AttributeError:
|
||||
def _translate(context, text, disambig):
|
||||
return QtGui.QApplication.translate(context, text, disambig)
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
class Ui_KCC(object):
|
||||
def setupUi(self, KCC):
|
||||
KCC.setObjectName(_fromUtf8("KCC"))
|
||||
KCC.resize(420, 380)
|
||||
KCC.setMinimumSize(QtCore.QSize(420, 380))
|
||||
KCC.setMaximumSize(QtCore.QSize(420, 380))
|
||||
KCC.setObjectName("KCC")
|
||||
KCC.resize(420, 397)
|
||||
KCC.setMinimumSize(QtCore.QSize(420, 397))
|
||||
KCC.setMaximumSize(QtCore.QSize(420, 397))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
KCC.setFont(font)
|
||||
KCC.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon = QtGui.QIcon()
|
||||
icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/Icon/icons/comic2ebook.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon.addPixmap(QtGui.QPixmap(":/Icon/icons/comic2ebook.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
KCC.setWindowIcon(icon)
|
||||
KCC.setLocale(QtCore.QLocale(QtCore.QLocale.C, QtCore.QLocale.AnyCountry))
|
||||
self.Form = QtGui.QWidget(KCC)
|
||||
self.Form.setObjectName(_fromUtf8("Form"))
|
||||
self.OptionsAdvanced = QtGui.QFrame(self.Form)
|
||||
self.Form = QtWidgets.QWidget(KCC)
|
||||
self.Form.setObjectName("Form")
|
||||
self.OptionsAdvanced = QtWidgets.QFrame(self.Form)
|
||||
self.OptionsAdvanced.setEnabled(True)
|
||||
self.OptionsAdvanced.setGeometry(QtCore.QRect(1, 254, 421, 61))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("DejaVu Sans"))
|
||||
font.setFamily("DejaVu Sans")
|
||||
font.setPointSize(9)
|
||||
self.OptionsAdvanced.setFont(font)
|
||||
self.OptionsAdvanced.setObjectName(_fromUtf8("OptionsAdvanced"))
|
||||
self.gridLayout = QtGui.QGridLayout(self.OptionsAdvanced)
|
||||
self.OptionsAdvanced.setObjectName("OptionsAdvanced")
|
||||
self.gridLayout = QtWidgets.QGridLayout(self.OptionsAdvanced)
|
||||
self.gridLayout.setContentsMargins(9, -1, -1, -1)
|
||||
self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
|
||||
self.ProcessingBox = QtGui.QCheckBox(self.OptionsAdvanced)
|
||||
self.gridLayout.setObjectName("gridLayout")
|
||||
self.ProcessingBox = QtWidgets.QCheckBox(self.OptionsAdvanced)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("DejaVu Sans"))
|
||||
font.setFamily("DejaVu Sans")
|
||||
self.ProcessingBox.setFont(font)
|
||||
self.ProcessingBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.ProcessingBox.setObjectName(_fromUtf8("ProcessingBox"))
|
||||
self.ProcessingBox.setObjectName("ProcessingBox")
|
||||
self.gridLayout.addWidget(self.ProcessingBox, 1, 0, 1, 1)
|
||||
self.UpscaleBox = QtGui.QCheckBox(self.OptionsAdvanced)
|
||||
self.UpscaleBox = QtWidgets.QCheckBox(self.OptionsAdvanced)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("DejaVu Sans"))
|
||||
font.setFamily("DejaVu Sans")
|
||||
self.UpscaleBox.setFont(font)
|
||||
self.UpscaleBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.UpscaleBox.setTristate(True)
|
||||
self.UpscaleBox.setObjectName(_fromUtf8("UpscaleBox"))
|
||||
self.UpscaleBox.setObjectName("UpscaleBox")
|
||||
self.gridLayout.addWidget(self.UpscaleBox, 1, 1, 1, 1)
|
||||
self.WebtoonBox = QtGui.QCheckBox(self.OptionsAdvanced)
|
||||
self.WebtoonBox = QtWidgets.QCheckBox(self.OptionsAdvanced)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("DejaVu Sans"))
|
||||
font.setFamily("DejaVu Sans")
|
||||
self.WebtoonBox.setFont(font)
|
||||
self.WebtoonBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.WebtoonBox.setObjectName(_fromUtf8("WebtoonBox"))
|
||||
self.WebtoonBox.setObjectName("WebtoonBox")
|
||||
self.gridLayout.addWidget(self.WebtoonBox, 3, 1, 1, 1)
|
||||
self.NoDitheringBox = QtGui.QCheckBox(self.OptionsAdvanced)
|
||||
self.NoDitheringBox = QtWidgets.QCheckBox(self.OptionsAdvanced)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("DejaVu Sans"))
|
||||
font.setFamily("DejaVu Sans")
|
||||
self.NoDitheringBox.setFont(font)
|
||||
self.NoDitheringBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.NoDitheringBox.setObjectName(_fromUtf8("NoDitheringBox"))
|
||||
self.NoDitheringBox.setObjectName("NoDitheringBox")
|
||||
self.gridLayout.addWidget(self.NoDitheringBox, 3, 2, 1, 1)
|
||||
self.BorderBox = QtGui.QCheckBox(self.OptionsAdvanced)
|
||||
self.BorderBox = QtWidgets.QCheckBox(self.OptionsAdvanced)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("DejaVu Sans"))
|
||||
font.setFamily("DejaVu Sans")
|
||||
self.BorderBox.setFont(font)
|
||||
self.BorderBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.BorderBox.setTristate(True)
|
||||
self.BorderBox.setObjectName(_fromUtf8("BorderBox"))
|
||||
self.BorderBox.setObjectName("BorderBox")
|
||||
self.gridLayout.addWidget(self.BorderBox, 3, 0, 1, 1)
|
||||
self.NoRotateBox = QtGui.QCheckBox(self.OptionsAdvanced)
|
||||
self.NoRotateBox = QtWidgets.QCheckBox(self.OptionsAdvanced)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("DejaVu Sans"))
|
||||
font.setFamily("DejaVu Sans")
|
||||
self.NoRotateBox.setFont(font)
|
||||
self.NoRotateBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.NoRotateBox.setObjectName(_fromUtf8("NoRotateBox"))
|
||||
self.NoRotateBox.setObjectName("NoRotateBox")
|
||||
self.gridLayout.addWidget(self.NoRotateBox, 1, 2, 1, 1)
|
||||
self.DeviceBox = QtGui.QComboBox(self.Form)
|
||||
self.DeviceBox = QtWidgets.QComboBox(self.Form)
|
||||
self.DeviceBox.setGeometry(QtCore.QRect(10, 200, 141, 31))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("DejaVu Sans"))
|
||||
font.setFamily("DejaVu Sans")
|
||||
font.setPointSize(8)
|
||||
self.DeviceBox.setFont(font)
|
||||
self.DeviceBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.DeviceBox.setObjectName(_fromUtf8("DeviceBox"))
|
||||
self.FormatBox = QtGui.QComboBox(self.Form)
|
||||
self.DeviceBox.setObjectName("DeviceBox")
|
||||
self.FormatBox = QtWidgets.QComboBox(self.Form)
|
||||
self.FormatBox.setGeometry(QtCore.QRect(260, 200, 151, 31))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("DejaVu Sans"))
|
||||
font.setFamily("DejaVu Sans")
|
||||
font.setPointSize(8)
|
||||
self.FormatBox.setFont(font)
|
||||
self.FormatBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.FormatBox.setObjectName(_fromUtf8("FormatBox"))
|
||||
self.ConvertButton = QtGui.QPushButton(self.Form)
|
||||
self.FormatBox.setObjectName("FormatBox")
|
||||
self.ConvertButton = QtWidgets.QPushButton(self.Form)
|
||||
self.ConvertButton.setGeometry(QtCore.QRect(160, 200, 91, 32))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("DejaVu Sans"))
|
||||
font.setFamily("DejaVu Sans")
|
||||
font.setPointSize(9)
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.ConvertButton.setFont(font)
|
||||
self.ConvertButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon1 = QtGui.QIcon()
|
||||
icon1.addPixmap(QtGui.QPixmap(_fromUtf8(":/Other/icons/convert.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon1.addPixmap(QtGui.QPixmap(":/Other/icons/convert.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.ConvertButton.setIcon(icon1)
|
||||
self.ConvertButton.setObjectName(_fromUtf8("ConvertButton"))
|
||||
self.DirectoryButton = QtGui.QPushButton(self.Form)
|
||||
self.ConvertButton.setObjectName("ConvertButton")
|
||||
self.DirectoryButton = QtWidgets.QPushButton(self.Form)
|
||||
self.DirectoryButton.setGeometry(QtCore.QRect(10, 160, 141, 32))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("DejaVu Sans"))
|
||||
font.setFamily("DejaVu Sans")
|
||||
font.setPointSize(8)
|
||||
self.DirectoryButton.setFont(font)
|
||||
self.DirectoryButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon2 = QtGui.QIcon()
|
||||
icon2.addPixmap(QtGui.QPixmap(_fromUtf8(":/Other/icons/folder_new.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon2.addPixmap(QtGui.QPixmap(":/Other/icons/folder_new.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.DirectoryButton.setIcon(icon2)
|
||||
self.DirectoryButton.setObjectName(_fromUtf8("DirectoryButton"))
|
||||
self.FileButton = QtGui.QPushButton(self.Form)
|
||||
self.DirectoryButton.setObjectName("DirectoryButton")
|
||||
self.FileButton = QtWidgets.QPushButton(self.Form)
|
||||
self.FileButton.setGeometry(QtCore.QRect(260, 160, 151, 32))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("DejaVu Sans"))
|
||||
font.setFamily("DejaVu Sans")
|
||||
font.setPointSize(8)
|
||||
self.FileButton.setFont(font)
|
||||
self.FileButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon3 = QtGui.QIcon()
|
||||
icon3.addPixmap(QtGui.QPixmap(_fromUtf8(":/Other/icons/document_new.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon3.addPixmap(QtGui.QPixmap(":/Other/icons/document_new.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.FileButton.setIcon(icon3)
|
||||
self.FileButton.setObjectName(_fromUtf8("FileButton"))
|
||||
self.ClearButton = QtGui.QPushButton(self.Form)
|
||||
self.FileButton.setObjectName("FileButton")
|
||||
self.ClearButton = QtWidgets.QPushButton(self.Form)
|
||||
self.ClearButton.setGeometry(QtCore.QRect(160, 160, 91, 32))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("DejaVu Sans"))
|
||||
font.setFamily("DejaVu Sans")
|
||||
font.setPointSize(8)
|
||||
self.ClearButton.setFont(font)
|
||||
self.ClearButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon4 = QtGui.QIcon()
|
||||
icon4.addPixmap(QtGui.QPixmap(_fromUtf8(":/Other/icons/clear.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon4.addPixmap(QtGui.QPixmap(":/Other/icons/clear.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.ClearButton.setIcon(icon4)
|
||||
self.ClearButton.setObjectName(_fromUtf8("ClearButton"))
|
||||
self.OptionsBasic = QtGui.QFrame(self.Form)
|
||||
self.ClearButton.setObjectName("ClearButton")
|
||||
self.OptionsBasic = QtWidgets.QFrame(self.Form)
|
||||
self.OptionsBasic.setGeometry(QtCore.QRect(1, 230, 421, 41))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("DejaVu Sans"))
|
||||
font.setFamily("DejaVu Sans")
|
||||
font.setPointSize(9)
|
||||
self.OptionsBasic.setFont(font)
|
||||
self.OptionsBasic.setObjectName(_fromUtf8("OptionsBasic"))
|
||||
self.MangaBox = QtGui.QCheckBox(self.OptionsBasic)
|
||||
self.OptionsBasic.setObjectName("OptionsBasic")
|
||||
self.MangaBox = QtWidgets.QCheckBox(self.OptionsBasic)
|
||||
self.MangaBox.setGeometry(QtCore.QRect(9, 10, 130, 18))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("DejaVu Sans"))
|
||||
font.setFamily("DejaVu Sans")
|
||||
self.MangaBox.setFont(font)
|
||||
self.MangaBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.MangaBox.setObjectName(_fromUtf8("MangaBox"))
|
||||
self.QualityBox = QtGui.QCheckBox(self.OptionsBasic)
|
||||
self.MangaBox.setObjectName("MangaBox")
|
||||
self.QualityBox = QtWidgets.QCheckBox(self.OptionsBasic)
|
||||
self.QualityBox.setGeometry(QtCore.QRect(282, 10, 135, 18))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("DejaVu Sans"))
|
||||
font.setFamily("DejaVu Sans")
|
||||
self.QualityBox.setFont(font)
|
||||
self.QualityBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.QualityBox.setTristate(True)
|
||||
self.QualityBox.setObjectName(_fromUtf8("QualityBox"))
|
||||
self.RotateBox = QtGui.QCheckBox(self.OptionsBasic)
|
||||
self.QualityBox.setObjectName("QualityBox")
|
||||
self.RotateBox = QtWidgets.QCheckBox(self.OptionsBasic)
|
||||
self.RotateBox.setGeometry(QtCore.QRect(145, 10, 130, 18))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("DejaVu Sans"))
|
||||
font.setFamily("DejaVu Sans")
|
||||
self.RotateBox.setFont(font)
|
||||
self.RotateBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.RotateBox.setObjectName(_fromUtf8("RotateBox"))
|
||||
self.JobList = QtGui.QListWidget(self.Form)
|
||||
self.RotateBox.setObjectName("RotateBox")
|
||||
self.JobList = QtWidgets.QListWidget(self.Form)
|
||||
self.JobList.setGeometry(QtCore.QRect(10, 50, 401, 101))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("DejaVu Sans"))
|
||||
font.setFamily("DejaVu Sans")
|
||||
font.setPointSize(8)
|
||||
font.setItalic(False)
|
||||
self.JobList.setFont(font)
|
||||
self.JobList.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.JobList.setStyleSheet("QListWidget#JobList {background:#ffffff;background-image:url(:/Other/icons/list_background.png);background-position:center center;background-repeat:no-repeat;}QScrollBar:vertical{border:1px solid #999;background:#FFF;width:5px;margin:0}QScrollBar::handle:vertical{background:DarkGray;min-height:0}QScrollBar::add-line:vertical{height:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:vertical{height:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}QScrollBar:horizontal{border:1px solid #999;background:#FFF;height:5px;margin:0}QScrollBar::handle:horizontal{background:DarkGray;min-width:0}QScrollBar::add-line:horizontal{width:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:horizontal{width:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}")
|
||||
self.JobList.setProperty("showDropIndicator", False)
|
||||
self.JobList.setSelectionMode(QtGui.QAbstractItemView.NoSelection)
|
||||
self.JobList.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
|
||||
self.JobList.setIconSize(QtCore.QSize(18, 18))
|
||||
self.JobList.setObjectName(_fromUtf8("JobList"))
|
||||
self.BasicModeButton = QtGui.QPushButton(self.Form)
|
||||
self.BasicModeButton.setGeometry(QtCore.QRect(10, 10, 195, 32))
|
||||
self.JobList.setObjectName("JobList")
|
||||
self.BasicModeButton = QtWidgets.QPushButton(self.Form)
|
||||
self.BasicModeButton.setGeometry(QtCore.QRect(10, 10, 141, 32))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("DejaVu Sans"))
|
||||
font.setFamily("DejaVu Sans")
|
||||
font.setPointSize(9)
|
||||
self.BasicModeButton.setFont(font)
|
||||
self.BasicModeButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.BasicModeButton.setObjectName(_fromUtf8("BasicModeButton"))
|
||||
self.AdvModeButton = QtGui.QPushButton(self.Form)
|
||||
self.AdvModeButton.setGeometry(QtCore.QRect(217, 10, 195, 32))
|
||||
self.BasicModeButton.setObjectName("BasicModeButton")
|
||||
self.AdvModeButton = QtWidgets.QPushButton(self.Form)
|
||||
self.AdvModeButton.setGeometry(QtCore.QRect(260, 10, 151, 32))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("DejaVu Sans"))
|
||||
font.setFamily("DejaVu Sans")
|
||||
font.setPointSize(9)
|
||||
self.AdvModeButton.setFont(font)
|
||||
self.AdvModeButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.AdvModeButton.setObjectName(_fromUtf8("AdvModeButton"))
|
||||
self.OptionsAdvancedGamma = QtGui.QFrame(self.Form)
|
||||
self.AdvModeButton.setObjectName("AdvModeButton")
|
||||
self.OptionsAdvancedGamma = QtWidgets.QFrame(self.Form)
|
||||
self.OptionsAdvancedGamma.setEnabled(True)
|
||||
self.OptionsAdvancedGamma.setGeometry(QtCore.QRect(10, 305, 401, 41))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("DejaVu Sans"))
|
||||
font.setFamily("DejaVu Sans")
|
||||
font.setPointSize(9)
|
||||
self.OptionsAdvancedGamma.setFont(font)
|
||||
self.OptionsAdvancedGamma.setObjectName(_fromUtf8("OptionsAdvancedGamma"))
|
||||
self.GammaLabel = QtGui.QLabel(self.OptionsAdvancedGamma)
|
||||
self.OptionsAdvancedGamma.setObjectName("OptionsAdvancedGamma")
|
||||
self.GammaLabel = QtWidgets.QLabel(self.OptionsAdvancedGamma)
|
||||
self.GammaLabel.setGeometry(QtCore.QRect(15, 0, 100, 40))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("DejaVu Sans"))
|
||||
font.setFamily("DejaVu Sans")
|
||||
self.GammaLabel.setFont(font)
|
||||
self.GammaLabel.setObjectName(_fromUtf8("GammaLabel"))
|
||||
self.GammaSlider = QtGui.QSlider(self.OptionsAdvancedGamma)
|
||||
self.GammaLabel.setObjectName("GammaLabel")
|
||||
self.GammaSlider = QtWidgets.QSlider(self.OptionsAdvancedGamma)
|
||||
self.GammaSlider.setGeometry(QtCore.QRect(110, 10, 275, 22))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("DejaVu Sans"))
|
||||
font.setFamily("DejaVu Sans")
|
||||
self.GammaSlider.setFont(font)
|
||||
self.GammaSlider.setFocusPolicy(QtCore.Qt.ClickFocus)
|
||||
self.GammaSlider.setMaximum(500)
|
||||
self.GammaSlider.setSingleStep(5)
|
||||
self.GammaSlider.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.GammaSlider.setObjectName(_fromUtf8("GammaSlider"))
|
||||
self.ProgressBar = QtGui.QProgressBar(self.Form)
|
||||
self.GammaSlider.setObjectName("GammaSlider")
|
||||
self.ProgressBar = QtWidgets.QProgressBar(self.Form)
|
||||
self.ProgressBar.setGeometry(QtCore.QRect(10, 10, 401, 31))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("DejaVu Sans"))
|
||||
font.setFamily("DejaVu Sans")
|
||||
font.setPointSize(10)
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.ProgressBar.setFont(font)
|
||||
self.ProgressBar.setProperty("value", 0)
|
||||
self.ProgressBar.setAlignment(QtCore.Qt.AlignJustify|QtCore.Qt.AlignVCenter)
|
||||
self.ProgressBar.setFormat(_fromUtf8(""))
|
||||
self.ProgressBar.setObjectName(_fromUtf8("ProgressBar"))
|
||||
self.OptionsExpert = QtGui.QFrame(self.Form)
|
||||
self.ProgressBar.setFormat("")
|
||||
self.ProgressBar.setObjectName("ProgressBar")
|
||||
self.OptionsExpert = QtWidgets.QFrame(self.Form)
|
||||
self.OptionsExpert.setGeometry(QtCore.QRect(1, 337, 421, 41))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("DejaVu Sans"))
|
||||
font.setFamily("DejaVu Sans")
|
||||
font.setPointSize(9)
|
||||
self.OptionsExpert.setFont(font)
|
||||
self.OptionsExpert.setObjectName(_fromUtf8("OptionsExpert"))
|
||||
self.ColorBox = QtGui.QCheckBox(self.OptionsExpert)
|
||||
self.OptionsExpert.setObjectName("OptionsExpert")
|
||||
self.ColorBox = QtWidgets.QCheckBox(self.OptionsExpert)
|
||||
self.ColorBox.setGeometry(QtCore.QRect(9, 11, 130, 18))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("DejaVu Sans"))
|
||||
font.setFamily("DejaVu Sans")
|
||||
self.ColorBox.setFont(font)
|
||||
self.ColorBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.ColorBox.setObjectName(_fromUtf8("ColorBox"))
|
||||
self.OptionsExpertInternal = QtGui.QFrame(self.OptionsExpert)
|
||||
self.ColorBox.setObjectName("ColorBox")
|
||||
self.OptionsExpertInternal = QtWidgets.QFrame(self.OptionsExpert)
|
||||
self.OptionsExpertInternal.setGeometry(QtCore.QRect(105, 0, 295, 40))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("DejaVu Sans"))
|
||||
font.setFamily("DejaVu Sans")
|
||||
self.OptionsExpertInternal.setFont(font)
|
||||
self.OptionsExpertInternal.setObjectName(_fromUtf8("OptionsExpertInternal"))
|
||||
self.gridLayout_2 = QtGui.QGridLayout(self.OptionsExpertInternal)
|
||||
self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2"))
|
||||
self.wLabel = QtGui.QLabel(self.OptionsExpertInternal)
|
||||
self.OptionsExpertInternal.setObjectName("OptionsExpertInternal")
|
||||
self.gridLayout_2 = QtWidgets.QGridLayout(self.OptionsExpertInternal)
|
||||
self.gridLayout_2.setObjectName("gridLayout_2")
|
||||
self.wLabel = QtWidgets.QLabel(self.OptionsExpertInternal)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("DejaVu Sans"))
|
||||
font.setFamily("DejaVu Sans")
|
||||
self.wLabel.setFont(font)
|
||||
self.wLabel.setObjectName(_fromUtf8("wLabel"))
|
||||
self.wLabel.setObjectName("wLabel")
|
||||
self.gridLayout_2.addWidget(self.wLabel, 0, 0, 1, 1)
|
||||
self.customWidth = QtGui.QLineEdit(self.OptionsExpertInternal)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
|
||||
self.customWidth = QtWidgets.QLineEdit(self.OptionsExpertInternal)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.customWidth.sizePolicy().hasHeightForWidth())
|
||||
self.customWidth.setSizePolicy(sizePolicy)
|
||||
self.customWidth.setMaximumSize(QtCore.QSize(40, 16777215))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("DejaVu Sans"))
|
||||
font.setFamily("DejaVu Sans")
|
||||
self.customWidth.setFont(font)
|
||||
self.customWidth.setFocusPolicy(QtCore.Qt.ClickFocus)
|
||||
self.customWidth.setAcceptDrops(False)
|
||||
self.customWidth.setMaxLength(4)
|
||||
self.customWidth.setObjectName(_fromUtf8("customWidth"))
|
||||
self.customWidth.setObjectName("customWidth")
|
||||
self.gridLayout_2.addWidget(self.customWidth, 0, 1, 1, 1)
|
||||
self.hLabel = QtGui.QLabel(self.OptionsExpertInternal)
|
||||
self.hLabel = QtWidgets.QLabel(self.OptionsExpertInternal)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("DejaVu Sans"))
|
||||
font.setFamily("DejaVu Sans")
|
||||
self.hLabel.setFont(font)
|
||||
self.hLabel.setObjectName(_fromUtf8("hLabel"))
|
||||
self.hLabel.setObjectName("hLabel")
|
||||
self.gridLayout_2.addWidget(self.hLabel, 0, 2, 1, 1)
|
||||
self.customHeight = QtGui.QLineEdit(self.OptionsExpertInternal)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
|
||||
self.customHeight = QtWidgets.QLineEdit(self.OptionsExpertInternal)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.customHeight.sizePolicy().hasHeightForWidth())
|
||||
self.customHeight.setSizePolicy(sizePolicy)
|
||||
self.customHeight.setMaximumSize(QtCore.QSize(40, 16777215))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("DejaVu Sans"))
|
||||
font.setFamily("DejaVu Sans")
|
||||
self.customHeight.setFont(font)
|
||||
self.customHeight.setFocusPolicy(QtCore.Qt.ClickFocus)
|
||||
self.customHeight.setAcceptDrops(False)
|
||||
self.customHeight.setMaxLength(4)
|
||||
self.customHeight.setObjectName(_fromUtf8("customHeight"))
|
||||
self.customHeight.setObjectName("customHeight")
|
||||
self.gridLayout_2.addWidget(self.customHeight, 0, 3, 1, 1)
|
||||
self.EditorButton = QtWidgets.QPushButton(self.Form)
|
||||
self.EditorButton.setGeometry(QtCore.QRect(160, 10, 91, 32))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily("DejaVu Sans")
|
||||
font.setPointSize(9)
|
||||
self.EditorButton.setFont(font)
|
||||
self.EditorButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon5 = QtGui.QIcon()
|
||||
icon5.addPixmap(QtGui.QPixmap(":/Other/icons/editor.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.EditorButton.setIcon(icon5)
|
||||
self.EditorButton.setObjectName("EditorButton")
|
||||
KCC.setCentralWidget(self.Form)
|
||||
self.ActionBasic = QtGui.QAction(KCC)
|
||||
self.statusBar = QtWidgets.QStatusBar(KCC)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily("DejaVu Sans")
|
||||
font.setPointSize(8)
|
||||
self.statusBar.setFont(font)
|
||||
self.statusBar.setSizeGripEnabled(False)
|
||||
self.statusBar.setObjectName("statusBar")
|
||||
KCC.setStatusBar(self.statusBar)
|
||||
self.ActionBasic = QtWidgets.QAction(KCC)
|
||||
self.ActionBasic.setCheckable(True)
|
||||
self.ActionBasic.setChecked(False)
|
||||
font = QtGui.QFont()
|
||||
self.ActionBasic.setFont(font)
|
||||
self.ActionBasic.setObjectName(_fromUtf8("ActionBasic"))
|
||||
self.ActionAdvanced = QtGui.QAction(KCC)
|
||||
self.ActionBasic.setObjectName("ActionBasic")
|
||||
self.ActionAdvanced = QtWidgets.QAction(KCC)
|
||||
self.ActionAdvanced.setCheckable(True)
|
||||
self.ActionAdvanced.setObjectName(_fromUtf8("ActionAdvanced"))
|
||||
self.ActionAdvanced.setObjectName("ActionAdvanced")
|
||||
|
||||
self.retranslateUi(KCC)
|
||||
QtCore.QMetaObject.connectSlotsByName(KCC)
|
||||
@@ -331,53 +336,50 @@ class Ui_KCC(object):
|
||||
KCC.setTabOrder(self.ConvertButton, self.ClearButton)
|
||||
|
||||
def retranslateUi(self, KCC):
|
||||
KCC.setWindowTitle(_translate("KCC", "Kindle Comic Converter", None))
|
||||
self.ProcessingBox.setToolTip(_translate("KCC", "Disable image optimizations.", None))
|
||||
self.ProcessingBox.setText(_translate("KCC", "No optimisation", None))
|
||||
self.UpscaleBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - Nothing<br/></span>Images smaller than device resolution will not be resized.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Indeterminate - Stretching<br/></span>Images smaller than device resolution will be resized. Aspect ratio will be not preserved.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - Upscaling<br/></span>Images smaller than device resolution will be resized. Aspect ratio will be preserved.</p></body></html>", None))
|
||||
self.UpscaleBox.setText(_translate("KCC", "Stretch/Upscale", None))
|
||||
self.WebtoonBox.setToolTip(_translate("KCC", "<html><head/><body><p>Enable auto-splitting of webtoons like <span style=\" font-style:italic;\">Tower of God</span> or <span style=\" font-style:italic;\">Noblesse</span>.<br/>Pages with a low width, high height and vertical panel flow.</p></body></html>", None))
|
||||
self.WebtoonBox.setText(_translate("KCC", "Webtoon mode", None))
|
||||
self.NoDitheringBox.setToolTip(_translate("KCC", "<html><head/><body><p>Create PNG files instead JPEG.</p></body></html>", None))
|
||||
self.NoDitheringBox.setText(_translate("KCC", "PNG output", None))
|
||||
self.BorderBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - Autodetection<br/></span>Color of margins fill will be detected automatically.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Indeterminate - White<br/></span>Margins will be filled with white color.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - Black<br/></span>Margins will be filled with black color.</p></body></html>", None))
|
||||
self.BorderBox.setText(_translate("KCC", "W/B margins", None))
|
||||
self.NoRotateBox.setToolTip(_translate("KCC", "<html><head/><body><p>Disable splitting and rotation.</p></body></html>", None))
|
||||
self.NoRotateBox.setText(_translate("KCC", "No split/rotate", None))
|
||||
self.DeviceBox.setToolTip(_translate("KCC", "Target device.", None))
|
||||
self.FormatBox.setToolTip(_translate("KCC", "Output format.", None))
|
||||
self.ConvertButton.setText(_translate("KCC", "Convert", None))
|
||||
self.DirectoryButton.setText(_translate("KCC", "Add directory", None))
|
||||
self.FileButton.setText(_translate("KCC", "Add file", None))
|
||||
self.ClearButton.setText(_translate("KCC", "Clear list", None))
|
||||
self.MangaBox.setToolTip(_translate("KCC", "Enable right-to-left reading.", None))
|
||||
self.MangaBox.setText(_translate("KCC", "Manga mode", None))
|
||||
self.QualityBox.setToolTip(_translate("KCC", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
|
||||
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
|
||||
"p, li { white-space: pre-wrap; }\n"
|
||||
"</style></head><body style=\" font-family:\'Sans\'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
|
||||
"<p style=\" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-weight:600; text-decoration: underline;\">Unchecked - Normal quality mode<br /></span><span style=\" font-family:\'MS Shell Dlg 2\'; font-style:italic;\">Use it when Panel View support is not needed.</span><span style=\" font-family:\'MS Shell Dlg 2\'; font-weight:600; text-decoration: underline;\"><br /></span><span style=\" font-family:\'MS Shell Dlg 2\';\">- Maximum quality when zoom is not enabled.<br />- Poor quality when zoom is enabled.<br />- Lowest file size.</span></p>\n"
|
||||
"<p style=\" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-weight:600; text-decoration: underline;\">Indeterminate - High quality mode<br /></span><span style=\" font-family:\'MS Shell Dlg 2\'; font-style:italic;\">Not zoomed image </span><span style=\" font-family:\'MS Shell Dlg 2\'; font-weight:600; font-style:italic;\">might </span><span style=\" font-family:\'MS Shell Dlg 2\'; font-style:italic;\">be a little blurry.</span><span style=\" font-family:\'MS Shell Dlg 2\'; font-weight:600; text-decoration: underline;\"><br /></span><span style=\" font-family:\'MS Shell Dlg 2\';\">- Medium/High quality when zoom is not enabled.<br />- Maximum quality when zoom is enabled.</span></p>\n"
|
||||
"<p style=\" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-weight:600; text-decoration: underline;\">Checked - Ultra quality mode<br /></span><span style=\" font-family:\'MS Shell Dlg 2\'; font-style:italic;\">Maximum possible quality.</span><span style=\" font-family:\'MS Shell Dlg 2\'; font-weight:600; text-decoration: underline;\"><br /></span><span style=\" font-family:\'MS Shell Dlg 2\';\">- Maximum quality when zoom is not enabled.<br />- Maximum quality when zoom is enabled.<br />- Very high file size.</span></p></body></html>", None))
|
||||
self.QualityBox.setText(_translate("KCC", "High/Ultra quality", None))
|
||||
self.RotateBox.setToolTip(_translate("KCC", "<html><head/><body><p>Disable page spliting.<br/>They will be rotated instead.</p></body></html>", None))
|
||||
self.RotateBox.setText(_translate("KCC", "Horizontal mode", None))
|
||||
self.BasicModeButton.setText(_translate("KCC", "Basic", None))
|
||||
self.AdvModeButton.setText(_translate("KCC", "Advanced", None))
|
||||
self.GammaLabel.setToolTip(_translate("KCC", "<html><head/><body><p>When converting color images setting this option to 1.0 <span style=\" font-weight:600;\">might</span> improve readability.</p></body></html>", None))
|
||||
self.GammaLabel.setText(_translate("KCC", "Gamma: Auto", None))
|
||||
self.GammaSlider.setToolTip(_translate("KCC", "<html><head/><body><p>When converting color images setting this option to 1.0 <span style=\" font-weight:600;\">might</span> improve readability.</p></body></html>", None))
|
||||
self.ColorBox.setToolTip(_translate("KCC", "Do not convert images to grayscale.", None))
|
||||
self.ColorBox.setText(_translate("KCC", "Color mode", None))
|
||||
self.wLabel.setToolTip(_translate("KCC", "Resolution of target device.", None))
|
||||
self.wLabel.setText(_translate("KCC", "Custom width: ", None))
|
||||
self.customWidth.setToolTip(_translate("KCC", "Resolution of target device.", None))
|
||||
self.customWidth.setInputMask(_translate("KCC", "0000; ", None))
|
||||
self.hLabel.setToolTip(_translate("KCC", "Resolution of target device.", None))
|
||||
self.hLabel.setText(_translate("KCC", "Custom height: ", None))
|
||||
self.customHeight.setToolTip(_translate("KCC", "Resolution of target device.", None))
|
||||
self.customHeight.setInputMask(_translate("KCC", "0000; ", None))
|
||||
self.ActionBasic.setText(_translate("KCC", "Basic", None))
|
||||
self.ActionAdvanced.setText(_translate("KCC", "Advanced", None))
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
KCC.setWindowTitle(_translate("KCC", "Kindle Comic Converter"))
|
||||
self.ProcessingBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Disable image optimizations.<br/><span style=\" font-weight:600;\">Input images must be already resized.</span></p></body></html>"))
|
||||
self.ProcessingBox.setText(_translate("KCC", "No optimisation"))
|
||||
self.UpscaleBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - Nothing<br/></span>Images smaller than device resolution will not be resized.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Indeterminate - Stretching<br/></span>Images smaller than device resolution will be resized. Aspect ratio will be not preserved.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - Upscaling<br/></span>Images smaller than device resolution will be resized. Aspect ratio will be preserved.</p></body></html>"))
|
||||
self.UpscaleBox.setText(_translate("KCC", "Stretch/Upscale"))
|
||||
self.WebtoonBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Enable special parsing mode for WebToons.</p></body></html>"))
|
||||
self.WebtoonBox.setText(_translate("KCC", "Webtoon mode"))
|
||||
self.NoDitheringBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Create PNG files instead JPEG.<br/>Quality increase is not noticeable on most of devices.<br/>Output files <span style=\" font-weight:600;\">might</span> be smaller.<br/><span style=\" font-weight:600;\">MOBI conversion will be much slower.</span></p></body></html>"))
|
||||
self.NoDitheringBox.setText(_translate("KCC", "PNG output"))
|
||||
self.BorderBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - Autodetection<br/></span>Color of margins fill will be detected automatically.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Indeterminate - White<br/></span>Margins will be filled with white color.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - Black<br/></span>Margins will be filled with black color.</p></body></html>"))
|
||||
self.BorderBox.setText(_translate("KCC", "W/B margins"))
|
||||
self.NoRotateBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Disable page splitting and rotation.</p></body></html>"))
|
||||
self.NoRotateBox.setText(_translate("KCC", "No split/rotate"))
|
||||
self.DeviceBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Target device.</p></body></html>"))
|
||||
self.FormatBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Output format.</p></body></html>"))
|
||||
self.ConvertButton.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Shift+Click to select the output directory.</p></body></html>"))
|
||||
self.ConvertButton.setText(_translate("KCC", "Convert"))
|
||||
self.DirectoryButton.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Add directory containing JPG, PNG or GIF files to queue.<br/><span style=\" font-weight:600;\">CBR, CBZ and CB7 files inside will not be processed!</span></p></body></html>"))
|
||||
self.DirectoryButton.setText(_translate("KCC", "Add directory"))
|
||||
self.FileButton.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Add CBR, CBZ, CB7 or PDF file to queue.</p></body></html>"))
|
||||
self.FileButton.setText(_translate("KCC", "Add file"))
|
||||
self.ClearButton.setText(_translate("KCC", "Clear list"))
|
||||
self.MangaBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Enable right-to-left reading.</p></body></html>"))
|
||||
self.MangaBox.setText(_translate("KCC", "Manga mode"))
|
||||
self.QualityBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Quality of Panel View/zoom. Highly impact size of output file.<br/><span style=\" font-weight:600;\">This option control only quality of magnification!</span></p></body></html>"))
|
||||
self.QualityBox.setText(_translate("KCC", "High/Ultra quality"))
|
||||
self.RotateBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Disable splitting of two-page spreads.<br/>They will be rotated instead.</p></body></html>"))
|
||||
self.RotateBox.setText(_translate("KCC", "Horizontal mode"))
|
||||
self.BasicModeButton.setText(_translate("KCC", "Basic"))
|
||||
self.AdvModeButton.setText(_translate("KCC", "Advanced"))
|
||||
self.GammaLabel.setText(_translate("KCC", "Gamma: Auto"))
|
||||
self.ColorBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Don\'t convert images to grayscale.</p></body></html>"))
|
||||
self.ColorBox.setText(_translate("KCC", "Color mode"))
|
||||
self.wLabel.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Resolution of target device.</p></body></html>"))
|
||||
self.wLabel.setText(_translate("KCC", "Custom width: "))
|
||||
self.customWidth.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Resolution of target device.</p></body></html>"))
|
||||
self.customWidth.setInputMask(_translate("KCC", "0000"))
|
||||
self.hLabel.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Resolution of target device.</p></body></html>"))
|
||||
self.hLabel.setText(_translate("KCC", "Custom height: "))
|
||||
self.customHeight.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Resolution of target device.</p></body></html>"))
|
||||
self.customHeight.setInputMask(_translate("KCC", "0000"))
|
||||
self.EditorButton.setText(_translate("KCC", "Editor"))
|
||||
self.ActionBasic.setText(_translate("KCC", "Basic"))
|
||||
self.ActionAdvanced.setText(_translate("KCC", "Advanced"))
|
||||
|
||||
import KCC_rc
|
||||
from . import KCC_rc
|
||||
|
||||
@@ -1,352 +1,356 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'KCC-OSX.ui'
|
||||
# Form implementation generated from reading ui file '/Users/pawelj/Documents/KCC/gui/KCC-OSX.ui'
|
||||
#
|
||||
# Created: Fri Sep 20 10:57:31 2013
|
||||
# by: PyQt4 UI code generator 4.10.2
|
||||
# Created: Sun Feb 8 12:37:33 2015
|
||||
# by: PyQt5 UI code generator 5.4
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
try:
|
||||
_fromUtf8 = QtCore.QString.fromUtf8
|
||||
except AttributeError:
|
||||
def _fromUtf8(s):
|
||||
return s
|
||||
|
||||
try:
|
||||
_encoding = QtGui.QApplication.UnicodeUTF8
|
||||
def _translate(context, text, disambig):
|
||||
return QtGui.QApplication.translate(context, text, disambig, _encoding)
|
||||
except AttributeError:
|
||||
def _translate(context, text, disambig):
|
||||
return QtGui.QApplication.translate(context, text, disambig)
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
class Ui_KCC(object):
|
||||
def setupUi(self, KCC):
|
||||
KCC.setObjectName(_fromUtf8("KCC"))
|
||||
KCC.resize(420, 380)
|
||||
KCC.setMinimumSize(QtCore.QSize(420, 380))
|
||||
KCC.setMaximumSize(QtCore.QSize(420, 380))
|
||||
KCC.setObjectName("KCC")
|
||||
KCC.resize(420, 397)
|
||||
KCC.setMinimumSize(QtCore.QSize(420, 397))
|
||||
KCC.setMaximumSize(QtCore.QSize(420, 397))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
KCC.setFont(font)
|
||||
KCC.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon = QtGui.QIcon()
|
||||
icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/Icon/icons/comic2ebook.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon.addPixmap(QtGui.QPixmap(":/Icon/icons/comic2ebook.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
KCC.setWindowIcon(icon)
|
||||
KCC.setLocale(QtCore.QLocale(QtCore.QLocale.C, QtCore.QLocale.AnyCountry))
|
||||
self.Form = QtGui.QWidget(KCC)
|
||||
self.Form.setObjectName(_fromUtf8("Form"))
|
||||
self.OptionsAdvanced = QtGui.QFrame(self.Form)
|
||||
self.Form = QtWidgets.QWidget(KCC)
|
||||
self.Form.setObjectName("Form")
|
||||
self.OptionsAdvanced = QtWidgets.QFrame(self.Form)
|
||||
self.OptionsAdvanced.setEnabled(True)
|
||||
self.OptionsAdvanced.setGeometry(QtCore.QRect(4, 253, 421, 61))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("Lucida Grande"))
|
||||
font.setFamily("Lucida Grande")
|
||||
font.setPointSize(9)
|
||||
self.OptionsAdvanced.setFont(font)
|
||||
self.OptionsAdvanced.setObjectName(_fromUtf8("OptionsAdvanced"))
|
||||
self.gridLayout = QtGui.QGridLayout(self.OptionsAdvanced)
|
||||
self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
|
||||
self.ProcessingBox = QtGui.QCheckBox(self.OptionsAdvanced)
|
||||
self.OptionsAdvanced.setObjectName("OptionsAdvanced")
|
||||
self.gridLayout = QtWidgets.QGridLayout(self.OptionsAdvanced)
|
||||
self.gridLayout.setObjectName("gridLayout")
|
||||
self.ProcessingBox = QtWidgets.QCheckBox(self.OptionsAdvanced)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("Lucida Grande"))
|
||||
font.setFamily("Lucida Grande")
|
||||
font.setPointSize(12)
|
||||
self.ProcessingBox.setFont(font)
|
||||
self.ProcessingBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.ProcessingBox.setObjectName(_fromUtf8("ProcessingBox"))
|
||||
self.ProcessingBox.setObjectName("ProcessingBox")
|
||||
self.gridLayout.addWidget(self.ProcessingBox, 1, 0, 1, 1)
|
||||
self.UpscaleBox = QtGui.QCheckBox(self.OptionsAdvanced)
|
||||
self.UpscaleBox = QtWidgets.QCheckBox(self.OptionsAdvanced)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("Lucida Grande"))
|
||||
font.setFamily("Lucida Grande")
|
||||
font.setPointSize(12)
|
||||
self.UpscaleBox.setFont(font)
|
||||
self.UpscaleBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.UpscaleBox.setTristate(True)
|
||||
self.UpscaleBox.setObjectName(_fromUtf8("UpscaleBox"))
|
||||
self.UpscaleBox.setObjectName("UpscaleBox")
|
||||
self.gridLayout.addWidget(self.UpscaleBox, 1, 1, 1, 1)
|
||||
self.WebtoonBox = QtGui.QCheckBox(self.OptionsAdvanced)
|
||||
self.WebtoonBox = QtWidgets.QCheckBox(self.OptionsAdvanced)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("Lucida Grande"))
|
||||
font.setFamily("Lucida Grande")
|
||||
font.setPointSize(12)
|
||||
self.WebtoonBox.setFont(font)
|
||||
self.WebtoonBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.WebtoonBox.setObjectName(_fromUtf8("WebtoonBox"))
|
||||
self.WebtoonBox.setObjectName("WebtoonBox")
|
||||
self.gridLayout.addWidget(self.WebtoonBox, 3, 1, 1, 1)
|
||||
self.NoDitheringBox = QtGui.QCheckBox(self.OptionsAdvanced)
|
||||
self.NoDitheringBox = QtWidgets.QCheckBox(self.OptionsAdvanced)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("Lucida Grande"))
|
||||
font.setFamily("Lucida Grande")
|
||||
font.setPointSize(12)
|
||||
self.NoDitheringBox.setFont(font)
|
||||
self.NoDitheringBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.NoDitheringBox.setObjectName(_fromUtf8("NoDitheringBox"))
|
||||
self.NoDitheringBox.setObjectName("NoDitheringBox")
|
||||
self.gridLayout.addWidget(self.NoDitheringBox, 3, 2, 1, 1)
|
||||
self.BorderBox = QtGui.QCheckBox(self.OptionsAdvanced)
|
||||
self.BorderBox = QtWidgets.QCheckBox(self.OptionsAdvanced)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("Lucida Grande"))
|
||||
font.setFamily("Lucida Grande")
|
||||
font.setPointSize(12)
|
||||
self.BorderBox.setFont(font)
|
||||
self.BorderBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.BorderBox.setTristate(True)
|
||||
self.BorderBox.setObjectName(_fromUtf8("BorderBox"))
|
||||
self.BorderBox.setObjectName("BorderBox")
|
||||
self.gridLayout.addWidget(self.BorderBox, 3, 0, 1, 1)
|
||||
self.NoRotateBox = QtGui.QCheckBox(self.OptionsAdvanced)
|
||||
self.NoRotateBox = QtWidgets.QCheckBox(self.OptionsAdvanced)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("Lucida Grande"))
|
||||
font.setFamily("Lucida Grande")
|
||||
font.setPointSize(12)
|
||||
self.NoRotateBox.setFont(font)
|
||||
self.NoRotateBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.NoRotateBox.setObjectName(_fromUtf8("NoRotateBox"))
|
||||
self.NoRotateBox.setObjectName("NoRotateBox")
|
||||
self.gridLayout.addWidget(self.NoRotateBox, 1, 2, 1, 1)
|
||||
self.DeviceBox = QtGui.QComboBox(self.Form)
|
||||
self.DeviceBox.setGeometry(QtCore.QRect(8, 200, 151, 34))
|
||||
self.DeviceBox = QtWidgets.QComboBox(self.Form)
|
||||
self.DeviceBox.setGeometry(QtCore.QRect(8, 201, 151, 34))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("Lucida Grande"))
|
||||
font.setFamily("Lucida Grande")
|
||||
font.setPointSize(11)
|
||||
self.DeviceBox.setFont(font)
|
||||
self.DeviceBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.DeviceBox.setObjectName(_fromUtf8("DeviceBox"))
|
||||
self.FormatBox = QtGui.QComboBox(self.Form)
|
||||
self.FormatBox.setGeometry(QtCore.QRect(262, 200, 152, 34))
|
||||
self.DeviceBox.setObjectName("DeviceBox")
|
||||
self.FormatBox = QtWidgets.QComboBox(self.Form)
|
||||
self.FormatBox.setGeometry(QtCore.QRect(262, 201, 152, 34))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("Lucida Grande"))
|
||||
font.setFamily("Lucida Grande")
|
||||
font.setPointSize(11)
|
||||
self.FormatBox.setFont(font)
|
||||
self.FormatBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.FormatBox.setObjectName(_fromUtf8("FormatBox"))
|
||||
self.ConvertButton = QtGui.QPushButton(self.Form)
|
||||
self.FormatBox.setObjectName("FormatBox")
|
||||
self.ConvertButton = QtWidgets.QPushButton(self.Form)
|
||||
self.ConvertButton.setGeometry(QtCore.QRect(160, 200, 101, 41))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("Lucida Grande"))
|
||||
font.setFamily("Lucida Grande")
|
||||
font.setPointSize(11)
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.ConvertButton.setFont(font)
|
||||
self.ConvertButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon1 = QtGui.QIcon()
|
||||
icon1.addPixmap(QtGui.QPixmap(_fromUtf8(":/Other/icons/convert.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon1.addPixmap(QtGui.QPixmap(":/Other/icons/convert.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.ConvertButton.setIcon(icon1)
|
||||
self.ConvertButton.setObjectName(_fromUtf8("ConvertButton"))
|
||||
self.DirectoryButton = QtGui.QPushButton(self.Form)
|
||||
self.ConvertButton.setObjectName("ConvertButton")
|
||||
self.DirectoryButton = QtWidgets.QPushButton(self.Form)
|
||||
self.DirectoryButton.setGeometry(QtCore.QRect(5, 160, 156, 41))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("Lucida Grande"))
|
||||
font.setFamily("Lucida Grande")
|
||||
font.setPointSize(11)
|
||||
self.DirectoryButton.setFont(font)
|
||||
self.DirectoryButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon2 = QtGui.QIcon()
|
||||
icon2.addPixmap(QtGui.QPixmap(_fromUtf8(":/Other/icons/folder_new.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon2.addPixmap(QtGui.QPixmap(":/Other/icons/folder_new.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.DirectoryButton.setIcon(icon2)
|
||||
self.DirectoryButton.setObjectName(_fromUtf8("DirectoryButton"))
|
||||
self.FileButton = QtGui.QPushButton(self.Form)
|
||||
self.DirectoryButton.setObjectName("DirectoryButton")
|
||||
self.FileButton = QtWidgets.QPushButton(self.Form)
|
||||
self.FileButton.setGeometry(QtCore.QRect(260, 160, 157, 41))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("Lucida Grande"))
|
||||
font.setFamily("Lucida Grande")
|
||||
font.setPointSize(11)
|
||||
self.FileButton.setFont(font)
|
||||
self.FileButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon3 = QtGui.QIcon()
|
||||
icon3.addPixmap(QtGui.QPixmap(_fromUtf8(":/Other/icons/document_new.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon3.addPixmap(QtGui.QPixmap(":/Other/icons/document_new.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.FileButton.setIcon(icon3)
|
||||
self.FileButton.setObjectName(_fromUtf8("FileButton"))
|
||||
self.ClearButton = QtGui.QPushButton(self.Form)
|
||||
self.FileButton.setObjectName("FileButton")
|
||||
self.ClearButton = QtWidgets.QPushButton(self.Form)
|
||||
self.ClearButton.setGeometry(QtCore.QRect(160, 160, 101, 41))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("Lucida Grande"))
|
||||
font.setFamily("Lucida Grande")
|
||||
font.setPointSize(11)
|
||||
self.ClearButton.setFont(font)
|
||||
self.ClearButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon4 = QtGui.QIcon()
|
||||
icon4.addPixmap(QtGui.QPixmap(_fromUtf8(":/Other/icons/clear.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon4.addPixmap(QtGui.QPixmap(":/Other/icons/clear.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.ClearButton.setIcon(icon4)
|
||||
self.ClearButton.setObjectName(_fromUtf8("ClearButton"))
|
||||
self.OptionsBasic = QtGui.QFrame(self.Form)
|
||||
self.ClearButton.setObjectName("ClearButton")
|
||||
self.OptionsBasic = QtWidgets.QFrame(self.Form)
|
||||
self.OptionsBasic.setGeometry(QtCore.QRect(5, 233, 421, 41))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("Lucida Grande"))
|
||||
font.setFamily("Lucida Grande")
|
||||
font.setPointSize(12)
|
||||
self.OptionsBasic.setFont(font)
|
||||
self.OptionsBasic.setObjectName(_fromUtf8("OptionsBasic"))
|
||||
self.MangaBox = QtGui.QCheckBox(self.OptionsBasic)
|
||||
self.OptionsBasic.setObjectName("OptionsBasic")
|
||||
self.MangaBox = QtWidgets.QCheckBox(self.OptionsBasic)
|
||||
self.MangaBox.setGeometry(QtCore.QRect(9, 10, 130, 18))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("Lucida Grande"))
|
||||
font.setFamily("Lucida Grande")
|
||||
font.setPointSize(12)
|
||||
self.MangaBox.setFont(font)
|
||||
self.MangaBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.MangaBox.setObjectName(_fromUtf8("MangaBox"))
|
||||
self.QualityBox = QtGui.QCheckBox(self.OptionsBasic)
|
||||
self.MangaBox.setObjectName("MangaBox")
|
||||
self.QualityBox = QtWidgets.QCheckBox(self.OptionsBasic)
|
||||
self.QualityBox.setGeometry(QtCore.QRect(282, 10, 135, 18))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("Lucida Grande"))
|
||||
font.setFamily("Lucida Grande")
|
||||
font.setPointSize(12)
|
||||
self.QualityBox.setFont(font)
|
||||
self.QualityBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.QualityBox.setTristate(True)
|
||||
self.QualityBox.setObjectName(_fromUtf8("QualityBox"))
|
||||
self.RotateBox = QtGui.QCheckBox(self.OptionsBasic)
|
||||
self.QualityBox.setObjectName("QualityBox")
|
||||
self.RotateBox = QtWidgets.QCheckBox(self.OptionsBasic)
|
||||
self.RotateBox.setGeometry(QtCore.QRect(145, 10, 130, 18))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("Lucida Grande"))
|
||||
font.setFamily("Lucida Grande")
|
||||
font.setPointSize(12)
|
||||
self.RotateBox.setFont(font)
|
||||
self.RotateBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.RotateBox.setObjectName(_fromUtf8("RotateBox"))
|
||||
self.JobList = QtGui.QListWidget(self.Form)
|
||||
self.RotateBox.setObjectName("RotateBox")
|
||||
self.JobList = QtWidgets.QListWidget(self.Form)
|
||||
self.JobList.setGeometry(QtCore.QRect(10, 50, 401, 101))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("Lucida Grande"))
|
||||
font.setFamily("Lucida Grande")
|
||||
font.setPointSize(11)
|
||||
self.JobList.setFont(font)
|
||||
self.JobList.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.JobList.setStyleSheet("QListWidget#JobList {background:#ffffff;background-image:url(:/Other/icons/list_background.png);background-position:center center;background-repeat:no-repeat;}QScrollBar:vertical{border:1px solid #999;background:#FFF;width:5px;margin:0}QScrollBar::handle:vertical{background:DarkGray;min-height:0}QScrollBar::add-line:vertical{height:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:vertical{height:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}QScrollBar:horizontal{border:1px solid #999;background:#FFF;height:5px;margin:0}QScrollBar::handle:horizontal{background:DarkGray;min-width:0}QScrollBar::add-line:horizontal{width:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:horizontal{width:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}")
|
||||
self.JobList.setProperty("showDropIndicator", False)
|
||||
self.JobList.setSelectionMode(QtGui.QAbstractItemView.NoSelection)
|
||||
self.JobList.setObjectName(_fromUtf8("JobList"))
|
||||
self.BasicModeButton = QtGui.QPushButton(self.Form)
|
||||
self.BasicModeButton.setGeometry(QtCore.QRect(5, 10, 210, 41))
|
||||
self.JobList.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
|
||||
self.JobList.setObjectName("JobList")
|
||||
self.BasicModeButton = QtWidgets.QPushButton(self.Form)
|
||||
self.BasicModeButton.setGeometry(QtCore.QRect(5, 10, 156, 41))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("Lucida Grande"))
|
||||
font.setFamily("Lucida Grande")
|
||||
font.setPointSize(12)
|
||||
font.setBold(False)
|
||||
font.setWeight(50)
|
||||
self.BasicModeButton.setFont(font)
|
||||
self.BasicModeButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.BasicModeButton.setObjectName(_fromUtf8("BasicModeButton"))
|
||||
self.AdvModeButton = QtGui.QPushButton(self.Form)
|
||||
self.AdvModeButton.setGeometry(QtCore.QRect(207, 10, 210, 41))
|
||||
self.BasicModeButton.setObjectName("BasicModeButton")
|
||||
self.AdvModeButton = QtWidgets.QPushButton(self.Form)
|
||||
self.AdvModeButton.setGeometry(QtCore.QRect(260, 10, 156, 41))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("Lucida Grande"))
|
||||
font.setFamily("Lucida Grande")
|
||||
font.setPointSize(12)
|
||||
font.setBold(False)
|
||||
font.setWeight(50)
|
||||
self.AdvModeButton.setFont(font)
|
||||
self.AdvModeButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.AdvModeButton.setObjectName(_fromUtf8("AdvModeButton"))
|
||||
self.OptionsAdvancedGamma = QtGui.QFrame(self.Form)
|
||||
self.AdvModeButton.setObjectName("AdvModeButton")
|
||||
self.OptionsAdvancedGamma = QtWidgets.QFrame(self.Form)
|
||||
self.OptionsAdvancedGamma.setEnabled(True)
|
||||
self.OptionsAdvancedGamma.setGeometry(QtCore.QRect(5, 303, 401, 41))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("Lucida Grande"))
|
||||
font.setFamily("Lucida Grande")
|
||||
font.setPointSize(9)
|
||||
self.OptionsAdvancedGamma.setFont(font)
|
||||
self.OptionsAdvancedGamma.setObjectName(_fromUtf8("OptionsAdvancedGamma"))
|
||||
self.GammaLabel = QtGui.QLabel(self.OptionsAdvancedGamma)
|
||||
self.OptionsAdvancedGamma.setObjectName("OptionsAdvancedGamma")
|
||||
self.GammaLabel = QtWidgets.QLabel(self.OptionsAdvancedGamma)
|
||||
self.GammaLabel.setGeometry(QtCore.QRect(20, 0, 100, 40))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("Lucida Grande"))
|
||||
font.setFamily("Lucida Grande")
|
||||
font.setPointSize(12)
|
||||
font.setBold(False)
|
||||
font.setWeight(50)
|
||||
self.GammaLabel.setFont(font)
|
||||
self.GammaLabel.setObjectName(_fromUtf8("GammaLabel"))
|
||||
self.GammaSlider = QtGui.QSlider(self.OptionsAdvancedGamma)
|
||||
self.GammaLabel.setObjectName("GammaLabel")
|
||||
self.GammaSlider = QtWidgets.QSlider(self.OptionsAdvancedGamma)
|
||||
self.GammaSlider.setGeometry(QtCore.QRect(110, 10, 290, 22))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("Lucida Grande"))
|
||||
font.setFamily("Lucida Grande")
|
||||
self.GammaSlider.setFont(font)
|
||||
self.GammaSlider.setFocusPolicy(QtCore.Qt.ClickFocus)
|
||||
self.GammaSlider.setMaximum(500)
|
||||
self.GammaSlider.setSingleStep(5)
|
||||
self.GammaSlider.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.GammaSlider.setObjectName(_fromUtf8("GammaSlider"))
|
||||
self.ProgressBar = QtGui.QProgressBar(self.Form)
|
||||
self.ProgressBar.setGeometry(QtCore.QRect(10, 10, 401, 35))
|
||||
self.GammaSlider.setObjectName("GammaSlider")
|
||||
self.ProgressBar = QtWidgets.QProgressBar(self.Form)
|
||||
self.ProgressBar.setGeometry(QtCore.QRect(10, 10, 401, 29))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("Lucida Grande"))
|
||||
font.setFamily("Lucida Grande")
|
||||
font.setPointSize(10)
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.ProgressBar.setFont(font)
|
||||
self.ProgressBar.setAutoFillBackground(True)
|
||||
self.ProgressBar.setProperty("value", 0)
|
||||
self.ProgressBar.setAlignment(QtCore.Qt.AlignJustify|QtCore.Qt.AlignVCenter)
|
||||
self.ProgressBar.setFormat(_fromUtf8(""))
|
||||
self.ProgressBar.setObjectName(_fromUtf8("ProgressBar"))
|
||||
self.OptionsExpert = QtGui.QFrame(self.Form)
|
||||
self.ProgressBar.setFormat("")
|
||||
self.ProgressBar.setObjectName("ProgressBar")
|
||||
self.OptionsExpert = QtWidgets.QFrame(self.Form)
|
||||
self.OptionsExpert.setGeometry(QtCore.QRect(5, 335, 421, 41))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("Lucida Grande"))
|
||||
font.setFamily("Lucida Grande")
|
||||
font.setPointSize(9)
|
||||
self.OptionsExpert.setFont(font)
|
||||
self.OptionsExpert.setObjectName(_fromUtf8("OptionsExpert"))
|
||||
self.ColorBox = QtGui.QCheckBox(self.OptionsExpert)
|
||||
self.OptionsExpert.setObjectName("OptionsExpert")
|
||||
self.ColorBox = QtWidgets.QCheckBox(self.OptionsExpert)
|
||||
self.ColorBox.setGeometry(QtCore.QRect(9, 11, 130, 18))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("Lucida Grande"))
|
||||
font.setFamily("Lucida Grande")
|
||||
font.setPointSize(12)
|
||||
self.ColorBox.setFont(font)
|
||||
self.ColorBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.ColorBox.setObjectName(_fromUtf8("ColorBox"))
|
||||
self.OptionsExpertInternal = QtGui.QFrame(self.OptionsExpert)
|
||||
self.ColorBox.setObjectName("ColorBox")
|
||||
self.OptionsExpertInternal = QtWidgets.QFrame(self.OptionsExpert)
|
||||
self.OptionsExpertInternal.setGeometry(QtCore.QRect(95, 0, 315, 40))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("Lucida Grande"))
|
||||
font.setFamily("Lucida Grande")
|
||||
self.OptionsExpertInternal.setFont(font)
|
||||
self.OptionsExpertInternal.setObjectName(_fromUtf8("OptionsExpertInternal"))
|
||||
self.gridLayout_2 = QtGui.QGridLayout(self.OptionsExpertInternal)
|
||||
self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2"))
|
||||
self.wLabel = QtGui.QLabel(self.OptionsExpertInternal)
|
||||
self.OptionsExpertInternal.setObjectName("OptionsExpertInternal")
|
||||
self.gridLayout_2 = QtWidgets.QGridLayout(self.OptionsExpertInternal)
|
||||
self.gridLayout_2.setObjectName("gridLayout_2")
|
||||
self.wLabel = QtWidgets.QLabel(self.OptionsExpertInternal)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("Lucida Grande"))
|
||||
font.setFamily("Lucida Grande")
|
||||
font.setPointSize(12)
|
||||
font.setBold(False)
|
||||
font.setWeight(50)
|
||||
self.wLabel.setFont(font)
|
||||
self.wLabel.setObjectName(_fromUtf8("wLabel"))
|
||||
self.wLabel.setObjectName("wLabel")
|
||||
self.gridLayout_2.addWidget(self.wLabel, 0, 0, 1, 1)
|
||||
self.customWidth = QtGui.QLineEdit(self.OptionsExpertInternal)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
|
||||
self.customWidth = QtWidgets.QLineEdit(self.OptionsExpertInternal)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.customWidth.sizePolicy().hasHeightForWidth())
|
||||
self.customWidth.setSizePolicy(sizePolicy)
|
||||
self.customWidth.setMaximumSize(QtCore.QSize(45, 16777215))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("Lucida Grande"))
|
||||
font.setFamily("Lucida Grande")
|
||||
font.setPointSize(12)
|
||||
self.customWidth.setFont(font)
|
||||
self.customWidth.setFocusPolicy(QtCore.Qt.ClickFocus)
|
||||
self.customWidth.setAcceptDrops(False)
|
||||
self.customWidth.setMaxLength(4)
|
||||
self.customWidth.setObjectName(_fromUtf8("customWidth"))
|
||||
self.customWidth.setObjectName("customWidth")
|
||||
self.gridLayout_2.addWidget(self.customWidth, 0, 1, 1, 1)
|
||||
self.hLabel = QtGui.QLabel(self.OptionsExpertInternal)
|
||||
self.hLabel = QtWidgets.QLabel(self.OptionsExpertInternal)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("Lucida Grande"))
|
||||
font.setFamily("Lucida Grande")
|
||||
font.setPointSize(12)
|
||||
font.setBold(False)
|
||||
font.setWeight(50)
|
||||
self.hLabel.setFont(font)
|
||||
self.hLabel.setObjectName(_fromUtf8("hLabel"))
|
||||
self.hLabel.setObjectName("hLabel")
|
||||
self.gridLayout_2.addWidget(self.hLabel, 0, 2, 1, 1)
|
||||
self.customHeight = QtGui.QLineEdit(self.OptionsExpertInternal)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
|
||||
self.customHeight = QtWidgets.QLineEdit(self.OptionsExpertInternal)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.customHeight.sizePolicy().hasHeightForWidth())
|
||||
self.customHeight.setSizePolicy(sizePolicy)
|
||||
self.customHeight.setMaximumSize(QtCore.QSize(45, 16777215))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("Lucida Grande"))
|
||||
font.setFamily("Lucida Grande")
|
||||
font.setPointSize(12)
|
||||
self.customHeight.setFont(font)
|
||||
self.customHeight.setFocusPolicy(QtCore.Qt.ClickFocus)
|
||||
self.customHeight.setAcceptDrops(False)
|
||||
self.customHeight.setMaxLength(4)
|
||||
self.customHeight.setObjectName(_fromUtf8("customHeight"))
|
||||
self.customHeight.setObjectName("customHeight")
|
||||
self.gridLayout_2.addWidget(self.customHeight, 0, 3, 1, 1)
|
||||
self.EditorButton = QtWidgets.QPushButton(self.Form)
|
||||
self.EditorButton.setGeometry(QtCore.QRect(160, 10, 101, 41))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily("Lucida Grande")
|
||||
font.setPointSize(12)
|
||||
self.EditorButton.setFont(font)
|
||||
self.EditorButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon5 = QtGui.QIcon()
|
||||
icon5.addPixmap(QtGui.QPixmap(":/Other/icons/editor.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.EditorButton.setIcon(icon5)
|
||||
self.EditorButton.setObjectName("EditorButton")
|
||||
KCC.setCentralWidget(self.Form)
|
||||
self.ActionBasic = QtGui.QAction(KCC)
|
||||
self.statusBar = QtWidgets.QStatusBar(KCC)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily("Aharoni")
|
||||
font.setPointSize(8)
|
||||
self.statusBar.setFont(font)
|
||||
self.statusBar.setSizeGripEnabled(False)
|
||||
self.statusBar.setObjectName("statusBar")
|
||||
KCC.setStatusBar(self.statusBar)
|
||||
self.ActionBasic = QtWidgets.QAction(KCC)
|
||||
self.ActionBasic.setCheckable(True)
|
||||
self.ActionBasic.setChecked(False)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
self.ActionBasic.setFont(font)
|
||||
self.ActionBasic.setObjectName(_fromUtf8("ActionBasic"))
|
||||
self.ActionAdvanced = QtGui.QAction(KCC)
|
||||
self.ActionBasic.setObjectName("ActionBasic")
|
||||
self.ActionAdvanced = QtWidgets.QAction(KCC)
|
||||
self.ActionAdvanced.setCheckable(True)
|
||||
self.ActionAdvanced.setObjectName(_fromUtf8("ActionAdvanced"))
|
||||
self.ActionAdvanced.setObjectName("ActionAdvanced")
|
||||
|
||||
self.retranslateUi(KCC)
|
||||
QtCore.QMetaObject.connectSlotsByName(KCC)
|
||||
@@ -355,47 +359,50 @@ class Ui_KCC(object):
|
||||
KCC.setTabOrder(self.ConvertButton, self.ClearButton)
|
||||
|
||||
def retranslateUi(self, KCC):
|
||||
KCC.setWindowTitle(_translate("KCC", "Kindle Comic Converter", None))
|
||||
self.ProcessingBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-size:12pt;\">Disable image optimizations.</span></p></body></html>", None))
|
||||
self.ProcessingBox.setText(_translate("KCC", "No optimisation", None))
|
||||
self.UpscaleBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-size:12pt; font-weight:600; text-decoration: underline;\">Unchecked - Nothing<br/></span><span style=\" font-size:12pt;\">Images smaller than device resolution will not be resized.</span></p><p><span style=\" font-size:12pt; font-weight:600; text-decoration: underline;\">Indeterminate - Stretching<br/></span><span style=\" font-size:12pt;\">Images smaller than device resolution will be resized. Aspect ratio will be not preserved.</span></p><p><span style=\" font-size:12pt; font-weight:600; text-decoration: underline;\">Checked - Upscaling<br/></span><span style=\" font-size:12pt;\">Images smaller than device resolution will be resized. Aspect ratio will be preserved.</span></p></body></html>", None))
|
||||
self.UpscaleBox.setText(_translate("KCC", "Stretch/Upscale", None))
|
||||
self.WebtoonBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-size:12pt;\">Enable auto-splitting of webtoons like </span><span style=\" font-size:12pt; font-style:italic;\">Tower of God</span><span style=\" font-size:12pt;\"> or </span><span style=\" font-size:12pt; font-style:italic;\">Noblesse</span><span style=\" font-size:12pt;\">.<br/>Pages with a low width, high height and vertical panel flow.</span></p></body></html>", None))
|
||||
self.WebtoonBox.setText(_translate("KCC", "Webtoon mode", None))
|
||||
self.NoDitheringBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-size:12pt;\">Create PNG files instead JPEG.</span></p></body></html>", None))
|
||||
self.NoDitheringBox.setText(_translate("KCC", "PNG output", None))
|
||||
self.BorderBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-size:12pt; font-weight:600; text-decoration: underline;\">Unchecked - Autodetection<br/></span><span style=\" font-size:12pt;\">Color of margins fill will be detected automatically.</span></p><p><span style=\" font-size:12pt; font-weight:600; text-decoration: underline;\">Indeterminate - White<br/></span><span style=\" font-size:12pt;\">Margins will be filled with white color.</span></p><p><span style=\" font-size:12pt; font-weight:600; text-decoration: underline;\">Checked - Black<br/></span><span style=\" font-size:12pt;\">Margins will be filled with black color.</span></p></body></html>", None))
|
||||
self.BorderBox.setText(_translate("KCC", "W/B margins", None))
|
||||
self.NoRotateBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-size:12pt;\">Disable splitting and rotation.</span></p></body></html>", None))
|
||||
self.NoRotateBox.setText(_translate("KCC", "No split/rotate", None))
|
||||
self.DeviceBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-size:12pt;\">Target device.</span></p></body></html>", None))
|
||||
self.FormatBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-size:12pt;\">Output format.</span></p></body></html>", None))
|
||||
self.ConvertButton.setText(_translate("KCC", "Convert", None))
|
||||
self.DirectoryButton.setText(_translate("KCC", "Add directory", None))
|
||||
self.FileButton.setText(_translate("KCC", "Add file", None))
|
||||
self.ClearButton.setText(_translate("KCC", "Clear list", None))
|
||||
self.MangaBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-size:12pt;\">Enable right-to-left reading.</span></p></body></html>", None))
|
||||
self.MangaBox.setText(_translate("KCC", "Manga mode", None))
|
||||
self.QualityBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\"font-size:12pt; font-weight:600; text-decoration: underline;\">Unchecked - Normal quality mode<br/></span><span style=\"font-size:12pt; font-style:italic;\">Use it when Panel View support is not needed.</span><span style=\"font-size:12pt; font-weight:600; text-decoration: underline;\"><br/></span><span style=\"font-size:12pt;\">- Maximum quality when zoom is not enabled.<br/>- Poor quality when zoom is enabled.<br/>- Lowest file size.</span></p><p><span style=\"font-size:12pt; font-weight:600; text-decoration: underline;\">Indeterminate - High quality mode<br/></span><span style=\"font-size:12pt; font-style:italic;\">Not zoomed image </span><span style=\"font-size:12pt; font-weight:600; font-style:italic;\">might </span><span style=\"font-size:12pt; font-style:italic;\">be a little blurry.</span><span style=\"font-size:12pt; font-weight:600; text-decoration: underline;\"><br/></span><span style=\"font-size:12pt;\">- Medium/High quality when zoom is not enabled.<br/>- Maximum quality when zoom is enabled.</span></p><p><span style=\"font-size:12pt; font-weight:600; text-decoration: underline;\">Checked - Ultra quality mode<br/></span><span style=\"font-size:12pt; font-style:italic;\">Maximum possible quality.</span><span style=\"font-size:12pt; font-weight:600; text-decoration: underline;\"><br/></span><span style=\"font-size:12pt;\">- Maximum quality when zoom is not enabled.<br/>- Maximum quality when zoom is enabled.<br/>- Very high file size.</span></p></body></html>", None))
|
||||
self.QualityBox.setText(_translate("KCC", "High/Ultra quality", None))
|
||||
self.RotateBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-size:12pt;\">Disable page spliting.<br/>They will be rotated instead.</span></p></body></html>", None))
|
||||
self.RotateBox.setText(_translate("KCC", "Horizontal mode", None))
|
||||
self.BasicModeButton.setText(_translate("KCC", "Basic", None))
|
||||
self.AdvModeButton.setText(_translate("KCC", "Advanced", None))
|
||||
self.GammaLabel.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-size:12pt;\">When converting color images setting this option to 1.0 </span><span style=\" font-size:12pt; font-weight:600;\">might</span><span style=\" font-size:12pt;\"> improve readability.</span></p></body></html>", None))
|
||||
self.GammaLabel.setText(_translate("KCC", "Gamma: Auto", None))
|
||||
self.GammaSlider.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-size:12pt;\">When converting color images setting this option to 1.0 </span><span style=\" font-size:12pt; font-weight:600;\">might</span><span style=\" font-size:12pt;\"> improve readability.</span></p></body></html>", None))
|
||||
self.ColorBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-size:12pt;\">Do not convert images to grayscale.</span></p></body></html>", None))
|
||||
self.ColorBox.setText(_translate("KCC", "Color mode", None))
|
||||
self.wLabel.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-size:12pt;\">Resolution of target device.</span></p></body></html>", None))
|
||||
self.wLabel.setText(_translate("KCC", "Custom width: ", None))
|
||||
self.customWidth.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-size:12pt;\">Resolution of target device.</span></p></body></html>", None))
|
||||
self.customWidth.setInputMask(_translate("KCC", "0000; ", None))
|
||||
self.hLabel.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-size:12pt;\">Resolution of target device.</span></p></body></html>", None))
|
||||
self.hLabel.setText(_translate("KCC", "Custom height: ", None))
|
||||
self.customHeight.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-size:12pt;\">Resolution of target device.</span></p></body></html>", None))
|
||||
self.customHeight.setInputMask(_translate("KCC", "0000; ", None))
|
||||
self.ActionBasic.setText(_translate("KCC", "Basic", None))
|
||||
self.ActionAdvanced.setText(_translate("KCC", "Advanced", None))
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
KCC.setWindowTitle(_translate("KCC", "Kindle Comic Converter"))
|
||||
self.ProcessingBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Disable image optimizations.<br/><span style=\" font-weight:600;\">Input images must be already resized.</span></p></body></html>"))
|
||||
self.ProcessingBox.setText(_translate("KCC", "No optimisation"))
|
||||
self.UpscaleBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - Nothing<br/></span>Images smaller than device resolution will not be resized.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Indeterminate - Stretching<br/></span>Images smaller than device resolution will be resized. Aspect ratio will be not preserved.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - Upscaling<br/></span>Images smaller than device resolution will be resized. Aspect ratio will be preserved.</p></body></html>"))
|
||||
self.UpscaleBox.setText(_translate("KCC", "Stretch/Upscale"))
|
||||
self.WebtoonBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Enable special parsing mode for WebToons.</p></body></html>"))
|
||||
self.WebtoonBox.setText(_translate("KCC", "Webtoon mode"))
|
||||
self.NoDitheringBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Create PNG files instead JPEG.<br/>Quality increase is not noticeable on most of devices.<br/>Output files <span style=\" font-weight:600;\">might</span> be smaller.<br/><span style=\" font-weight:600;\">MOBI conversion will be much slower.</span></p></body></html>"))
|
||||
self.NoDitheringBox.setText(_translate("KCC", "PNG output"))
|
||||
self.BorderBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - Autodetection<br/></span>Color of margins fill will be detected automatically.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Indeterminate - White<br/></span>Margins will be filled with white color.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - Black<br/></span>Margins will be filled with black color.</p></body></html>"))
|
||||
self.BorderBox.setText(_translate("KCC", "W/B margins"))
|
||||
self.NoRotateBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Disable page splitting and rotation.</p></body></html>"))
|
||||
self.NoRotateBox.setText(_translate("KCC", "No split/rotate"))
|
||||
self.DeviceBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Target device.</p></body></html>"))
|
||||
self.FormatBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Output format.</p></body></html>"))
|
||||
self.ConvertButton.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Shift+Click to select the output directory.</p></body></html>"))
|
||||
self.ConvertButton.setText(_translate("KCC", "Convert"))
|
||||
self.DirectoryButton.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Add directory containing JPG, PNG or GIF files to queue.<br/><span style=\" font-weight:600;\">CBR, CBZ and CB7 files inside will not be processed!</span></p></body></html>"))
|
||||
self.DirectoryButton.setText(_translate("KCC", "Add directory"))
|
||||
self.FileButton.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Add CBR, CBZ, CB7 or PDF file to queue.</p></body></html>"))
|
||||
self.FileButton.setText(_translate("KCC", "Add file"))
|
||||
self.ClearButton.setText(_translate("KCC", "Clear list"))
|
||||
self.MangaBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Enable right-to-left reading.</p></body></html>"))
|
||||
self.MangaBox.setText(_translate("KCC", "Manga mode"))
|
||||
self.QualityBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Quality of Panel View/zoom. Highly impact size of output file.<br/><span style=\" font-weight:600;\">This option control only quality of magnification!</span></p></body></html>"))
|
||||
self.QualityBox.setText(_translate("KCC", "High/Ultra quality"))
|
||||
self.RotateBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Disable splitting of two-page spreads.<br/>They will be rotated instead.</p></body></html>"))
|
||||
self.RotateBox.setText(_translate("KCC", "Horizontal mode"))
|
||||
self.BasicModeButton.setText(_translate("KCC", "Basic"))
|
||||
self.AdvModeButton.setText(_translate("KCC", "Advanced"))
|
||||
self.GammaLabel.setText(_translate("KCC", "Gamma: Auto"))
|
||||
self.ColorBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Don\'t convert images to grayscale.</p></body></html>"))
|
||||
self.ColorBox.setText(_translate("KCC", "Color mode"))
|
||||
self.wLabel.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Resolution of target device.</p></body></html>"))
|
||||
self.wLabel.setText(_translate("KCC", "Custom width: "))
|
||||
self.customWidth.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Resolution of target device.</p></body></html>"))
|
||||
self.customWidth.setInputMask(_translate("KCC", "0000"))
|
||||
self.hLabel.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Resolution of target device.</p></body></html>"))
|
||||
self.hLabel.setText(_translate("KCC", "Custom height: "))
|
||||
self.customHeight.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Resolution of target device.</p></body></html>"))
|
||||
self.customHeight.setInputMask(_translate("KCC", "0000"))
|
||||
self.EditorButton.setText(_translate("KCC", "Editor"))
|
||||
self.ActionBasic.setText(_translate("KCC", "Basic"))
|
||||
self.ActionAdvanced.setText(_translate("KCC", "Advanced"))
|
||||
|
||||
import KCC_rc
|
||||
from . import KCC_rc
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
__version__ = '3.3'
|
||||
__version__ = '4.5'
|
||||
__license__ = 'ISC'
|
||||
__copyright__ = '2012-2013, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
|
||||
__copyright__ = '2012-2015, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
@@ -1,5 +1,5 @@
|
||||
# Copyright (c) 2012-2013 Ciro Mattia Gonano <ciromattia@gmail.com>
|
||||
# Copyright (c) 2013 Pawel Jastrzebski <pawelj@vulturis.eu>
|
||||
# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
|
||||
# Copyright (c) 2013-2015 Pawel Jastrzebski <pawelj@iosphe.re>
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for
|
||||
# any purpose with or without fee is hereby granted, provided that the
|
||||
@@ -15,25 +15,25 @@
|
||||
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
__license__ = 'ISC'
|
||||
__copyright__ = '2012-2013, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import sys
|
||||
import os
|
||||
import zipfile
|
||||
import rarfile
|
||||
from subprocess import Popen, STDOUT, PIPE
|
||||
from zipfile import is_zipfile, ZipFile
|
||||
from subprocess import STDOUT, PIPE
|
||||
from psutil import Popen
|
||||
from shutil import move, copy
|
||||
from . import rarfile
|
||||
from .shared import check7ZFile as is_7zfile, saferReplace
|
||||
|
||||
|
||||
# noinspection PyBroadException
|
||||
class CBxArchive:
|
||||
def __init__(self, origFileName):
|
||||
self.origFileName = origFileName
|
||||
if zipfile.is_zipfile(origFileName):
|
||||
if is_zipfile(origFileName):
|
||||
self.compressor = 'zip'
|
||||
elif rarfile.is_rarfile(origFileName):
|
||||
self.compressor = 'rar'
|
||||
elif origFileName.endswith('.7z') or origFileName.endswith('.cb7'):
|
||||
elif is_7zfile(origFileName):
|
||||
self.compressor = '7z'
|
||||
else:
|
||||
self.compressor = None
|
||||
@@ -42,7 +42,7 @@ class CBxArchive:
|
||||
return self.compressor is not None
|
||||
|
||||
def extractCBZ(self, targetdir):
|
||||
cbzFile = zipfile.ZipFile(self.origFileName)
|
||||
cbzFile = ZipFile(self.origFileName)
|
||||
filelist = []
|
||||
for f in cbzFile.namelist():
|
||||
if f.startswith('__MACOSX') or f.endswith('.DS_Store') or f.endswith('thumbs.db'):
|
||||
@@ -50,7 +50,7 @@ class CBxArchive:
|
||||
elif f.endswith('/'):
|
||||
try:
|
||||
os.makedirs(os.path.join(targetdir, f))
|
||||
except:
|
||||
except Exception:
|
||||
pass # the dir exists so we are going to extract the images only.
|
||||
else:
|
||||
filelist.append(f)
|
||||
@@ -65,24 +65,29 @@ class CBxArchive:
|
||||
elif f.endswith('/'):
|
||||
try:
|
||||
os.makedirs(os.path.join(targetdir, f))
|
||||
except:
|
||||
except Exception:
|
||||
pass # the dir exists so we are going to extract the images only.
|
||||
else:
|
||||
filelist.append(f)
|
||||
cbrFile.extractall(targetdir, filelist)
|
||||
|
||||
def extractCB7(self, targetdir):
|
||||
output = Popen('7za x "' + self.origFileName + '" -xr!__MACOSX -xr!.DS_Store -xr!thumbs.db -o"' + targetdir +
|
||||
'"', stdout=PIPE, stderr=STDOUT, shell=True)
|
||||
# Workaround for some wide UTF-8 + Popen abnormalities
|
||||
if sys.platform.startswith('darwin'):
|
||||
copy(self.origFileName, os.path.join(os.path.dirname(self.origFileName), 'TMP_KCC_TMP'))
|
||||
self.origFileName = os.path.join(os.path.dirname(self.origFileName), 'TMP_KCC_TMP')
|
||||
output = Popen('7za x "' + self.origFileName + '" -xr!__MACOSX -xr!.DS_Store -xr!thumbs.db -o"'
|
||||
+ targetdir + '"', stdout=PIPE, stderr=STDOUT, shell=True)
|
||||
extracted = False
|
||||
for line in output.stdout:
|
||||
if "Everything is Ok" in line:
|
||||
if b"Everything is Ok" in line:
|
||||
extracted = True
|
||||
if sys.platform.startswith('darwin'):
|
||||
os.remove(self.origFileName)
|
||||
if not extracted:
|
||||
raise OSError
|
||||
|
||||
def extract(self, targetdir):
|
||||
print "\n" + targetdir + "\n"
|
||||
if self.compressor == 'rar':
|
||||
self.extractCBR(targetdir)
|
||||
elif self.compressor == 'zip':
|
||||
@@ -90,9 +95,14 @@ class CBxArchive:
|
||||
elif self.compressor == '7z':
|
||||
self.extractCB7(targetdir)
|
||||
adir = os.listdir(targetdir)
|
||||
if 'ComicInfo.xml' in adir:
|
||||
adir.remove('ComicInfo.xml')
|
||||
if len(adir) == 1 and os.path.isdir(os.path.join(targetdir, adir[0])):
|
||||
import shutil
|
||||
for f in os.listdir(os.path.join(targetdir, adir[0])):
|
||||
shutil.move(os.path.join(targetdir, adir[0], f), targetdir)
|
||||
# If directory names contain UTF-8 chars shutil.move can't clean up the mess alone
|
||||
if os.path.isdir(os.path.join(targetdir, f)):
|
||||
saferReplace(os.path.join(targetdir, adir[0], f), os.path.join(targetdir, adir[0], f + '-A'))
|
||||
f += '-A'
|
||||
move(os.path.join(targetdir, adir[0], f), targetdir)
|
||||
os.rmdir(os.path.join(targetdir, adir[0]))
|
||||
return targetdir
|
||||
|
||||
1368
kcc/comic2ebook.py
1368
kcc/comic2ebook.py
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2012-2013 Ciro Mattia Gonano <ciromattia@gmail.com>
|
||||
# Copyright (c) 2013 Pawel Jastrzebski <pawelj@vulturis.eu>
|
||||
# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
|
||||
# Copyright (c) 2013-2015 Pawel Jastrzebski <pawelj@iosphe.re>
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for
|
||||
# any purpose with or without fee is hereby granted, provided that the
|
||||
@@ -18,46 +17,74 @@
|
||||
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
__version__ = '3.3'
|
||||
__license__ = 'ISC'
|
||||
__copyright__ = '2012-2013, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import os
|
||||
import sys
|
||||
from shutil import rmtree, copytree, move
|
||||
from optparse import OptionParser, OptionGroup
|
||||
from multiprocessing import Pool, Queue, freeze_support
|
||||
from multiprocessing import Pool
|
||||
from PIL import Image, ImageStat, ImageOps
|
||||
from scandir import walk
|
||||
from .shared import getImageFileName, walkLevel, walkSort
|
||||
try:
|
||||
# noinspection PyUnresolvedReferences
|
||||
from PIL import Image, ImageStat
|
||||
except ImportError:
|
||||
print "ERROR: Pillow is not installed!"
|
||||
exit(1)
|
||||
try:
|
||||
from PyQt4 import QtCore
|
||||
from PyQt5 import QtCore
|
||||
except ImportError:
|
||||
QtCore = None
|
||||
|
||||
|
||||
def getImageFileName(imgfile):
|
||||
filename = os.path.splitext(imgfile)
|
||||
if filename[0].startswith('.') or\
|
||||
(filename[1].lower() != '.png' and
|
||||
filename[1].lower() != '.jpg' and
|
||||
filename[1].lower() != '.gif' and
|
||||
filename[1].lower() != '.tif' and
|
||||
filename[1].lower() != '.tiff' and
|
||||
filename[1].lower() != '.bmp' and
|
||||
filename[1].lower() != '.jpeg'):
|
||||
return None
|
||||
return filename
|
||||
def mergeDirectoryTick(output):
|
||||
if output:
|
||||
mergeWorkerOutput.append(output)
|
||||
mergeWorkerPool.terminate()
|
||||
if GUI:
|
||||
GUI.progressBarTick.emit('tick')
|
||||
if not GUI.conversionAlive:
|
||||
mergeWorkerPool.terminate()
|
||||
|
||||
|
||||
def mergeDirectory(work):
|
||||
try:
|
||||
directory = work[0]
|
||||
images = []
|
||||
imagesValid = []
|
||||
sizes = []
|
||||
targetHeight = 0
|
||||
for root, dirs, files in walkLevel(directory, 0):
|
||||
for name in files:
|
||||
if getImageFileName(name) is not None:
|
||||
i = Image.open(os.path.join(root, name))
|
||||
images.append([os.path.join(root, name), i.size[0], i.size[1]])
|
||||
sizes.append(i.size[0])
|
||||
if len(images) > 0:
|
||||
targetWidth = max(set(sizes), key=sizes.count)
|
||||
for i in images:
|
||||
if i[1] <= targetWidth:
|
||||
targetHeight += i[2]
|
||||
imagesValid.append(i[0])
|
||||
# Silently drop directories that contain too many images
|
||||
# 131072 = GIMP_MAX_IMAGE_SIZE / 4
|
||||
if targetHeight > 131072:
|
||||
return None
|
||||
result = Image.new('RGB', (targetWidth, targetHeight))
|
||||
y = 0
|
||||
for i in imagesValid:
|
||||
img = Image.open(i)
|
||||
img = img.convert('RGB')
|
||||
if img.size[0] < targetWidth:
|
||||
img = ImageOps.fit(img, (targetWidth, img.size[1]), method=Image.BICUBIC, centering=(0.5, 0.5))
|
||||
result.paste(img, (0, y))
|
||||
y += img.size[1]
|
||||
os.remove(i)
|
||||
savePath = os.path.split(imagesValid[0])
|
||||
result.save(os.path.join(savePath[0], os.path.splitext(savePath[1])[0] + '.png'), 'PNG')
|
||||
except Exception:
|
||||
return str(sys.exc_info()[1])
|
||||
|
||||
|
||||
def sanitizePanelSize(panel, opt):
|
||||
newPanels = []
|
||||
if panel[2] > 8 * opt.height:
|
||||
diff = (panel[2] / 8)
|
||||
if panel[2] > 6 * opt.height:
|
||||
diff = int(panel[2] / 8)
|
||||
newPanels.append([panel[0], panel[1] - diff*7, diff])
|
||||
newPanels.append([panel[1] - diff*7, panel[1] - diff*6, diff])
|
||||
newPanels.append([panel[1] - diff*6, panel[1] - diff*5, diff])
|
||||
@@ -66,144 +93,129 @@ def sanitizePanelSize(panel, opt):
|
||||
newPanels.append([panel[1] - diff*3, panel[1] - diff*2, diff])
|
||||
newPanels.append([panel[1] - diff*2, panel[1] - diff, diff])
|
||||
newPanels.append([panel[1] - diff, panel[1], diff])
|
||||
elif panel[2] > 4 * opt.height:
|
||||
diff = (panel[2] / 4)
|
||||
elif panel[2] > 3 * opt.height:
|
||||
diff = int(panel[2] / 4)
|
||||
newPanels.append([panel[0], panel[1] - diff*3, diff])
|
||||
newPanels.append([panel[1] - diff*3, panel[1] - diff*2, diff])
|
||||
newPanels.append([panel[1] - diff*2, panel[1] - diff, diff])
|
||||
newPanels.append([panel[1] - diff, panel[1], diff])
|
||||
elif panel[2] > 2 * opt.height:
|
||||
newPanels.append([panel[0], panel[1] - (panel[2] / 2), (panel[2] / 2)])
|
||||
newPanels.append([panel[1] - (panel[2] / 2), panel[1], (panel[2] / 2)])
|
||||
elif panel[2] > 1.5 * opt.height:
|
||||
newPanels.append([panel[0], panel[1] - int(panel[2] / 2), int(panel[2] / 2)])
|
||||
newPanels.append([panel[1] - int(panel[2] / 2), panel[1], int(panel[2] / 2)])
|
||||
else:
|
||||
newPanels = [panel]
|
||||
return newPanels
|
||||
|
||||
|
||||
def splitImage_init(queue, opt):
|
||||
splitImage.queue = queue
|
||||
splitImage.options = opt
|
||||
def splitImageTick(output):
|
||||
if output:
|
||||
splitWorkerOutput.append(output)
|
||||
splitWorkerPool.terminate()
|
||||
if GUI:
|
||||
GUI.progressBarTick.emit('tick')
|
||||
if not GUI.conversionAlive:
|
||||
splitWorkerPool.terminate()
|
||||
|
||||
|
||||
# noinspection PyUnresolvedReferences
|
||||
def splitImage(work):
|
||||
path = work[0]
|
||||
name = work[1]
|
||||
opt = splitImage.options
|
||||
# Harcoded opttions
|
||||
threshold = 1.0
|
||||
delta = 15
|
||||
print ".",
|
||||
splitImage.queue.put(".")
|
||||
fileExpanded = os.path.splitext(name)
|
||||
filePath = os.path.join(path, name)
|
||||
# Detect corrupted files
|
||||
try:
|
||||
Image.open(filePath)
|
||||
except IOError:
|
||||
raise RuntimeError('Cannot read image file %s' % filePath)
|
||||
try:
|
||||
path = work[0]
|
||||
name = work[1]
|
||||
opt = work[2]
|
||||
# Hardcoded options
|
||||
threshold = 1.0
|
||||
delta = 15
|
||||
fileExpanded = os.path.splitext(name)
|
||||
filePath = os.path.join(path, name)
|
||||
image = Image.open(filePath)
|
||||
image.verify()
|
||||
except:
|
||||
raise RuntimeError('Image file %s is corrupted' % filePath)
|
||||
try:
|
||||
image = Image.open(filePath)
|
||||
image.load()
|
||||
except:
|
||||
raise RuntimeError('Image file %s is corrupted' % filePath)
|
||||
image = Image.open(filePath)
|
||||
image = image.convert('RGB')
|
||||
widthImg, heightImg = image.size
|
||||
if heightImg > opt.height:
|
||||
if opt.debug:
|
||||
from PIL import ImageDraw
|
||||
debugImage = Image.open(filePath)
|
||||
draw = ImageDraw.Draw(debugImage)
|
||||
|
||||
# Find panels
|
||||
y1 = 0
|
||||
y2 = 15
|
||||
panels = []
|
||||
while y2 < heightImg:
|
||||
while ImageStat.Stat(image.crop([0, y1, widthImg, y2])).var[0] < threshold and y2 < heightImg:
|
||||
y2 += delta
|
||||
y2 -= delta
|
||||
y1Temp = y2
|
||||
y1 = y2 + delta
|
||||
y2 = y1 + delta
|
||||
while ImageStat.Stat(image.crop([0, y1, widthImg, y2])).var[0] >= threshold and y2 < heightImg:
|
||||
y1 += delta
|
||||
y2 += delta
|
||||
if y1 + delta >= heightImg:
|
||||
y1 = heightImg - 1
|
||||
y2Temp = y1
|
||||
image = image.convert('RGB')
|
||||
widthImg, heightImg = image.size
|
||||
if heightImg > opt.height:
|
||||
if opt.debug:
|
||||
draw.line([(0, y1Temp), (widthImg, y1Temp)], fill=(0, 255, 0))
|
||||
draw.line([(0, y2Temp), (widthImg, y2Temp)], fill=(255, 0, 0))
|
||||
panelHeight = y2Temp - y1Temp
|
||||
if panelHeight > delta:
|
||||
# Panels that can't be cut nicely will be forcefully splitted
|
||||
panelsCleaned = sanitizePanelSize([y1Temp, y2Temp, panelHeight], opt)
|
||||
for panel in panelsCleaned:
|
||||
panels.append(panel)
|
||||
if opt.debug:
|
||||
# noinspection PyUnboundLocalVariable
|
||||
debugImage.save(os.path.join(path, fileExpanded[0] + '-debug.png'), 'PNG')
|
||||
from PIL import ImageDraw
|
||||
debugImage = Image.open(filePath)
|
||||
draw = ImageDraw.Draw(debugImage)
|
||||
|
||||
# Create virtual pages
|
||||
pages = []
|
||||
currentPage = []
|
||||
pageLeft = opt.height
|
||||
panelNumber = 0
|
||||
for panel in panels:
|
||||
if pageLeft - panel[2] > 0:
|
||||
pageLeft -= panel[2]
|
||||
currentPage.append(panelNumber)
|
||||
panelNumber += 1
|
||||
else:
|
||||
if len(currentPage) > 0:
|
||||
pages.append(currentPage)
|
||||
pageLeft = opt.height - panel[2]
|
||||
currentPage = [panelNumber]
|
||||
panelNumber += 1
|
||||
if len(currentPage) > 0:
|
||||
pages.append(currentPage)
|
||||
# Find panels
|
||||
y1 = 0
|
||||
y2 = 15
|
||||
panels = []
|
||||
while y2 < heightImg:
|
||||
while ImageStat.Stat(image.crop([0, y1, widthImg, y2])).var[0] < threshold and y2 < heightImg:
|
||||
y2 += delta
|
||||
y2 -= delta
|
||||
y1Temp = y2
|
||||
y1 = y2 + delta
|
||||
y2 = y1 + delta
|
||||
while ImageStat.Stat(image.crop([0, y1, widthImg, y2])).var[0] >= threshold and y2 < heightImg:
|
||||
y1 += delta
|
||||
y2 += delta
|
||||
if y1 + delta >= heightImg:
|
||||
y1 = heightImg - 1
|
||||
y2Temp = y1
|
||||
if opt.debug:
|
||||
draw.line([(0, y1Temp), (widthImg, y1Temp)], fill=(0, 255, 0))
|
||||
draw.line([(0, y2Temp), (widthImg, y2Temp)], fill=(255, 0, 0))
|
||||
panelHeight = y2Temp - y1Temp
|
||||
if panelHeight > delta:
|
||||
# Panels that can't be cut nicely will be forcefully splitted
|
||||
panelsCleaned = sanitizePanelSize([y1Temp, y2Temp, panelHeight], opt)
|
||||
for panel in panelsCleaned:
|
||||
panels.append(panel)
|
||||
if opt.debug:
|
||||
# noinspection PyUnboundLocalVariable
|
||||
debugImage.save(os.path.join(path, fileExpanded[0] + '-debug.png'), 'PNG')
|
||||
|
||||
# Create pages
|
||||
pageNumber = 1
|
||||
for page in pages:
|
||||
pageHeight = 0
|
||||
targetHeight = 0
|
||||
for panel in page:
|
||||
pageHeight += panels[panel][2]
|
||||
if pageHeight > delta:
|
||||
newPage = Image.new('RGB', (widthImg, pageHeight))
|
||||
# Create virtual pages
|
||||
pages = []
|
||||
currentPage = []
|
||||
pageLeft = opt.height
|
||||
panelNumber = 0
|
||||
for panel in panels:
|
||||
if pageLeft - panel[2] > 0:
|
||||
pageLeft -= panel[2]
|
||||
currentPage.append(panelNumber)
|
||||
panelNumber += 1
|
||||
else:
|
||||
if len(currentPage) > 0:
|
||||
pages.append(currentPage)
|
||||
pageLeft = opt.height - panel[2]
|
||||
currentPage = [panelNumber]
|
||||
panelNumber += 1
|
||||
if len(currentPage) > 0:
|
||||
pages.append(currentPage)
|
||||
|
||||
# Create pages
|
||||
pageNumber = 1
|
||||
for page in pages:
|
||||
pageHeight = 0
|
||||
targetHeight = 0
|
||||
for panel in page:
|
||||
panelImg = image.crop([0, panels[panel][0], widthImg, panels[panel][1]])
|
||||
newPage.paste(panelImg, (0, targetHeight))
|
||||
targetHeight += panels[panel][2]
|
||||
newPage.save(os.path.join(path, fileExpanded[0] + '-' +
|
||||
str(pageNumber) + '.png'), 'PNG')
|
||||
pageNumber += 1
|
||||
os.remove(filePath)
|
||||
pageHeight += panels[panel][2]
|
||||
if pageHeight > delta:
|
||||
newPage = Image.new('RGB', (widthImg, pageHeight))
|
||||
for panel in page:
|
||||
panelImg = image.crop([0, panels[panel][0], widthImg, panels[panel][1]])
|
||||
newPage.paste(panelImg, (0, targetHeight))
|
||||
targetHeight += panels[panel][2]
|
||||
newPage.save(os.path.join(path, fileExpanded[0] + '-' + str(pageNumber) + '.png'), 'PNG')
|
||||
pageNumber += 1
|
||||
os.remove(filePath)
|
||||
except Exception:
|
||||
return str(sys.exc_info()[1])
|
||||
|
||||
|
||||
def Copyright():
|
||||
print ('comic2panel v%(__version__)s. '
|
||||
'Written 2013 by Ciro Mattia Gonano and Pawel Jastrzebski.' % globals())
|
||||
|
||||
|
||||
# noinspection PyBroadException
|
||||
def main(argv=None, qtGUI=None):
|
||||
global options
|
||||
parser = OptionParser(usage="Usage: %prog [options] comic_folder", add_help_option=False)
|
||||
global options, GUI, splitWorkerPool, splitWorkerOutput, mergeWorkerPool, mergeWorkerOutput
|
||||
parser = OptionParser(usage="Usage: kcc-c2p [options] comic_folder", add_help_option=False)
|
||||
mainOptions = OptionGroup(parser, "MANDATORY")
|
||||
otherOptions = OptionGroup(parser, "OTHER")
|
||||
mainOptions.add_option("-y", "--height", type="int", dest="height", default=0,
|
||||
help="Height of the target device screen")
|
||||
mainOptions.add_option("-i", "--in-place", action="store_true", dest="inPlace", default=False,
|
||||
help="Overwrite source directory")
|
||||
mainOptions.add_option("-m", "--merge", action="store_true", dest="merge", default=False,
|
||||
help="Combine every directory into a single image before splitting")
|
||||
otherOptions.add_option("-d", "--debug", action="store_true", dest="debug", default=False,
|
||||
help="Create debug file for every splitted image")
|
||||
otherOptions.add_option("-h", "--help", action="help",
|
||||
@@ -221,57 +233,68 @@ def main(argv=None, qtGUI=None):
|
||||
if options.height > 0:
|
||||
options.sourceDir = args[0]
|
||||
options.targetDir = args[0] + "-Splitted"
|
||||
print "\nSplitting images..."
|
||||
if os.path.isdir(options.sourceDir):
|
||||
rmtree(options.targetDir, True)
|
||||
copytree(options.sourceDir, options.targetDir)
|
||||
work = []
|
||||
pagenumber = 0
|
||||
queue = Queue()
|
||||
pool = Pool(None, splitImage_init, [queue, options])
|
||||
for root, dirs, files in os.walk(options.targetDir, False):
|
||||
pagenumber = 1
|
||||
splitWorkerOutput = []
|
||||
splitWorkerPool = Pool()
|
||||
if options.merge:
|
||||
print("\nMerging images...")
|
||||
directoryNumer = 1
|
||||
mergeWork = []
|
||||
mergeWorkerOutput = []
|
||||
mergeWorkerPool = Pool()
|
||||
mergeWork.append([options.targetDir])
|
||||
for root, dirs, files in walk(options.targetDir, False):
|
||||
dirs, files = walkSort(dirs, files)
|
||||
for directory in dirs:
|
||||
directoryNumer += 1
|
||||
mergeWork.append([os.path.join(root, directory)])
|
||||
if GUI:
|
||||
GUI.progressBarTick.emit('Combining images')
|
||||
GUI.progressBarTick.emit(str(directoryNumer))
|
||||
for i in mergeWork:
|
||||
mergeWorkerPool.apply_async(func=mergeDirectory, args=(i, ), callback=mergeDirectoryTick)
|
||||
mergeWorkerPool.close()
|
||||
mergeWorkerPool.join()
|
||||
if GUI and not GUI.conversionAlive:
|
||||
rmtree(options.targetDir, True)
|
||||
raise UserWarning("Conversion interrupted.")
|
||||
if len(mergeWorkerOutput) > 0:
|
||||
rmtree(options.targetDir, True)
|
||||
raise RuntimeError("One of workers crashed. Cause: " + mergeWorkerOutput[0])
|
||||
print("\nSplitting images...")
|
||||
for root, dirs, files in walk(options.targetDir, False):
|
||||
for name in files:
|
||||
if getImageFileName(name) is not None:
|
||||
pagenumber += 1
|
||||
work.append([root, name])
|
||||
work.append([root, name, options])
|
||||
else:
|
||||
os.remove(os.path.join(root, name))
|
||||
if GUI:
|
||||
GUI.emit(QtCore.SIGNAL("progressBarTick"), pagenumber)
|
||||
GUI.progressBarTick.emit('Splitting images')
|
||||
GUI.progressBarTick.emit(str(pagenumber))
|
||||
GUI.progressBarTick.emit('tick')
|
||||
if len(work) > 0:
|
||||
workers = pool.map_async(func=splitImage, iterable=work)
|
||||
pool.close()
|
||||
if GUI:
|
||||
while not workers.ready():
|
||||
# noinspection PyBroadException
|
||||
try:
|
||||
queue.get(True, 5)
|
||||
except:
|
||||
pass
|
||||
GUI.emit(QtCore.SIGNAL("progressBarTick"))
|
||||
pool.join()
|
||||
queue.close()
|
||||
try:
|
||||
workers.get()
|
||||
except:
|
||||
for i in work:
|
||||
splitWorkerPool.apply_async(func=splitImage, args=(i, ), callback=splitImageTick)
|
||||
splitWorkerPool.close()
|
||||
splitWorkerPool.join()
|
||||
if GUI and not GUI.conversionAlive:
|
||||
rmtree(options.targetDir, True)
|
||||
raise RuntimeError("One of workers crashed. Cause: " + str(sys.exc_info()[1]))
|
||||
if GUI:
|
||||
GUI.emit(QtCore.SIGNAL("progressBarTick"), 1)
|
||||
raise UserWarning("Conversion interrupted.")
|
||||
if len(splitWorkerOutput) > 0:
|
||||
rmtree(options.targetDir, True)
|
||||
raise RuntimeError("One of workers crashed. Cause: " + splitWorkerOutput[0])
|
||||
if options.inPlace:
|
||||
rmtree(options.sourceDir, True)
|
||||
rmtree(options.sourceDir)
|
||||
move(options.targetDir, options.sourceDir)
|
||||
else:
|
||||
rmtree(options.targetDir)
|
||||
rmtree(options.targetDir, True)
|
||||
raise UserWarning("Source directory is empty.")
|
||||
else:
|
||||
raise UserWarning("Provided path is not a directory.")
|
||||
else:
|
||||
raise UserWarning("Target height is not set.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
freeze_support()
|
||||
Copyright()
|
||||
main(sys.argv[1:])
|
||||
sys.exit(0)
|
||||
raise UserWarning("Target height is not set.")
|
||||
184
kcc/dualmetafix.py
Normal file
184
kcc/dualmetafix.py
Normal file
@@ -0,0 +1,184 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Based on initial version of DualMetaFix. Copyright (C) 2013 Kevin Hendricks
|
||||
# Changes for KCC Copyright (C) 2014-2015 Pawel Jastrzebski <pawelj@iosphe.re>
|
||||
#
|
||||
# This program 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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import struct
|
||||
import mmap
|
||||
import shutil
|
||||
|
||||
|
||||
class DualMetaFixException(Exception):
|
||||
pass
|
||||
|
||||
# palm database offset constants
|
||||
number_of_pdb_records = 76
|
||||
first_pdb_record = 78
|
||||
|
||||
# important rec0 offsets
|
||||
mobi_header_base = 16
|
||||
mobi_header_length = 20
|
||||
mobi_version = 36
|
||||
title_offset = 84
|
||||
|
||||
|
||||
def getint(data, ofs, sz='L'):
|
||||
i, = struct.unpack_from('>'+sz, data, ofs)
|
||||
return i
|
||||
|
||||
|
||||
def writeint(data, ofs, n, slen='L'):
|
||||
if slen == 'L':
|
||||
return data[:ofs]+struct.pack('>L', n)+data[ofs+4:]
|
||||
else:
|
||||
return data[:ofs]+struct.pack('>H', n)+data[ofs+2:]
|
||||
|
||||
|
||||
def getsecaddr(datain, secno):
|
||||
nsec = getint(datain, number_of_pdb_records, 'H')
|
||||
if (secno < 0) | (secno >= nsec):
|
||||
emsg = 'requested section number %d out of range (nsec=%d)' % (secno, nsec)
|
||||
raise DualMetaFixException(emsg)
|
||||
secstart = getint(datain, first_pdb_record+secno*8)
|
||||
if secno == nsec-1:
|
||||
secend = len(datain)
|
||||
else:
|
||||
secend = getint(datain, first_pdb_record+(secno+1)*8)
|
||||
return secstart, secend
|
||||
|
||||
|
||||
def readsection(datain, secno):
|
||||
secstart, secend = getsecaddr(datain, secno)
|
||||
return datain[secstart:secend]
|
||||
|
||||
|
||||
# overwrite section - must be exact same length as original
|
||||
def replacesection(datain, secno, secdata):
|
||||
secstart, secend = getsecaddr(datain, secno)
|
||||
seclen = secend - secstart
|
||||
if len(secdata) != seclen:
|
||||
raise DualMetaFixException('section length change in replacesection')
|
||||
datain[secstart:secstart+seclen] = secdata
|
||||
|
||||
|
||||
def get_exth_params(rec0):
|
||||
ebase = mobi_header_base + getint(rec0, mobi_header_length)
|
||||
if rec0[ebase:ebase+4] != b'EXTH':
|
||||
raise DualMetaFixException('EXTH tag not found where expected')
|
||||
elen = getint(rec0, ebase+4)
|
||||
enum = getint(rec0, ebase+8)
|
||||
rlen = len(rec0)
|
||||
return ebase, elen, enum, rlen
|
||||
|
||||
|
||||
def add_exth(rec0, exth_num, exth_bytes):
|
||||
ebase, elen, enum, rlen = get_exth_params(rec0)
|
||||
newrecsize = 8+len(exth_bytes)
|
||||
newrec0 = rec0[0:ebase+4]+struct.pack('>L', elen+newrecsize)+struct.pack('>L', enum+1)+struct.pack('>L', exth_num)\
|
||||
+ struct.pack('>L', newrecsize)+exth_bytes+rec0[ebase+12:]
|
||||
newrec0 = writeint(newrec0, title_offset, getint(newrec0, title_offset)+newrecsize)
|
||||
# keep constant record length by removing newrecsize null bytes from end
|
||||
sectail = newrec0[-newrecsize:]
|
||||
if sectail != b'\0'*newrecsize:
|
||||
raise DualMetaFixException('add_exth: trimmed non-null bytes at end of section')
|
||||
newrec0 = newrec0[0:rlen]
|
||||
return newrec0
|
||||
|
||||
|
||||
def read_exth(rec0, exth_num):
|
||||
exth_values = []
|
||||
ebase, elen, enum, rlen = get_exth_params(rec0)
|
||||
ebase += 12
|
||||
while enum > 0:
|
||||
exth_id = getint(rec0, ebase)
|
||||
if exth_id == exth_num:
|
||||
# We might have multiple exths, so build a list.
|
||||
exth_values.append(rec0[ebase+8:ebase+getint(rec0, ebase+4)])
|
||||
enum -= 1
|
||||
ebase = ebase+getint(rec0, ebase+4)
|
||||
return exth_values
|
||||
|
||||
|
||||
def del_exth(rec0, exth_num):
|
||||
ebase, elen, enum, rlen = get_exth_params(rec0)
|
||||
ebase_idx = ebase+12
|
||||
enum_idx = 0
|
||||
while enum_idx < enum:
|
||||
exth_id = getint(rec0, ebase_idx)
|
||||
exth_size = getint(rec0, ebase_idx+4)
|
||||
if exth_id == exth_num:
|
||||
newrec0 = rec0
|
||||
newrec0 = writeint(newrec0, title_offset, getint(newrec0, title_offset)-exth_size)
|
||||
newrec0 = newrec0[:ebase_idx]+newrec0[ebase_idx+exth_size:]
|
||||
newrec0 = newrec0[0:ebase+4]+struct.pack('>L', elen-exth_size)+struct.pack('>L', enum-1)+newrec0[ebase+12:]
|
||||
newrec0 += b'\0'*exth_size
|
||||
if rlen != len(newrec0):
|
||||
raise DualMetaFixException('del_exth: incorrect section size change')
|
||||
return newrec0
|
||||
enum_idx += 1
|
||||
ebase_idx = ebase_idx+exth_size
|
||||
return rec0
|
||||
|
||||
|
||||
class DualMobiMetaFix:
|
||||
def __init__(self, infile, outfile, asin):
|
||||
shutil.copyfile(infile, outfile)
|
||||
f = open(outfile, "r+b")
|
||||
self.datain = mmap.mmap(f.fileno(), 0)
|
||||
self.datain_rec0 = readsection(self.datain, 0)
|
||||
|
||||
# in the first mobi header
|
||||
# add 501 to "EBOK", add 113 as asin, add 504 as asin
|
||||
rec0 = self.datain_rec0
|
||||
rec0 = del_exth(rec0, 501)
|
||||
rec0 = del_exth(rec0, 113)
|
||||
rec0 = del_exth(rec0, 504)
|
||||
rec0 = add_exth(rec0, 501, b'EBOK')
|
||||
rec0 = add_exth(rec0, 113, asin)
|
||||
rec0 = add_exth(rec0, 504, asin)
|
||||
replacesection(self.datain, 0, rec0)
|
||||
|
||||
ver = getint(self.datain_rec0, mobi_version)
|
||||
self.combo = (ver != 8)
|
||||
if not self.combo:
|
||||
return
|
||||
|
||||
exth121 = read_exth(self.datain_rec0, 121)
|
||||
if len(exth121) == 0:
|
||||
self.combo = False
|
||||
return
|
||||
else:
|
||||
# only pay attention to first exth121
|
||||
# (there should only be one)
|
||||
datain_kf8, = struct.unpack_from('>L', exth121[0], 0)
|
||||
if datain_kf8 == 0xffffffff:
|
||||
self.combo = False
|
||||
return
|
||||
self.datain_kfrec0 = readsection(self.datain, datain_kf8)
|
||||
|
||||
# in the second header
|
||||
# add 501 to "EBOK", add 113 as asin, add 504 as asin
|
||||
rec0 = self.datain_kfrec0
|
||||
rec0 = del_exth(rec0, 501)
|
||||
rec0 = del_exth(rec0, 113)
|
||||
rec0 = del_exth(rec0, 504)
|
||||
rec0 = add_exth(rec0, 501, b'EBOK')
|
||||
rec0 = add_exth(rec0, 113, asin)
|
||||
rec0 = add_exth(rec0, 504, asin)
|
||||
replacesection(self.datain, datain_kf8, rec0)
|
||||
|
||||
self.datain.flush()
|
||||
self.datain.close()
|
||||
514
kcc/image.py
514
kcc/image.py
@@ -1,7 +1,7 @@
|
||||
# Copyright (C) 2010 Alex Yatskov
|
||||
# Copyright (C) 2011 Stanislav (proDOOMman) Kosolapov <prodoomman@gmail.com>
|
||||
# Copyright (C) 2012-2013 Ciro Mattia Gonano <ciromattia@gmail.com>
|
||||
# Copyright (C) 2013 Pawel Jastrzebski <pawelj@vulturis.eu>
|
||||
# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
|
||||
# Copyright (c) 2013-2015 Pawel Jastrzebski <pawelj@iosphe.re>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -16,17 +16,14 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
__license__ = 'ISC'
|
||||
__copyright__ = '2012-2013, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import os
|
||||
try:
|
||||
# noinspection PyUnresolvedReferences
|
||||
from PIL import Image, ImageOps, ImageStat, ImageChops
|
||||
except ImportError:
|
||||
print "ERROR: Pillow is not installed!"
|
||||
exit(1)
|
||||
from io import BytesIO
|
||||
from urllib.request import Request, urlopen
|
||||
from urllib.parse import quote
|
||||
from functools import reduce
|
||||
from PIL import Image, ImageOps, ImageStat, ImageChops
|
||||
from .shared import md5Checksum
|
||||
from . import __version__
|
||||
|
||||
|
||||
class ProfileData:
|
||||
@@ -84,236 +81,229 @@ class ProfileData:
|
||||
'K1': ("Kindle 1", (600, 670), Palette4, 1.8, (900, 1005)),
|
||||
'K2': ("Kindle 2", (600, 670), Palette15, 1.8, (900, 1005)),
|
||||
'K345': ("Kindle", (600, 800), Palette16, 1.8, (900, 1200)),
|
||||
'KHD': ("Kindle Paperwhite", (758, 1024), Palette16, 1.8, (1137, 1536)),
|
||||
'KDX': ("Kindle DX", (824, 1000), Palette15, 1.8, (1236, 1500)),
|
||||
'KDXG': ("Kindle DXG", (824, 1000), Palette16, 1.8, (1236, 1500)),
|
||||
'KF': ("Kindle Fire", (600, 1024), PalleteNull, 1.0, (900, 1536)),
|
||||
'KFHD': ("K. Fire HD 7\"", (800, 1280), PalleteNull, 1.0, (1200, 1920)),
|
||||
'KFHD8': ("K. Fire HD 8.9\"", (1200, 1920), PalleteNull, 1.0, (1800, 2880)),
|
||||
'KFHDX': ("K. Fire HDX 7\"", (1200, 1920), PalleteNull, 1.0, (1800, 2880)),
|
||||
'KFHDX8': ("K. Fire HDX 8.9\"", (1600, 2560), PalleteNull, 1.0, (2400, 3840)),
|
||||
'KDX': ("Kindle DX/DXG", (824, 1000), Palette16, 1.8, (1236, 1500)),
|
||||
'KPW': ("Kindle Paperwhite", (758, 1024), Palette16, 1.8, (1137, 1536)),
|
||||
'KV': ("Kindle Voyage", (1072, 1448), Palette16, 1.8, (1608, 2172)),
|
||||
'KFHD': ("K. Fire HD", (800, 1280), PalleteNull, 1.0, (1200, 1920)),
|
||||
'KFHDX': ("K. Fire HDX", (1200, 1920), PalleteNull, 1.0, (1800, 2880)),
|
||||
'KFHDX8': ("K. Fire HDX 8.9", (1600, 2560), PalleteNull, 1.0, (2400, 3840)),
|
||||
'KFA': ("Kindle for Android", (0, 0), PalleteNull, 1.0, (0, 0)),
|
||||
'KoMT': ("Kobo Mini/Touch", (600, 800), Palette16, 1.8, (900, 1200)),
|
||||
'KoG': ("Kobo Glow", (768, 1024), Palette16, 1.8, (1152, 1536)),
|
||||
'KoA': ("Kobo Aura", (758, 1024), Palette16, 1.8, (1137, 1536)),
|
||||
'KoAHD': ("Kobo Aura HD", (1080, 1440), Palette16, 1.8, (1620, 2160)),
|
||||
'KoAH2O': ("Kobo Aura H2O", (1080, 1430), Palette16, 1.8, (1620, 2145)),
|
||||
'OTHER': ("Other", (0, 0), Palette16, 1.8, (0, 0)),
|
||||
}
|
||||
|
||||
ProfileLabels = {
|
||||
"Kindle 1": 'K1',
|
||||
"Kindle 2": 'K2',
|
||||
"Kindle": 'K345',
|
||||
"Kindle Paperwhite": 'KHD',
|
||||
"Kindle DX": 'KDX',
|
||||
"Kindle DXG": 'KDXG',
|
||||
"Kindle Fire": 'KF',
|
||||
"K. Fire HD 7\"": 'KFHD',
|
||||
"K. Fire HD 8.9\"": 'KFHD8',
|
||||
"K. Fire HDX 7\"": 'KFHDX',
|
||||
"K. Fire HDX 8.9\"": 'KFHDX8',
|
||||
"Kindle for Android": 'KFA',
|
||||
"Other": 'OTHER'
|
||||
}
|
||||
|
||||
ProfileLabelsGUI = [
|
||||
"Kindle Paperwhite",
|
||||
"Kindle",
|
||||
"Separator",
|
||||
"K. Fire HD 7\"",
|
||||
"K. Fire HD 8.9\"",
|
||||
"K. Fire HDX 7\"",
|
||||
"K. Fire HDX 8.9\"",
|
||||
"Separator",
|
||||
"Kindle for Android",
|
||||
"Other",
|
||||
"Separator",
|
||||
"Kindle 1",
|
||||
"Kindle 2",
|
||||
"Kindle DX",
|
||||
"Kindle DXG",
|
||||
"Kindle Fire"
|
||||
]
|
||||
|
||||
|
||||
class ComicPage:
|
||||
def __init__(self, source, device):
|
||||
def __init__(self, source, options, original=None):
|
||||
try:
|
||||
self.profile_label, self.size, self.palette, self.gamma, self.panelviewsize = device
|
||||
self.profile_label, self.size, self.palette, self.gamma, self.panelviewsize = options.profileData
|
||||
except KeyError:
|
||||
raise RuntimeError('Unexpected output device %s' % device)
|
||||
# Detect corrupted files - Phase 2
|
||||
try:
|
||||
self.origFileName = source
|
||||
self.filename = os.path.basename(self.origFileName)
|
||||
self.image = Image.open(source)
|
||||
except IOError:
|
||||
raise RuntimeError('Cannot read image file %s' % source)
|
||||
# Detect corrupted files - Phase 3
|
||||
try:
|
||||
self.image = Image.open(source)
|
||||
self.image.verify()
|
||||
except:
|
||||
raise RuntimeError('Image file %s is corrupted' % source)
|
||||
# Detect corrupted files - Phase 4
|
||||
try:
|
||||
self.image = Image.open(source)
|
||||
self.image.load()
|
||||
except:
|
||||
raise RuntimeError('Image file %s is corrupted' % source)
|
||||
raise RuntimeError('Unexpected output device %s' % options.profileData)
|
||||
self.origFileName = source
|
||||
self.filename = os.path.basename(self.origFileName)
|
||||
self.image = Image.open(source)
|
||||
self.image = self.image.convert('RGB')
|
||||
self.rotated = None
|
||||
self.border = None
|
||||
self.noHPV = None
|
||||
self.noVPV = None
|
||||
self.fill = None
|
||||
|
||||
def saveToDir(self, targetdir, forcepng, color, wipe):
|
||||
try:
|
||||
suffix = ""
|
||||
if not color:
|
||||
self.image = self.image.convert('L') # convert to grayscale
|
||||
self.opt = options
|
||||
if original:
|
||||
self.second = True
|
||||
self.rotated = original.rotated
|
||||
self.border = original.border
|
||||
self.noHPV = original.noHPV
|
||||
self.noVPV = original.noVPV
|
||||
self.noPV = original.noPV
|
||||
self.noHQ = original.noHQ
|
||||
self.fill = original.fill
|
||||
self.color = original.color
|
||||
if self.rotated:
|
||||
suffix += "_kccrot"
|
||||
if wipe:
|
||||
os.remove(os.path.join(targetdir, self.filename))
|
||||
self.image = self.image.rotate(90, Image.BICUBIC, True)
|
||||
self.opt.quality = 0
|
||||
else:
|
||||
self.second = False
|
||||
self.rotated = None
|
||||
self.border = None
|
||||
self.noHPV = None
|
||||
self.noVPV = None
|
||||
self.noPV = None
|
||||
self.fill = None
|
||||
self.noHQ = False
|
||||
if options.webtoon:
|
||||
self.color = True
|
||||
else:
|
||||
suffix += "_kcchq"
|
||||
if self.noHPV:
|
||||
suffix += "_kccnh"
|
||||
if self.noVPV:
|
||||
suffix += "_kccnv"
|
||||
if self.border:
|
||||
suffix += "_kccx" + str(self.border[0]) + "_kccy" + str(self.border[1])
|
||||
if forcepng:
|
||||
self.image.save(os.path.join(targetdir, os.path.splitext(self.filename)[0] + suffix + ".png"), "PNG")
|
||||
self.color = self.isImageColor()
|
||||
|
||||
def saveToDir(self, targetdir):
|
||||
try:
|
||||
flags = []
|
||||
filename = os.path.join(targetdir, os.path.splitext(self.filename)[0]) + '-KCC'
|
||||
if not self.opt.forcecolor and not self.opt.forcepng:
|
||||
self.image = self.image.convert('L')
|
||||
if self.rotated:
|
||||
flags.append('Rotated')
|
||||
if self.noPV:
|
||||
flags.append('NoPanelView')
|
||||
else:
|
||||
self.image.save(os.path.join(targetdir, os.path.splitext(self.filename)[0] + suffix + ".jpg"), "JPEG")
|
||||
if self.noHPV:
|
||||
flags.append('NoHorizontalPanelView')
|
||||
if self.noVPV:
|
||||
flags.append('NoVerticalPanelView')
|
||||
if self.border:
|
||||
flags.append('Margins-' + str(self.border[0]) + '-' + str(self.border[1]) + '-'
|
||||
+ str(self.border[2]) + '-' + str(self.border[3]))
|
||||
if self.fill != 'white':
|
||||
flags.append('BlackFill')
|
||||
if self.opt.quality == 2:
|
||||
filename += '-HQ'
|
||||
if self.opt.forcepng:
|
||||
filename += '.png'
|
||||
self.image.save(filename, 'PNG', optimize=1)
|
||||
else:
|
||||
filename += '.jpg'
|
||||
self.image.save(filename, 'JPEG', optimize=1, quality=80)
|
||||
return [md5Checksum(filename), flags]
|
||||
except IOError as e:
|
||||
raise RuntimeError('Cannot write image in directory %s: %s' % (targetdir, e))
|
||||
|
||||
def optimizeImage(self, gamma):
|
||||
def autocontrastImage(self):
|
||||
gamma = self.opt.gamma
|
||||
if gamma < 0.1:
|
||||
gamma = self.gamma
|
||||
if self.gamma != 1.0 and self.color:
|
||||
gamma = 1.0
|
||||
if gamma == 1.0:
|
||||
self.image = ImageOps.autocontrast(self.image)
|
||||
else:
|
||||
self.image = ImageOps.autocontrast(Image.eval(self.image, lambda a: 255 * (a / 255.) ** gamma))
|
||||
|
||||
def quantizeImage(self):
|
||||
self.image = self.image.convert('L') # convert to grayscale
|
||||
self.image = self.image.convert("RGB") # convert back to RGB
|
||||
colors = len(self.palette) / 3
|
||||
colors = len(self.palette) // 3
|
||||
if colors < 256:
|
||||
self.palette += self.palette[:3] * (256 - colors)
|
||||
palImg = Image.new('P', (1, 1))
|
||||
palImg.putpalette(self.palette)
|
||||
self.image = self.image.convert('L')
|
||||
self.image = self.image.convert('RGB')
|
||||
# Quantize is deprecated but new function call it internally anyway...
|
||||
self.image = self.image.quantize(palette=palImg)
|
||||
|
||||
def resizeImage(self, upscale=False, stretch=False, bordersColor=None, qualityMode=0):
|
||||
method = Image.ANTIALIAS
|
||||
if bordersColor:
|
||||
fill = bordersColor
|
||||
def calculateBorder(self):
|
||||
if self.noPV:
|
||||
self.border = [0.0, 0.0, 0.0, 0.0]
|
||||
return
|
||||
if self.fill == 'white':
|
||||
border = ImageChops.invert(self.image).getbbox()
|
||||
else:
|
||||
border = self.image.getbbox()
|
||||
if self.opt.quality == 2:
|
||||
multiplier = 1.0
|
||||
else:
|
||||
multiplier = 1.5
|
||||
if border is not None:
|
||||
self.border = [round(float(border[0])/float(self.image.size[0])*150, 3),
|
||||
round(float(border[1])/float(self.image.size[1])*150, 3),
|
||||
round(float(self.image.size[0]-border[2])/float(self.image.size[0])*150, 3),
|
||||
round(float(self.image.size[1]-border[3])/float(self.image.size[1])*150, 3)]
|
||||
if int((border[2] - border[0]) * multiplier) < self.size[0] + 10:
|
||||
self.noHPV = True
|
||||
if int((border[3] - border[1]) * multiplier) < self.size[1] + 10:
|
||||
self.noVPV = True
|
||||
else:
|
||||
self.border = [0.0, 0.0, 0.0, 0.0]
|
||||
self.noHPV = True
|
||||
self.noVPV = True
|
||||
|
||||
def resizeImage(self):
|
||||
if self.opt.bordersColor:
|
||||
fill = self.opt.bordersColor
|
||||
else:
|
||||
fill = self.fill
|
||||
if qualityMode == 0:
|
||||
# Set target size
|
||||
if self.opt.quality == 0:
|
||||
size = (self.size[0], self.size[1])
|
||||
generateBorder = True
|
||||
elif qualityMode == 1:
|
||||
elif self.opt.quality == 1 and not self.opt.stretch and not self.opt.upscale and self.image.size[0] <=\
|
||||
self.size[0] and self.image.size[1] <= self.size[1]:
|
||||
size = (self.size[0], self.size[1])
|
||||
elif self.opt.quality == 1:
|
||||
# Forcing upscale to make sure that margins will be not too big
|
||||
if not self.opt.stretch:
|
||||
self.opt.upscale = True
|
||||
size = (self.panelviewsize[0], self.panelviewsize[1])
|
||||
generateBorder = True
|
||||
elif self.opt.quality == 2 and not self.opt.stretch and not self.opt.upscale and self.image.size[0] <=\
|
||||
self.size[0] and self.image.size[1] <= self.size[1]:
|
||||
# HQ version will not be needed
|
||||
self.noHQ = True
|
||||
return
|
||||
else:
|
||||
size = (self.panelviewsize[0], self.panelviewsize[1])
|
||||
generateBorder = False
|
||||
if self.image.size[0] <= self.size[0] and self.image.size[1] <= self.size[1]:
|
||||
if not upscale:
|
||||
borderw = (self.size[0] - self.image.size[0]) / 2
|
||||
borderh = (self.size[1] - self.image.size[1]) / 2
|
||||
self.image = ImageOps.expand(self.image, border=(borderw, borderh), fill=fill)
|
||||
if generateBorder:
|
||||
if (self.image.size[0]-(2*borderw))*1.5 < self.size[0]:
|
||||
self.noHPV = True
|
||||
if (self.image.size[1]-(2*borderh))*1.5 < self.size[1]:
|
||||
self.noVPV = True
|
||||
self.border = [int(round(float(borderw)/float(self.image.size[0])*100, 2)*100*1.5),
|
||||
int(round(float(borderh)/float(self.image.size[1])*100, 2)*100*1.5)]
|
||||
return self.image
|
||||
# If stretching is on - Resize without other considerations
|
||||
if self.opt.stretch:
|
||||
if self.image.size[0] <= size[0] and self.image.size[1] <= size[1]:
|
||||
method = Image.BICUBIC
|
||||
else:
|
||||
method = Image.BILINEAR
|
||||
if stretch: # If stretching call directly resize() without other considerations.
|
||||
method = Image.LANCZOS
|
||||
self.image = self.image.resize(size, method)
|
||||
if generateBorder:
|
||||
if fill == 'white':
|
||||
border = ImageOps.invert(self.image).getbbox()
|
||||
else:
|
||||
border = self.image.getbbox()
|
||||
if border is not None:
|
||||
if (border[2]-border[0])*1.5 < self.size[0]:
|
||||
self.noHPV = True
|
||||
if (border[3]-border[1])*1.5 < self.size[1]:
|
||||
self.noVPV = True
|
||||
self.border = [int(round(float(border[0])/float(self.image.size[0])*100, 2)*100*1.5),
|
||||
int(round(float(border[1])/float(self.image.size[1])*100, 2)*100*1.5)]
|
||||
else:
|
||||
self.border = [0, 0]
|
||||
self.noHPV = True
|
||||
self.noVPV = True
|
||||
return self.image
|
||||
ratioDev = float(self.size[0]) / float(self.size[1])
|
||||
return
|
||||
# If image is smaller than target resolution and upscale is off - Just expand it by adding margins
|
||||
if self.image.size[0] <= size[0] and self.image.size[1] <= size[1] and not self.opt.upscale:
|
||||
borderw = int((size[0] - self.image.size[0]) / 2)
|
||||
borderh = int((size[1] - self.image.size[1]) / 2)
|
||||
# PV is disabled when source image is smaller than device screen and upscale is off
|
||||
if self.image.size[0] <= self.size[0] and self.image.size[1] <= self.size[1]:
|
||||
self.noPV = True
|
||||
self.image = ImageOps.expand(self.image, border=(borderw, borderh), fill=fill)
|
||||
# Border can't be float so sometimes image might be 1px too small/large
|
||||
if self.image.size[0] != size[0] or self.image.size[1] != size[1]:
|
||||
self.image = ImageOps.fit(self.image, size, method=Image.BICUBIC, centering=(0.5, 0.5))
|
||||
return
|
||||
# Otherwise - Upscale/Downscale
|
||||
ratioDev = float(size[0]) / float(size[1])
|
||||
if (float(self.image.size[0]) / float(self.image.size[1])) < ratioDev:
|
||||
diff = int(self.image.size[1] * ratioDev) - self.image.size[0]
|
||||
self.image = ImageOps.expand(self.image, border=(diff / 2, 0), fill=fill)
|
||||
self.image = ImageOps.expand(self.image, border=(int(diff / 2), 0), fill=fill)
|
||||
elif (float(self.image.size[0]) / float(self.image.size[1])) > ratioDev:
|
||||
diff = int(self.image.size[0] / ratioDev) - self.image.size[1]
|
||||
self.image = ImageOps.expand(self.image, border=(0, diff / 2), fill=fill)
|
||||
self.image = ImageOps.expand(self.image, border=(0, int(diff / 2)), fill=fill)
|
||||
if self.image.size[0] <= size[0] and self.image.size[1] <= size[1]:
|
||||
method = Image.BICUBIC
|
||||
else:
|
||||
method = Image.LANCZOS
|
||||
self.image = ImageOps.fit(self.image, size, method=method, centering=(0.5, 0.5))
|
||||
if generateBorder:
|
||||
if fill == 'white':
|
||||
border = ImageOps.invert(self.image).getbbox()
|
||||
else:
|
||||
border = self.image.getbbox()
|
||||
if border is not None:
|
||||
if (border[2]-border[0])*1.5 < self.size[0]:
|
||||
self.noHPV = True
|
||||
if (border[3]-border[1])*1.5 < self.size[1]:
|
||||
self.noVPV = True
|
||||
self.border = [int(round(float(border[0])/float(self.image.size[0])*100, 2)*100*1.5),
|
||||
int(round(float(border[1])/float(self.image.size[1])*100, 2)*100*1.5)]
|
||||
else:
|
||||
self.border = [0, 0]
|
||||
self.noHPV = True
|
||||
self.noVPV = True
|
||||
return self.image
|
||||
return
|
||||
|
||||
def splitPage(self, targetdir, righttoleft=False, rotate=False):
|
||||
def splitPage(self, targetdir):
|
||||
width, height = self.image.size
|
||||
dstwidth, dstheight = self.size
|
||||
# Only split if origin is not oriented the same as target
|
||||
if (width > height) != (dstwidth > dstheight):
|
||||
if rotate:
|
||||
self.image = self.image.rotate(90)
|
||||
if self.opt.rotate:
|
||||
self.image = self.image.rotate(90, Image.BICUBIC, True)
|
||||
self.rotated = True
|
||||
return None
|
||||
else:
|
||||
self.rotated = False
|
||||
if width > height:
|
||||
# Source is landscape, so split by the width
|
||||
leftbox = (0, 0, width / 2, height)
|
||||
rightbox = (width / 2, 0, width, height)
|
||||
leftbox = (0, 0, int(width / 2), height)
|
||||
rightbox = (int(width / 2), 0, width, height)
|
||||
else:
|
||||
# Source is portrait and target is landscape, so split by the height
|
||||
leftbox = (0, 0, width, height / 2)
|
||||
rightbox = (0, height / 2, width, height)
|
||||
filename = os.path.splitext(self.filename)
|
||||
fileone = targetdir + '/' + filename[0] + '_kcca' + filename[1]
|
||||
filetwo = targetdir + '/' + filename[0] + '_kccb' + filename[1]
|
||||
leftbox = (0, 0, width, int(height / 2))
|
||||
rightbox = (0, int(height / 2), width, height)
|
||||
filename = os.path.splitext(self.filename)[0]
|
||||
fileone = targetdir + '/' + filename + '-AAA.png'
|
||||
filetwo = targetdir + '/' + filename + '-BBB.png'
|
||||
try:
|
||||
if righttoleft:
|
||||
if self.opt.righttoleft:
|
||||
pageone = self.image.crop(rightbox)
|
||||
pagetwo = self.image.crop(leftbox)
|
||||
else:
|
||||
pageone = self.image.crop(leftbox)
|
||||
pagetwo = self.image.crop(rightbox)
|
||||
pageone.save(fileone)
|
||||
pagetwo.save(filetwo)
|
||||
os.remove(self.origFileName)
|
||||
pageone.save(fileone, 'PNG', optimize=1)
|
||||
pagetwo.save(filetwo, 'PNG', optimize=1)
|
||||
except IOError as e:
|
||||
raise RuntimeError('Cannot write image in directory %s: %s' % (targetdir, e))
|
||||
return fileone, filetwo
|
||||
@@ -339,7 +329,7 @@ class ComicPage:
|
||||
oldStat = ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg))).var[0]
|
||||
diff += delta
|
||||
while ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg))).var[0] - oldStat > 0\
|
||||
and diff < heightImg / 4:
|
||||
and diff < heightImg // 4:
|
||||
oldStat = ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg))).var[0]
|
||||
diff += delta
|
||||
diff -= delta
|
||||
@@ -348,7 +338,7 @@ class ComicPage:
|
||||
oldStat = ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg,
|
||||
heightImg - pageNumberCut2))).var[0]
|
||||
while ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg - pageNumberCut2))).var[0]\
|
||||
< fixedThreshold + oldStat and diff < heightImg / 4:
|
||||
< fixedThreshold + oldStat and diff < heightImg // 4:
|
||||
diff += delta
|
||||
diff -= delta
|
||||
pageNumberCut3 = diff
|
||||
@@ -374,88 +364,156 @@ class ComicPage:
|
||||
else:
|
||||
diff = pageNumberCut1
|
||||
self.image = self.image.crop((0, 0, widthImg, heightImg - diff))
|
||||
return self.image
|
||||
|
||||
def cropWhiteSpace(self, threshold):
|
||||
def cropWhiteSpace(self):
|
||||
if ImageChops.invert(self.image).getbbox() is not None:
|
||||
widthImg, heightImg = self.image.size
|
||||
delta = 10
|
||||
diff = delta
|
||||
fixedThreshold = 0.1
|
||||
# top
|
||||
while ImageStat.Stat(self.image.crop((0, 0, widthImg, diff))).var[0] < threshold and diff < heightImg:
|
||||
while ImageStat.Stat(self.image.crop((0, 0, widthImg, diff))).var[0] < fixedThreshold and diff < heightImg:
|
||||
diff += delta
|
||||
diff -= delta
|
||||
# print "Top crop: %s"%diff
|
||||
self.image = self.image.crop((0, diff, widthImg, heightImg))
|
||||
widthImg, heightImg = self.image.size
|
||||
diff = delta
|
||||
# left
|
||||
while ImageStat.Stat(self.image.crop((0, 0, diff, heightImg))).var[0] < threshold and diff < widthImg:
|
||||
while ImageStat.Stat(self.image.crop((0, 0, diff, heightImg))).var[0] < fixedThreshold and diff < widthImg:
|
||||
diff += delta
|
||||
diff -= delta
|
||||
# print "Left crop: %s"%diff
|
||||
self.image = self.image.crop((diff, 0, widthImg, heightImg))
|
||||
widthImg, heightImg = self.image.size
|
||||
diff = delta
|
||||
# down
|
||||
while ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg))).var[0] < threshold\
|
||||
while ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg))).var[0] < fixedThreshold\
|
||||
and diff < heightImg:
|
||||
diff += delta
|
||||
diff -= delta
|
||||
# print "Down crop: %s"%diff
|
||||
self.image = self.image.crop((0, 0, widthImg, heightImg - diff))
|
||||
widthImg, heightImg = self.image.size
|
||||
diff = delta
|
||||
# right
|
||||
while ImageStat.Stat(self.image.crop((widthImg - diff, 0, widthImg, heightImg))).var[0] < threshold\
|
||||
while ImageStat.Stat(self.image.crop((widthImg - diff, 0, widthImg, heightImg))).var[0] < fixedThreshold\
|
||||
and diff < widthImg:
|
||||
diff += delta
|
||||
diff -= delta
|
||||
# print "Right crop: %s"%diff
|
||||
self.image = self.image.crop((0, 0, widthImg - diff, heightImg))
|
||||
# print "New size: %sx%s"%(self.image.size[0],self.image.size[1])
|
||||
return self.image
|
||||
|
||||
def getImageHistogram(self, image):
|
||||
histogram = image.histogram()
|
||||
RBGW = []
|
||||
pixelCount = 0
|
||||
for i in range(256):
|
||||
pixelCount += histogram[i] + histogram[256 + i] + histogram[512 + i]
|
||||
RBGW.append(histogram[i] + histogram[256 + i] + histogram[512 + i])
|
||||
white = 0
|
||||
black = 0
|
||||
for i in range(245, 256):
|
||||
white += RBGW[i]
|
||||
for i in range(11):
|
||||
black += RBGW[i]
|
||||
if black > white and black > pixelCount*0.5:
|
||||
return True
|
||||
if histogram[0] == 0:
|
||||
return -1
|
||||
elif histogram[255] == 0:
|
||||
return 1
|
||||
else:
|
||||
return False
|
||||
return 0
|
||||
|
||||
def getImageFill(self, isWebToon):
|
||||
fill = 0
|
||||
if isWebToon or self.rotated:
|
||||
fill += self.getImageHistogram(self.image.crop((0, 0, self.image.size[0], 5)))
|
||||
fill += self.getImageHistogram(self.image.crop((0, self.image.size[1]-5, self.image.size[0],
|
||||
self.image.size[1])))
|
||||
def getImageFill(self):
|
||||
bw = self.image.convert('L').point(lambda x: 0 if x < 128 else 255, '1')
|
||||
imageBoxA = bw.getbbox()
|
||||
imageBoxB = ImageChops.invert(bw).getbbox()
|
||||
if imageBoxA is None or imageBoxB is None:
|
||||
surfaceB, surfaceW = 0, 0
|
||||
diff = 0
|
||||
else:
|
||||
fill += self.getImageHistogram(self.image.crop((0, 0, 5, self.image.size[1])))
|
||||
fill += self.getImageHistogram(self.image.crop((self.image.size[0]-5, 0, self.image.size[0],
|
||||
self.image.size[1])))
|
||||
if fill == 2:
|
||||
self.fill = 'black'
|
||||
elif fill == 0:
|
||||
self.fill = 'white'
|
||||
surfaceB = (imageBoxA[2] - imageBoxA[0]) * (imageBoxA[3] - imageBoxA[1])
|
||||
surfaceW = (imageBoxB[2] - imageBoxB[0]) * (imageBoxB[3] - imageBoxB[1])
|
||||
diff = ((max(surfaceB, surfaceW) - min(surfaceB, surfaceW)) / min(surfaceB, surfaceW)) * 100
|
||||
if diff > 0.5:
|
||||
if surfaceW < surfaceB:
|
||||
self.fill = 'white'
|
||||
elif surfaceW > surfaceB:
|
||||
self.fill = 'black'
|
||||
else:
|
||||
fill = 0
|
||||
fill += self.getImageHistogram(self.image.crop((0, 0, 5, 5)))
|
||||
fill += self.getImageHistogram(self.image.crop((self.image.size[0]-5, 0, self.image.size[0], 5)))
|
||||
fill += self.getImageHistogram(self.image.crop((0, self.image.size[1]-5, 5, self.image.size[1])))
|
||||
fill += self.getImageHistogram(self.image.crop((self.image.size[0]-5, self.image.size[1]-5,
|
||||
self.image.size[0], self.image.size[1])))
|
||||
if fill > 1:
|
||||
startY = 0
|
||||
while startY < bw.size[1]:
|
||||
if startY + 5 > bw.size[1]:
|
||||
startY = bw.size[1] - 5
|
||||
fill += self.getImageHistogram(bw.crop((0, startY, bw.size[0], startY+5)))
|
||||
startY += 5
|
||||
startX = 0
|
||||
while startX < bw.size[0]:
|
||||
if startX + 5 > bw.size[0]:
|
||||
startX = bw.size[0] - 5
|
||||
fill += self.getImageHistogram(bw.crop((startX, 0, startX+5, bw.size[1])))
|
||||
startX += 5
|
||||
if fill > 0:
|
||||
self.fill = 'black'
|
||||
else:
|
||||
self.fill = 'white'
|
||||
self.fill = 'white'
|
||||
|
||||
def isImageColor(self):
|
||||
v = ImageStat.Stat(self.image).var
|
||||
isMonochromatic = reduce(lambda x, y: x and y < 0.005, v, True)
|
||||
if isMonochromatic:
|
||||
# Monochromatic
|
||||
return False
|
||||
else:
|
||||
if len(v) == 3:
|
||||
maxmin = abs(max(v) - min(v))
|
||||
if maxmin > 1000:
|
||||
# Color
|
||||
return True
|
||||
elif maxmin > 100:
|
||||
# Probably color
|
||||
return True
|
||||
else:
|
||||
# Grayscale
|
||||
return False
|
||||
elif len(v) == 1:
|
||||
# Black and white
|
||||
return False
|
||||
else:
|
||||
# Detection failed
|
||||
return False
|
||||
|
||||
|
||||
class Cover:
|
||||
def __init__(self, source, target, opt, tomeNumber):
|
||||
self.options = opt
|
||||
self.source = source
|
||||
self.target = target
|
||||
if tomeNumber == 0:
|
||||
self.tomeNumber = 1
|
||||
else:
|
||||
self.tomeNumber = tomeNumber
|
||||
if self.tomeNumber in self.options.remoteCovers:
|
||||
try:
|
||||
source = urlopen(Request(quote(self.options.remoteCovers[self.tomeNumber]).replace('%3A', ':', 1),
|
||||
headers={'User-Agent': 'KindleComicConverter/' + __version__})).read()
|
||||
self.image = Image.open(BytesIO(source))
|
||||
self.processExternal()
|
||||
except Exception:
|
||||
self.image = Image.open(source)
|
||||
self.processInternal()
|
||||
else:
|
||||
self.image = Image.open(source)
|
||||
self.processInternal()
|
||||
|
||||
def processInternal(self):
|
||||
self.image = self.image.convert('RGB')
|
||||
self.image = self.trim()
|
||||
self.save()
|
||||
|
||||
def processExternal(self):
|
||||
self.image = self.image.convert('RGB')
|
||||
self.image.thumbnail(self.options.profileData[1], Image.LANCZOS)
|
||||
self.save()
|
||||
|
||||
def trim(self):
|
||||
bg = Image.new(self.image.mode, self.image.size, self.image.getpixel((0, 0)))
|
||||
diff = ImageChops.difference(self.image, bg)
|
||||
diff = ImageChops.add(diff, diff, 2.0, -100)
|
||||
bbox = diff.getbbox()
|
||||
if bbox:
|
||||
return self.image.crop(bbox)
|
||||
else:
|
||||
return self.image
|
||||
|
||||
def save(self):
|
||||
try:
|
||||
self.image.save(self.target, "JPEG", optimize=1, quality=80)
|
||||
except IOError:
|
||||
raise RuntimeError('Failed to save cover')
|
||||
|
||||
@@ -1,384 +0,0 @@
|
||||
# Based on initial version of KindleUnpack. Copyright (C) 2009 Charles M. Hannum <root@ihack.net>
|
||||
# Improvements Copyright (C) 2009-2012 P. Durrant, K. Hendricks, S. Siebert, fandrieu, DiapDealer, nickredding
|
||||
# Copyright (C) 2013 Pawel Jastrzebski <pawelj@vulturis.eu>
|
||||
#
|
||||
# This program 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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
__license__ = 'ISC'
|
||||
__copyright__ = '2012-2013, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import struct
|
||||
# from uuid import uuid4
|
||||
|
||||
# important pdb header offsets
|
||||
unique_id_seed = 68
|
||||
number_of_pdb_records = 76
|
||||
|
||||
# important palmdoc header offsets
|
||||
book_length = 4
|
||||
book_record_count = 8
|
||||
first_pdb_record = 78
|
||||
|
||||
# important rec0 offsets
|
||||
length_of_book = 4
|
||||
mobi_header_base = 16
|
||||
mobi_header_length = 20
|
||||
mobi_type = 24
|
||||
mobi_version = 36
|
||||
first_non_text = 80
|
||||
title_offset = 84
|
||||
first_image_record = 108
|
||||
first_content_index = 192
|
||||
last_content_index = 194
|
||||
kf8_last_content_index = 192 # for KF8 mobi headers
|
||||
fcis_index = 200
|
||||
flis_index = 208
|
||||
srcs_index = 224
|
||||
srcs_count = 228
|
||||
primary_index = 244
|
||||
datp_index = 256
|
||||
huffoff = 112
|
||||
hufftbloff = 120
|
||||
|
||||
|
||||
def getint(datain, ofs, sz='L'):
|
||||
i, = struct.unpack_from('>'+sz, datain, ofs)
|
||||
return i
|
||||
|
||||
|
||||
def writeint(datain, ofs, n, length='L'):
|
||||
if length == 'L':
|
||||
return datain[:ofs]+struct.pack('>L', n)+datain[ofs+4:]
|
||||
else:
|
||||
return datain[:ofs]+struct.pack('>H', n)+datain[ofs+2:]
|
||||
|
||||
|
||||
def getsecaddr(datain, secno):
|
||||
nsec = getint(datain, number_of_pdb_records, 'H')
|
||||
assert secno >= 0 & secno < nsec, 'secno %d out of range (nsec=%d)' % (secno, nsec)
|
||||
secstart = getint(datain, first_pdb_record+secno*8)
|
||||
if secno == nsec-1:
|
||||
secend = len(datain)
|
||||
else:
|
||||
secend = getint(datain, first_pdb_record+(secno+1)*8)
|
||||
return secstart, secend
|
||||
|
||||
|
||||
def readsection(datain, secno):
|
||||
secstart, secend = getsecaddr(datain, secno)
|
||||
return datain[secstart:secend]
|
||||
|
||||
|
||||
def writesection(datain, secno, secdata): # overwrite, accounting for different length
|
||||
dataout = deletesectionrange(datain, secno, secno)
|
||||
return insertsection(dataout, secno, secdata)
|
||||
|
||||
|
||||
def nullsection(datain, secno): # make it zero-length without deleting it
|
||||
datalst = []
|
||||
nsec = getint(datain, number_of_pdb_records, 'H')
|
||||
secstart, secend = getsecaddr(datain, secno)
|
||||
zerosecstart, zerosecend = getsecaddr(datain, 0)
|
||||
dif = secend-secstart
|
||||
datalst.append(datain[:first_pdb_record])
|
||||
for i in range(0, secno+1):
|
||||
ofs, flgval = struct.unpack_from('>2L', datain, first_pdb_record+i*8)
|
||||
datalst.append(struct.pack('>L', ofs) + struct.pack('>L', flgval))
|
||||
for i in range(secno+1, nsec):
|
||||
ofs, flgval = struct.unpack_from('>2L', datain, first_pdb_record+i*8)
|
||||
ofs -= dif
|
||||
datalst.append(struct.pack('>L', ofs) + struct.pack('>L', flgval))
|
||||
lpad = zerosecstart - (first_pdb_record + 8*nsec)
|
||||
if lpad > 0:
|
||||
datalst.append('\0' * lpad)
|
||||
datalst.append(datain[zerosecstart: secstart])
|
||||
datalst.append(datain[secend:])
|
||||
dataout = "".join(datalst)
|
||||
return dataout
|
||||
|
||||
|
||||
def deletesectionrange(datain, firstsec, lastsec): # delete a range of sections
|
||||
datalst = []
|
||||
firstsecstart, firstsecend = getsecaddr(datain, firstsec)
|
||||
lastsecstart, lastsecend = getsecaddr(datain, lastsec)
|
||||
zerosecstart, zerosecend = getsecaddr(datain, 0)
|
||||
dif = lastsecend - firstsecstart + 8*(lastsec-firstsec+1)
|
||||
nsec = getint(datain, number_of_pdb_records, 'H')
|
||||
datalst.append(datain[:unique_id_seed])
|
||||
datalst.append(struct.pack('>L', 2*(nsec-(lastsec-firstsec+1))+1))
|
||||
datalst.append(datain[unique_id_seed+4:number_of_pdb_records])
|
||||
datalst.append(struct.pack('>H', nsec-(lastsec-firstsec+1)))
|
||||
newstart = zerosecstart - 8*(lastsec-firstsec+1)
|
||||
for i in range(0, firstsec):
|
||||
ofs, flgval = struct.unpack_from('>2L', datain, first_pdb_record+i*8)
|
||||
ofs -= 8 * (lastsec - firstsec + 1)
|
||||
datalst.append(struct.pack('>L', ofs) + struct.pack('>L', flgval))
|
||||
for i in range(lastsec+1, nsec):
|
||||
ofs, flgval = struct.unpack_from('>2L', datain, first_pdb_record+i*8)
|
||||
ofs -= dif
|
||||
flgval = 2*(i-(lastsec-firstsec+1))
|
||||
datalst.append(struct.pack('>L', ofs) + struct.pack('>L', flgval))
|
||||
lpad = newstart - (first_pdb_record + 8*(nsec - (lastsec - firstsec + 1)))
|
||||
if lpad > 0:
|
||||
datalst.append('\0' * lpad)
|
||||
datalst.append(datain[zerosecstart:firstsecstart])
|
||||
datalst.append(datain[lastsecend:])
|
||||
dataout = "".join(datalst)
|
||||
return dataout
|
||||
|
||||
|
||||
def insertsection(datain, secno, secdata): # insert a new section
|
||||
datalst = []
|
||||
nsec = getint(datain, number_of_pdb_records, 'H')
|
||||
secstart, secend = getsecaddr(datain, secno)
|
||||
zerosecstart, zerosecend = getsecaddr(datain, 0)
|
||||
dif = len(secdata)
|
||||
datalst.append(datain[:unique_id_seed])
|
||||
datalst.append(struct.pack('>L', 2*(nsec+1)+1))
|
||||
datalst.append(datain[unique_id_seed+4:number_of_pdb_records])
|
||||
datalst.append(struct.pack('>H', nsec+1))
|
||||
newstart = zerosecstart + 8
|
||||
for i in range(0, secno):
|
||||
ofs, flgval = struct.unpack_from('>2L', datain, first_pdb_record+i*8)
|
||||
ofs += 8
|
||||
datalst.append(struct.pack('>L', ofs) + struct.pack('>L', flgval))
|
||||
datalst.append(struct.pack('>L', secstart + 8) + struct.pack('>L', (2*secno)))
|
||||
for i in range(secno, nsec):
|
||||
ofs, flgval = struct.unpack_from('>2L', datain, first_pdb_record+i*8)
|
||||
ofs = ofs + dif + 8
|
||||
flgval = 2*(i+1)
|
||||
datalst.append(struct.pack('>L', ofs) + struct.pack('>L', flgval))
|
||||
lpad = newstart - (first_pdb_record + 8*(nsec + 1))
|
||||
if lpad > 0:
|
||||
datalst.append('\0' * lpad)
|
||||
datalst.append(datain[zerosecstart:secstart])
|
||||
datalst.append(secdata)
|
||||
datalst.append(datain[secstart:])
|
||||
dataout = "".join(datalst)
|
||||
return dataout
|
||||
|
||||
|
||||
def insertsectionrange(sectionsource, firstsec, lastsec, sectiontarget, targetsec): # insert a range of sections
|
||||
dataout = sectiontarget
|
||||
for idx in range(lastsec, firstsec-1, -1):
|
||||
dataout = insertsection(dataout, targetsec, readsection(sectionsource, idx))
|
||||
return dataout
|
||||
|
||||
|
||||
def get_exth_params(rec0):
|
||||
ebase = mobi_header_base + getint(rec0, mobi_header_length)
|
||||
elen = getint(rec0, ebase+4)
|
||||
enum = getint(rec0, ebase+8)
|
||||
return ebase, elen, enum
|
||||
|
||||
|
||||
def add_exth(rec0, exth_num, exth_bytes):
|
||||
ebase, elen, enum = get_exth_params(rec0)
|
||||
newrecsize = 8+len(exth_bytes)
|
||||
newrec0 = rec0[0:ebase+4]+struct.pack('>L', elen+newrecsize)+struct.pack('>L', enum+1) +\
|
||||
struct.pack('>L', exth_num) + struct.pack('>L', newrecsize)+exth_bytes+rec0[ebase+12:]
|
||||
newrec0 = writeint(newrec0, title_offset, getint(newrec0, title_offset)+newrecsize)
|
||||
return newrec0
|
||||
|
||||
|
||||
def read_exth(rec0, exth_num):
|
||||
exth_values = []
|
||||
ebase, elen, enum = get_exth_params(rec0)
|
||||
ebase += 12
|
||||
while enum > 0:
|
||||
exth_id = getint(rec0, ebase)
|
||||
if exth_id == exth_num:
|
||||
# We might have multiple exths, so build a list.
|
||||
exth_values.append(rec0[ebase+8:ebase+getint(rec0, ebase+4)])
|
||||
enum -= 1
|
||||
ebase = ebase+getint(rec0, ebase+4)
|
||||
return exth_values
|
||||
|
||||
|
||||
def write_exth(rec0, exth_num, exth_bytes):
|
||||
ebase, elen, enum = get_exth_params(rec0)
|
||||
ebase_idx = ebase+12
|
||||
enum_idx = enum
|
||||
while enum_idx > 0:
|
||||
exth_id = getint(rec0, ebase_idx)
|
||||
if exth_id == exth_num:
|
||||
dif = len(exth_bytes)+8-getint(rec0, ebase_idx+4)
|
||||
newrec0 = rec0
|
||||
if dif != 0:
|
||||
newrec0 = writeint(newrec0, title_offset, getint(newrec0, title_offset)+dif)
|
||||
return newrec0[:ebase+4]+struct.pack('>L', elen+len(exth_bytes)+8-getint(rec0, ebase_idx+4)) +\
|
||||
struct.pack('>L', enum)+rec0[ebase+12:ebase_idx+4] +\
|
||||
struct.pack('>L', len(exth_bytes)+8)+exth_bytes +\
|
||||
rec0[ebase_idx+getint(rec0, ebase_idx+4):]
|
||||
enum_idx -= 1
|
||||
ebase_idx = ebase_idx+getint(rec0, ebase_idx+4)
|
||||
return rec0
|
||||
|
||||
|
||||
def del_exth(rec0, exth_num):
|
||||
ebase, elen, enum = get_exth_params(rec0)
|
||||
ebase_idx = ebase+12
|
||||
enum_idx = 0
|
||||
while enum_idx < enum:
|
||||
exth_id = getint(rec0, ebase_idx)
|
||||
exth_size = getint(rec0, ebase_idx+4)
|
||||
if exth_id == exth_num:
|
||||
newrec0 = rec0
|
||||
newrec0 = writeint(newrec0, title_offset, getint(newrec0, title_offset)-exth_size)
|
||||
newrec0 = newrec0[:ebase_idx]+newrec0[ebase_idx+exth_size:]
|
||||
newrec0 = newrec0[0:ebase+4]+struct.pack('>L', elen-exth_size)+struct.pack('>L', enum-1)+newrec0[ebase+12:]
|
||||
return newrec0
|
||||
enum_idx += 1
|
||||
ebase_idx = ebase_idx+exth_size
|
||||
return rec0
|
||||
|
||||
|
||||
class mobi_split:
|
||||
def __init__(self, infile, newKindle):
|
||||
try:
|
||||
datain = open(infile, 'rb').read()
|
||||
datain_rec0 = readsection(datain, 0)
|
||||
ver = getint(datain_rec0, mobi_version)
|
||||
# fake_asin = str(uuid4())
|
||||
self.combo = (ver != 8)
|
||||
if not self.combo:
|
||||
return
|
||||
exth121 = read_exth(datain_rec0, 121)
|
||||
if len(exth121) == 0:
|
||||
self.combo = False
|
||||
return
|
||||
else:
|
||||
# only pay attention to first exth121
|
||||
# (there should only be one)
|
||||
datain_kf8, = struct.unpack_from('>L', exth121[0], 0)
|
||||
if datain_kf8 == 0xffffffff:
|
||||
self.combo = False
|
||||
return
|
||||
datain_kfrec0 = readsection(datain, datain_kf8)
|
||||
firstimage = getint(datain_rec0, first_image_record)
|
||||
lastimage = getint(datain_rec0, last_content_index, 'H')
|
||||
|
||||
if not newKindle:
|
||||
# create the standalone mobi7
|
||||
num_sec = getint(datain, number_of_pdb_records, 'H')
|
||||
# remove BOUNDARY up to but not including ELF record
|
||||
self.result_file = deletesectionrange(datain, datain_kf8-1, num_sec-2)
|
||||
# check if there are SRCS records and delete them
|
||||
srcs = getint(datain_rec0, srcs_index)
|
||||
num_srcs = getint(datain_rec0, srcs_count)
|
||||
if srcs != 0xffffffff and num_srcs > 0:
|
||||
self.result_file = deletesectionrange(self.result_file, srcs, srcs+num_srcs-1)
|
||||
datain_rec0 = writeint(datain_rec0, srcs_index, 0xffffffff)
|
||||
datain_rec0 = writeint(datain_rec0, srcs_count, 0)
|
||||
# reset the EXTH 121 KF8 Boundary meta data to 0xffffffff
|
||||
datain_rec0 = write_exth(datain_rec0, 121, struct.pack('>L', 0xffffffff))
|
||||
# datain_rec0 = del_exth(datain_rec0,121)
|
||||
# datain_rec0 = del_exth(datain_rec0,534)
|
||||
# don't remove the EXTH 125 KF8 Count of Resources, seems to be present in mobi6 files as well
|
||||
# set the EXTH 129 KF8 Masthead / Cover Image string to the null string
|
||||
datain_rec0 = write_exth(datain_rec0, 129, '')
|
||||
# don't remove the EXTH 131 KF8 Unidentified Count, seems to be present in mobi6 files as well
|
||||
|
||||
# Make sure we have an ASIN & cdeType set...
|
||||
# if len(read_exth(datain_rec0, 113)) == 0:
|
||||
# datain_rec0 = add_exth(datain_rec0, 113, fake_asin)
|
||||
# if len(read_exth(datain_rec0, 504)) == 0:
|
||||
# datain_rec0 = add_exth(datain_rec0, 504, fake_asin)
|
||||
if len(read_exth(datain_rec0, 501)) == 0:
|
||||
datain_rec0 = add_exth(datain_rec0, 501, b'EBOK')
|
||||
|
||||
# need to reset flags stored in 0x80-0x83
|
||||
# old mobi with exth: 0x50, mobi7 part with exth: 0x1850, mobi8 part with exth: 0x1050
|
||||
# Bit Flags
|
||||
# 0x1000 = Bit 12 indicates if embedded fonts are used or not
|
||||
# 0x0800 = means this Header points to *shared* images/resource/fonts ??
|
||||
# 0x0080 = unknown new flag, why is this now being set by Kindlegen 2.8?
|
||||
# 0x0040 = exth exists
|
||||
# 0x0010 = Not sure but this is always set so far
|
||||
fval, = struct.unpack_from('>L', datain_rec0, 0x80)
|
||||
# need to remove flag 0x0800 for KindlePreviewer 2.8 and unset Bit 12 for embedded fonts
|
||||
fval &= 0x07FF
|
||||
datain_rec0 = datain_rec0[:0x80] + struct.pack('>L', fval) + datain_rec0[0x84:]
|
||||
self.result_file = writesection(self.result_file, 0, datain_rec0)
|
||||
if lastimage == 0xffff:
|
||||
# find the lowest of the next sections and copy up to that.
|
||||
ofs_list = [(kf8_last_content_index, 'L'), (fcis_index, 'L'), (flis_index, 'L'), (datp_index, 'L'),
|
||||
(hufftbloff, 'L')]
|
||||
for ofs, sz in ofs_list:
|
||||
n = getint(datain_kfrec0, ofs, sz)
|
||||
if 0 < n < lastimage:
|
||||
lastimage = n-1
|
||||
|
||||
# Try to null out FONT and RES, but leave the (empty) PDB record so image refs remain valid
|
||||
for i in range(firstimage, lastimage):
|
||||
imgsec = readsection(self.result_file, i)
|
||||
if imgsec[0:4] in ['RESC', 'FONT']:
|
||||
self.result_file = nullsection(self.result_file, i)
|
||||
# mobi7 finished
|
||||
else:
|
||||
# create standalone mobi8
|
||||
self.result_file = deletesectionrange(datain, 0, datain_kf8-1)
|
||||
target = getint(datain_kfrec0, first_image_record)
|
||||
self.result_file = insertsectionrange(datain, firstimage, lastimage, self.result_file, target)
|
||||
datain_kfrec0 = readsection(self.result_file, 0)
|
||||
|
||||
# Only keep the correct EXTH 116 StartOffset, KG 2.5 carries over the one from the mobi7 part,
|
||||
# which then points at garbage in the mobi8 part, and confuses FW 3.4
|
||||
kf8starts = read_exth(datain_kfrec0, 116)
|
||||
# If we have multiple StartOffset, keep only the last one
|
||||
kf8start_count = len(kf8starts)
|
||||
while kf8start_count > 1:
|
||||
kf8start_count -= 1
|
||||
datain_kfrec0 = del_exth(datain_kfrec0, 116)
|
||||
|
||||
# update the EXTH 125 KF8 Count of Images/Fonts/Resources
|
||||
datain_kfrec0 = write_exth(datain_kfrec0, 125, struct.pack('>L', lastimage-firstimage+1))
|
||||
|
||||
# Same dance for the KF8, we want an ASIN & cdeType :)
|
||||
# if len(read_exth(datain_kfrec0, 113)) == 0:
|
||||
# datain_kfrec0 = add_exth(datain_kfrec0, 113, fake_asin)
|
||||
# if len(read_exth(datain_kfrec0, 504)) == 0:
|
||||
# datain_kfrec0 = add_exth(datain_kfrec0, 504, fake_asin)
|
||||
if len(read_exth(datain_kfrec0, 501)) == 0:
|
||||
datain_kfrec0 = add_exth(datain_kfrec0, 501, b'EBOK')
|
||||
|
||||
# need to reset flags stored in 0x80-0x83
|
||||
# old mobi with exth: 0x50, mobi7 part with exth: 0x1850, mobi8 part with exth: 0x1050
|
||||
# standalone mobi8 with exth: 0x0050
|
||||
# Bit Flags
|
||||
# 0x1000 = Bit 12 indicates if embedded fonts are used or not
|
||||
# 0x0800 = means this Header points to *shared* images/resource/fonts ??
|
||||
# 0x0080 = unknown new flag, why is this now being set by Kindlegen 2.8?
|
||||
# 0x0040 = exth exists
|
||||
# 0x0010 = Not sure but this is always set so far
|
||||
fval, = struct.unpack_from('>L', datain_kfrec0, 0x80)
|
||||
fval &= 0x1FFF
|
||||
fval |= 0x0800
|
||||
datain_kfrec0 = datain_kfrec0[:0x80] + struct.pack('>L', fval) + datain_kfrec0[0x84:]
|
||||
|
||||
# properly update other index pointers that have been shifted by the insertion of images
|
||||
ofs_list = [(kf8_last_content_index, 'L'), (fcis_index, 'L'), (flis_index, 'L'), (datp_index, 'L'),
|
||||
(hufftbloff, 'L')]
|
||||
for ofs, sz in ofs_list:
|
||||
n = getint(datain_kfrec0, ofs, sz)
|
||||
if n != 0xffffffff:
|
||||
datain_kfrec0 = writeint(datain_kfrec0, ofs, n+lastimage-firstimage+1, sz)
|
||||
self.result_file = writesection(self.result_file, 0, datain_kfrec0)
|
||||
# mobi8 finished
|
||||
except Exception:
|
||||
raise
|
||||
|
||||
def getResult(self):
|
||||
return self.result_file
|
||||
169
kcc/metadata.py
Normal file
169
kcc/metadata.py
Normal file
@@ -0,0 +1,169 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2013-2015 Pawel Jastrzebski <pawelj@iosphe.re>
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for
|
||||
# any purpose with or without fee is hereby granted, provided that the
|
||||
# above copyright notice and this permission notice appear in all
|
||||
# copies.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
# AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
|
||||
# OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
import os
|
||||
from xml.dom.minidom import parse, Document
|
||||
from re import compile
|
||||
from zipfile import is_zipfile, ZipFile, ZIP_DEFLATED
|
||||
from subprocess import STDOUT, PIPE
|
||||
from psutil import Popen
|
||||
from tempfile import mkdtemp
|
||||
from shutil import rmtree
|
||||
from .shared import removeFromZIP, check7ZFile as is_7zfile
|
||||
from . import rarfile
|
||||
|
||||
|
||||
class MetadataParser:
|
||||
def __init__(self, source):
|
||||
self.source = source
|
||||
self.data = {'Series': '',
|
||||
'Volume': '',
|
||||
'Number': '',
|
||||
'Writers': [],
|
||||
'Pencillers': [],
|
||||
'Inkers': [],
|
||||
'Colorists': [],
|
||||
'MUid': '',
|
||||
'Bookmarks': []}
|
||||
self.rawdata = None
|
||||
self.compressor = None
|
||||
if self.source.endswith('.xml'):
|
||||
self.rawdata = parse(self.source)
|
||||
self.parseXML()
|
||||
else:
|
||||
if is_zipfile(self.source):
|
||||
self.compressor = 'zip'
|
||||
with ZipFile(self.source) as zip_file:
|
||||
for member in zip_file.namelist():
|
||||
if member != 'ComicInfo.xml':
|
||||
continue
|
||||
with zip_file.open(member) as xml_file:
|
||||
self.rawdata = parse(xml_file)
|
||||
elif rarfile.is_rarfile(self.source):
|
||||
self.compressor = 'rar'
|
||||
with rarfile.RarFile(self.source) as rar_file:
|
||||
for member in rar_file.namelist():
|
||||
if member != 'ComicInfo.xml':
|
||||
continue
|
||||
with rar_file.open(member) as xml_file:
|
||||
self.rawdata = parse(xml_file)
|
||||
elif is_7zfile(self.source):
|
||||
self.compressor = '7z'
|
||||
workdir = mkdtemp('', 'KCC-TMP-')
|
||||
tmpXML = os.path.join(workdir, 'ComicInfo.xml')
|
||||
output = Popen('7za e "' + self.source + '" ComicInfo.xml -o"' + workdir + '"',
|
||||
stdout=PIPE, stderr=STDOUT, shell=True)
|
||||
extracted = False
|
||||
for line in output.stdout:
|
||||
if b"Everything is Ok" in line or b"No files to process" in line:
|
||||
extracted = True
|
||||
if not extracted:
|
||||
rmtree(workdir)
|
||||
raise OSError
|
||||
if os.path.isfile(tmpXML):
|
||||
self.rawdata = parse(tmpXML)
|
||||
rmtree(workdir)
|
||||
else:
|
||||
raise OSError
|
||||
if self.rawdata:
|
||||
self.parseXML()
|
||||
|
||||
def parseXML(self):
|
||||
if len(self.rawdata.getElementsByTagName('Series')) != 0:
|
||||
self.data['Series'] = self.rawdata.getElementsByTagName('Series')[0].firstChild.nodeValue
|
||||
if len(self.rawdata.getElementsByTagName('Volume')) != 0:
|
||||
self.data['Volume'] = self.rawdata.getElementsByTagName('Volume')[0].firstChild.nodeValue
|
||||
if len(self.rawdata.getElementsByTagName('Number')) != 0:
|
||||
self.data['Number'] = self.rawdata.getElementsByTagName('Number')[0].firstChild.nodeValue
|
||||
for field in ['Writer', 'Penciller', 'Inker', 'Colorist']:
|
||||
if len(self.rawdata.getElementsByTagName(field)) != 0:
|
||||
for person in self.rawdata.getElementsByTagName(field)[0].firstChild.nodeValue.split(', '):
|
||||
self.data[field + 's'].append(person)
|
||||
self.data[field + 's'] = list(set(self.data[field + 's']))
|
||||
self.data[field + 's'].sort()
|
||||
if len(self.rawdata.getElementsByTagName('ScanInformation')) != 0:
|
||||
coverId = compile('(MCD\\()(\\d+)(\\))')\
|
||||
.search(self.rawdata.getElementsByTagName('ScanInformation')[0].firstChild.nodeValue)
|
||||
if coverId:
|
||||
self.data['MUid'] = coverId.group(2)
|
||||
if len(self.rawdata.getElementsByTagName('Page')) != 0:
|
||||
for page in self.rawdata.getElementsByTagName('Page'):
|
||||
if 'Bookmark' in page.attributes and 'Image' in page.attributes:
|
||||
self.data['Bookmarks'].append((int(page.attributes['Image'].value),
|
||||
page.attributes['Bookmark'].value))
|
||||
|
||||
def saveXML(self):
|
||||
if self.rawdata:
|
||||
root = self.rawdata.getElementsByTagName('ComicInfo')[0]
|
||||
for row in (['Series', self.data['Series']], ['Volume', self.data['Volume']],
|
||||
['Number', self.data['Number']], ['Writer', ', '.join(self.data['Writers'])],
|
||||
['Penciller', ', '.join(self.data['Pencillers'])], ['Inker', ', '.join(self.data['Inkers'])],
|
||||
['Colorist', ', '.join(self.data['Colorists'])],
|
||||
['ScanInformation', 'MCD(' + self.data['MUid'] + ')' if self.data['MUid'] else '']):
|
||||
if self.rawdata.getElementsByTagName(row[0]):
|
||||
node = self.rawdata.getElementsByTagName(row[0])[0]
|
||||
if row[1]:
|
||||
node.firstChild.replaceWholeText(row[1])
|
||||
else:
|
||||
root.removeChild(node)
|
||||
elif row[1]:
|
||||
main = self.rawdata.createElement(row[0])
|
||||
root.appendChild(main)
|
||||
text = self.rawdata.createTextNode(row[1])
|
||||
main.appendChild(text)
|
||||
else:
|
||||
doc = Document()
|
||||
root = doc.createElement('ComicInfo')
|
||||
root.setAttribute('xmlns:xsd', 'http://www.w3.org/2001/XMLSchema')
|
||||
root.setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance')
|
||||
doc.appendChild(root)
|
||||
for row in (['Series', self.data['Series']], ['Volume', self.data['Volume']],
|
||||
['Number', self.data['Number']], ['Writer', ', '.join(self.data['Writers'])],
|
||||
['Penciller', ', '.join(self.data['Pencillers'])], ['Inker', ', '.join(self.data['Inkers'])],
|
||||
['Colorist', ', '.join(self.data['Colorists'])],
|
||||
['ScanInformation', 'MCD(' + self.data['MUid'] + ')' if self.data['MUid'] else '']):
|
||||
if row[1]:
|
||||
main = doc.createElement(row[0])
|
||||
root.appendChild(main)
|
||||
text = doc.createTextNode(row[1])
|
||||
main.appendChild(text)
|
||||
self.rawdata = doc
|
||||
if self.source.endswith('.xml'):
|
||||
with open(self.source, 'w', encoding='utf-8') as f:
|
||||
self.rawdata.writexml(f, encoding='utf-8')
|
||||
else:
|
||||
workdir = mkdtemp('', 'KCC-TMP-')
|
||||
tmpXML = os.path.join(workdir, 'ComicInfo.xml')
|
||||
with open(tmpXML, 'w', encoding='utf-8') as f:
|
||||
self.rawdata.writexml(f, encoding='utf-8')
|
||||
if is_zipfile(self.source):
|
||||
removeFromZIP(self.source, 'ComicInfo.xml')
|
||||
with ZipFile(self.source, mode='a', compression=ZIP_DEFLATED) as zip_file:
|
||||
zip_file.write(tmpXML, arcname=tmpXML.split(os.sep)[-1])
|
||||
elif rarfile.is_rarfile(self.source):
|
||||
raise NotImplementedError
|
||||
elif is_7zfile(self.source):
|
||||
output = Popen('7za a "' + self.source + '" "' + tmpXML + '"', stdout=PIPE, stderr=STDOUT, shell=True)
|
||||
extracted = False
|
||||
for line in output.stdout:
|
||||
if b"Everything is Ok" in line:
|
||||
extracted = True
|
||||
if not extracted:
|
||||
rmtree(workdir)
|
||||
raise OSError
|
||||
rmtree(workdir)
|
||||
@@ -1,5 +1,5 @@
|
||||
# Copyright (c) 2012-2013 Ciro Mattia Gonano <ciromattia@gmail.com>
|
||||
# Copyright (c) 2013 Pawel Jastrzebski <pawelj@vulturis.eu>
|
||||
# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
|
||||
# Copyright (c) 2013-2015 Pawel Jastrzebski <pawelj@iosphe.re>
|
||||
#
|
||||
# Based upon the code snippet by Ned Batchelder
|
||||
# (http://nedbatchelder.com/blog/200712/extracting_jpgs_from_pdfs.html)
|
||||
@@ -19,56 +19,50 @@
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
|
||||
__license__ = 'ISC'
|
||||
__copyright__ = '2012-2013, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import os
|
||||
from random import choice
|
||||
from string import ascii_uppercase, digits
|
||||
|
||||
|
||||
class PdfJpgExtract:
|
||||
def __init__(self, origFileName):
|
||||
self.origFileName = origFileName
|
||||
self.filename = os.path.splitext(origFileName)
|
||||
self.path = self.filename[0] + "-KCC-TMP"
|
||||
# noinspection PyUnusedLocal
|
||||
self.path = self.filename[0] + "-KCC-TMP-" + ''.join(choice(ascii_uppercase + digits) for x in range(3))
|
||||
|
||||
def getPath(self):
|
||||
return self.path
|
||||
|
||||
def extract(self):
|
||||
pdf = file(self.origFileName, "rb").read()
|
||||
|
||||
startmark = "\xff\xd8"
|
||||
pdf = open(self.origFileName, "rb").read()
|
||||
startmark = b"\xff\xd8"
|
||||
startfix = 0
|
||||
endmark = "\xff\xd9"
|
||||
endmark = b"\xff\xd9"
|
||||
endfix = 2
|
||||
i = 0
|
||||
|
||||
njpg = 0
|
||||
os.makedirs(self.path)
|
||||
while True:
|
||||
istream = pdf.find("stream", i)
|
||||
istream = pdf.find(b"stream", i)
|
||||
if istream < 0:
|
||||
break
|
||||
istart = pdf.find(startmark, istream, istream + 20)
|
||||
if istart < 0:
|
||||
i = istream + 20
|
||||
continue
|
||||
iend = pdf.find("endstream", istart)
|
||||
iend = pdf.find(b"endstream", istart)
|
||||
if iend < 0:
|
||||
raise Exception("Didn't find end of stream!")
|
||||
iend = pdf.find(endmark, iend - 20)
|
||||
if iend < 0:
|
||||
raise Exception("Didn't find end of JPG!")
|
||||
|
||||
istart += startfix
|
||||
iend += endfix
|
||||
print "JPG %d from %d to %d" % (njpg, istart, iend)
|
||||
jpg = pdf[istart:iend]
|
||||
jpgfile = file(self.path + "/jpg%d.jpg" % njpg, "wb")
|
||||
jpgfile = open(self.path + "/jpg%d.jpg" % njpg, "wb")
|
||||
jpgfile.write(jpg)
|
||||
jpgfile.close()
|
||||
|
||||
njpg += 1
|
||||
i = iend
|
||||
return self.path, njpg
|
||||
|
||||
232
kcc/rarfile.py
232
kcc/rarfile.py
@@ -1,6 +1,6 @@
|
||||
# rarfile.py
|
||||
#
|
||||
# Copyright (c) 2005-2013 Marko Kreen <markokr@gmail.com>
|
||||
# Copyright (c) 2005-2014 Marko Kreen <markokr@gmail.com>
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
@@ -74,7 +74,7 @@ For more details, refer to source.
|
||||
|
||||
"""
|
||||
|
||||
__version__ = '2.6'
|
||||
__version__ = '2.7-kcc'
|
||||
|
||||
# export only interesting items
|
||||
__all__ = ['is_rarfile', 'RarInfo', 'RarFile', 'RarExtFile']
|
||||
@@ -108,6 +108,8 @@ if sys.hexversion < 0x3000000:
|
||||
# py2.6 has broken bytes()
|
||||
def bytes(s, enc):
|
||||
return str(s)
|
||||
else:
|
||||
unicode = str
|
||||
|
||||
# see if compat bytearray() is needed
|
||||
try:
|
||||
@@ -176,8 +178,25 @@ EXTRACT_ARGS = ('x', '-y', '-idq')
|
||||
#: args for testrar()
|
||||
TEST_ARGS = ('t', '-idq')
|
||||
|
||||
#
|
||||
# Allow use of tool that is not compatible with unrar.
|
||||
#
|
||||
# By default use 'bsdtar' which is 'tar' program that
|
||||
# sits on top of libarchive.
|
||||
#
|
||||
# Problems with libarchive RAR backend:
|
||||
# - Does not support solid archives.
|
||||
# - Does not support password-protected archives.
|
||||
#
|
||||
|
||||
ALT_TOOL = 'bsdtar'
|
||||
ALT_OPEN_ARGS = ('-x', '--to-stdout', '-f')
|
||||
ALT_EXTRACT_ARGS = ('-x', '-f')
|
||||
ALT_TEST_ARGS = ('-t', '-f')
|
||||
ALT_CHECK_ARGS = ('--help',)
|
||||
|
||||
#: whether to speed up decompression by using tmp archive
|
||||
USE_EXTRACT_HACK = 1
|
||||
USE_EXTRACT_HACK = 0
|
||||
|
||||
#: limit the filesize for tmp archive usage
|
||||
HACK_SIZE_LIMIT = 20*1024*1024
|
||||
@@ -188,10 +207,6 @@ NEED_COMMENTS = 1
|
||||
#: whether to convert comments to unicode strings
|
||||
UNICODE_COMMENTS = 0
|
||||
|
||||
#: When RAR is corrupt, stopping on bad header is better
|
||||
#: On unknown/misparsed RAR headers reporting is better
|
||||
REPORT_BAD_HEADER = 0
|
||||
|
||||
#: Convert RAR time tuple into datetime() object
|
||||
USE_DATETIME = 0
|
||||
|
||||
@@ -280,6 +295,7 @@ RAR_M5 = 0x35
|
||||
##
|
||||
|
||||
RAR_ID = bytes("Rar!\x1a\x07\x00", 'ascii')
|
||||
RAR5_ID = bytes("Rar!\x1a\x07\x01", 'ascii')
|
||||
ZERO = bytes("\0", 'ascii')
|
||||
EMPTY = bytes("", 'ascii')
|
||||
|
||||
@@ -338,12 +354,19 @@ class RarUnknownError(RarExecError):
|
||||
"""Unknown exit code"""
|
||||
class RarSignalExit(RarExecError):
|
||||
"""Unrar exited with signal"""
|
||||
class RarCannotExec(RarExecError):
|
||||
"""Executable not found."""
|
||||
|
||||
|
||||
def is_rarfile(fn):
|
||||
def is_rarfile(xfile):
|
||||
'''Check quickly whether file is rar archive.'''
|
||||
buf = open(fn, "rb").read(len(RAR_ID))
|
||||
return buf == RAR_ID
|
||||
fd = XFile(xfile)
|
||||
buf = fd.read(len(RAR_ID))
|
||||
fd.close()
|
||||
if buf == RAR_ID or buf == RAR5_ID:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
class RarInfo(object):
|
||||
@@ -453,11 +476,12 @@ class RarFile(object):
|
||||
'''Parse RAR structure, provide access to files in archive.
|
||||
'''
|
||||
|
||||
#: Archive comment. Byte string or None. Use UNICODE_COMMENTS
|
||||
#: Archive comment. Byte string or None. Use :data:`UNICODE_COMMENTS`
|
||||
#: to get automatic decoding to unicode.
|
||||
comment = None
|
||||
|
||||
def __init__(self, rarfile, mode="r", charset=None, info_callback=None, crc_check = True):
|
||||
def __init__(self, rarfile, mode="r", charset=None, info_callback=None,
|
||||
crc_check = True, errors = "stop"):
|
||||
"""Open and parse a RAR archive.
|
||||
|
||||
Parameters:
|
||||
@@ -472,6 +496,9 @@ class RarFile(object):
|
||||
debug callback, gets to see all archive entries.
|
||||
crc_check
|
||||
set to False to disable CRC checks
|
||||
errors
|
||||
Either "stop" to quietly stop parsing on errors,
|
||||
or "strict" to raise errors. Default is "stop".
|
||||
"""
|
||||
self.rarfile = rarfile
|
||||
self.comment = None
|
||||
@@ -485,6 +512,13 @@ class RarFile(object):
|
||||
self._crc_check = crc_check
|
||||
self._vol_list = []
|
||||
|
||||
if errors == "stop":
|
||||
self._strict = False
|
||||
elif errors == "strict":
|
||||
self._strict = True
|
||||
else:
|
||||
raise ValueError("Invalid value for 'errors' parameter.")
|
||||
|
||||
self._main = None
|
||||
|
||||
if mode != "r":
|
||||
@@ -548,8 +582,9 @@ class RarFile(object):
|
||||
'''Returns file-like object (:class:`RarExtFile`),
|
||||
from where the data can be read.
|
||||
|
||||
The object implements io.RawIOBase interface, so it can
|
||||
be further wrapped with io.BufferedReader and io.TextIOWrapper.
|
||||
The object implements :class:`io.RawIOBase` interface, so it can
|
||||
be further wrapped with :class:`io.BufferedReader`
|
||||
and :class:`io.TextIOWrapper`.
|
||||
|
||||
On older Python where io module is not available, it implements
|
||||
only .read(), .seek(), .tell() and .close() methods.
|
||||
@@ -588,16 +623,19 @@ class RarFile(object):
|
||||
psw = None
|
||||
|
||||
# is temp write usable?
|
||||
if not USE_EXTRACT_HACK or not self._main:
|
||||
use_hack = 1
|
||||
if not self._main:
|
||||
use_hack = 0
|
||||
elif self._main.flags & (RAR_MAIN_SOLID | RAR_MAIN_PASSWORD):
|
||||
use_hack = 0
|
||||
elif inf.flags & (RAR_FILE_SPLIT_BEFORE | RAR_FILE_SPLIT_AFTER):
|
||||
use_hack = 0
|
||||
elif is_filelike(self.rarfile):
|
||||
pass
|
||||
elif inf.file_size > HACK_SIZE_LIMIT:
|
||||
use_hack = 0
|
||||
else:
|
||||
use_hack = 1
|
||||
elif not USE_EXTRACT_HACK:
|
||||
use_hack = 0
|
||||
|
||||
# now extract
|
||||
if inf.compress_type == RAR_M0 and (inf.flags & RAR_FILE_PASSWORD) == 0:
|
||||
@@ -610,7 +648,7 @@ class RarFile(object):
|
||||
def read(self, fname, psw = None):
|
||||
"""Return uncompressed data for archive entry.
|
||||
|
||||
For longer files using .open() may be better idea.
|
||||
For longer files using :meth:`RarFile.open` may be better idea.
|
||||
|
||||
Parameters:
|
||||
|
||||
@@ -641,7 +679,7 @@ class RarFile(object):
|
||||
Parameters:
|
||||
|
||||
member
|
||||
filename or RarInfo instance
|
||||
filename or :class:`RarInfo` instance
|
||||
path
|
||||
optional destination path
|
||||
pwd
|
||||
@@ -661,7 +699,7 @@ class RarFile(object):
|
||||
path
|
||||
optional destination path
|
||||
members
|
||||
optional filename or RarInfo instance list to extract
|
||||
optional filename or :class:`RarInfo` instance list to extract
|
||||
pwd
|
||||
optional password to use
|
||||
"""
|
||||
@@ -678,19 +716,29 @@ class RarFile(object):
|
||||
"""Let 'unrar' test the archive.
|
||||
"""
|
||||
cmd = [UNRAR_TOOL] + list(TEST_ARGS)
|
||||
if self._password is not None:
|
||||
cmd.append('-p' + self._password)
|
||||
else:
|
||||
cmd.append('-p-')
|
||||
add_password_arg(cmd, self._password)
|
||||
cmd.append(self.rarfile)
|
||||
p = custom_popen(cmd)
|
||||
output = p.communicate()[0]
|
||||
check_returncode(p, output)
|
||||
|
||||
def strerror(self):
|
||||
"""Return error string if parsing failed,
|
||||
or None if no problems.
|
||||
"""
|
||||
return self._parse_error
|
||||
|
||||
##
|
||||
## private methods
|
||||
##
|
||||
|
||||
def _set_error(self, msg, *args):
|
||||
if args:
|
||||
msg = msg % args
|
||||
self._parse_error = msg
|
||||
if self._strict:
|
||||
raise BadRarFile(msg)
|
||||
|
||||
# store entry
|
||||
def _process_entry(self, item):
|
||||
if item.type == RAR_BLOCK_FILE:
|
||||
@@ -738,10 +786,10 @@ class RarFile(object):
|
||||
self._fd = None
|
||||
|
||||
def _parse_real(self):
|
||||
fd = open(self.rarfile, "rb")
|
||||
fd = XFile(self.rarfile)
|
||||
self._fd = fd
|
||||
id = fd.read(len(RAR_ID))
|
||||
if id != RAR_ID:
|
||||
if id != RAR_ID and id != RAR5_ID:
|
||||
raise NotRarFile("Not a Rar archive: "+self.rarfile)
|
||||
|
||||
volume = 0 # first vol (.rar) is 0
|
||||
@@ -757,9 +805,13 @@ class RarFile(object):
|
||||
if not h:
|
||||
if more_vols:
|
||||
volume += 1
|
||||
volfile = self._next_volname(volfile)
|
||||
fd.close()
|
||||
fd = open(volfile, "rb")
|
||||
try:
|
||||
volfile = self._next_volname(volfile)
|
||||
fd = XFile(volfile)
|
||||
except IOError:
|
||||
self._set_error("Cannot open next volume: %s", volfile)
|
||||
break
|
||||
self._fd = fd
|
||||
more_vols = 0
|
||||
endarc = 0
|
||||
@@ -824,8 +876,7 @@ class RarFile(object):
|
||||
# now read actual header
|
||||
return self._parse_block_header(fd)
|
||||
except struct.error:
|
||||
if REPORT_BAD_HEADER:
|
||||
raise BadRarFile('Broken header in RAR file')
|
||||
self._set_error('Broken header in RAR file')
|
||||
return None
|
||||
|
||||
# common header
|
||||
@@ -852,8 +903,7 @@ class RarFile(object):
|
||||
|
||||
# unexpected EOF?
|
||||
if len(h.header_data) != h.header_size:
|
||||
if REPORT_BAD_HEADER:
|
||||
raise BadRarFile('Unexpected EOF when reading header')
|
||||
self._set_error('Unexpected EOF when reading header')
|
||||
return None
|
||||
|
||||
# block has data assiciated with it?
|
||||
@@ -896,18 +946,9 @@ class RarFile(object):
|
||||
if h.header_crc == calc_crc:
|
||||
return h
|
||||
|
||||
# need to panic?
|
||||
if REPORT_BAD_HEADER:
|
||||
xlen = len(crcdat)
|
||||
crcdat = h.header_data[2:]
|
||||
msg = 'Header CRC error (%02x): exp=%x got=%x (xlen = %d)' % ( h.type, h.header_crc, calc_crc, xlen )
|
||||
xlen = len(crcdat)
|
||||
while xlen >= S_BLK_HDR.size - 2:
|
||||
crc = crc32(crcdat[:xlen]) & 0xFFFF
|
||||
if crc == h.header_crc:
|
||||
msg += ' / crc match, xlen = %d' % xlen
|
||||
xlen -= 1
|
||||
raise BadRarFile(msg)
|
||||
# header parsing failed.
|
||||
self._set_error('Header CRC error (%02x): exp=%x got=%x (xlen = %d)',
|
||||
h.type, h.header_crc, calc_crc, len(crcdat))
|
||||
|
||||
# instead panicing, send eof
|
||||
return None
|
||||
@@ -1053,6 +1094,8 @@ class RarFile(object):
|
||||
|
||||
# given current vol name, construct next one
|
||||
def _next_volname(self, volfile):
|
||||
if is_filelike(volfile):
|
||||
raise IOError("Working on single FD")
|
||||
if self._main.flags & RAR_MAIN_NEWNUMBERING:
|
||||
return self._next_newvol(volfile)
|
||||
return self._next_oldvol(volfile)
|
||||
@@ -1093,7 +1136,7 @@ class RarFile(object):
|
||||
BSIZE = 32*1024
|
||||
|
||||
size = inf.compress_size + inf.header_size
|
||||
rf = open(inf.volume_file, "rb", 0)
|
||||
rf = XFile(inf.volume_file, 0)
|
||||
rf.seek(inf.header_offset)
|
||||
|
||||
tmpfd, tmpname = mkstemp(suffix='.rar')
|
||||
@@ -1125,7 +1168,7 @@ class RarFile(object):
|
||||
def _read_comment_v3(self, inf, psw=None):
|
||||
|
||||
# read data
|
||||
rf = open(inf.volume_file, "rb")
|
||||
rf = XFile(inf.volume_file)
|
||||
rf.seek(inf.file_offset)
|
||||
data = rf.read(inf.compress_size)
|
||||
rf.close()
|
||||
@@ -1146,9 +1189,10 @@ class RarFile(object):
|
||||
|
||||
# extract using unrar
|
||||
def _open_unrar(self, rarfile, inf, psw = None, tmpfile = None):
|
||||
if is_filelike(rarfile):
|
||||
raise ValueError("Cannot use unrar directly on memory buffer")
|
||||
cmd = [UNRAR_TOOL] + list(OPEN_ARGS)
|
||||
if psw is not None:
|
||||
cmd.append("-p" + psw)
|
||||
add_password_arg(cmd, psw)
|
||||
cmd.append(rarfile)
|
||||
|
||||
# not giving filename avoids encoding related problems
|
||||
@@ -1180,10 +1224,7 @@ class RarFile(object):
|
||||
|
||||
# pasoword
|
||||
psw = psw or self._password
|
||||
if psw is not None:
|
||||
cmd.append('-p' + psw)
|
||||
else:
|
||||
cmd.append('-p-')
|
||||
add_password_arg(cmd, psw)
|
||||
|
||||
# rar file
|
||||
cmd.append(self.rarfile)
|
||||
@@ -1553,7 +1594,7 @@ class DirectReader(RarExtFile):
|
||||
RarExtFile._open(self)
|
||||
|
||||
self.volfile = self.inf.volume_file
|
||||
self.fd = open(self.volfile, "rb", 0)
|
||||
self.fd = XFile(self.volfile, 0)
|
||||
self.fd.seek(self.inf.header_offset, 0)
|
||||
self.cur = self.rf._parse_header(self.fd)
|
||||
self.cur_avail = self.cur.add_size
|
||||
@@ -1705,10 +1746,47 @@ class HeaderDecrypt:
|
||||
|
||||
return res
|
||||
|
||||
# handle (filename|filelike) object
|
||||
class XFile(object):
|
||||
__slots__ = ('_fd', '_need_close')
|
||||
def __init__(self, xfile, bufsize = 1024):
|
||||
if is_filelike(xfile):
|
||||
self._need_close = False
|
||||
self._fd = xfile
|
||||
self._fd.seek(0)
|
||||
else:
|
||||
self._need_close = True
|
||||
self._fd = open(xfile, 'rb', bufsize)
|
||||
def read(self, n=None):
|
||||
return self._fd.read(n)
|
||||
def tell(self):
|
||||
return self._fd.tell()
|
||||
def seek(self, ofs, whence=0):
|
||||
return self._fd.seek(ofs, whence)
|
||||
def readinto(self, dst):
|
||||
return self._fd.readinto(dst)
|
||||
def close(self):
|
||||
if self._need_close:
|
||||
self._fd.close()
|
||||
def __enter__(self):
|
||||
return self
|
||||
def __exit__(self, typ, val, tb):
|
||||
self.close()
|
||||
|
||||
##
|
||||
## Utility functions
|
||||
##
|
||||
|
||||
def is_filelike(obj):
|
||||
if isinstance(obj, str) or isinstance(obj, unicode):
|
||||
return False
|
||||
res = True
|
||||
for a in ('read', 'tell', 'seek'):
|
||||
res = res and hasattr(obj, a)
|
||||
if not res:
|
||||
raise ValueError("Invalid object passed as file")
|
||||
return True
|
||||
|
||||
def rar3_s2k(psw, salt):
|
||||
"""String-to-key hash for RAR3."""
|
||||
|
||||
@@ -1768,10 +1846,7 @@ def rar_decompress(vers, meth, data, declen=0, flags=0, crc=0, psw=None, salt=No
|
||||
tmpf.close()
|
||||
|
||||
cmd = [UNRAR_TOOL] + list(OPEN_ARGS)
|
||||
if psw is not None and (flags & RAR_FILE_PASSWORD):
|
||||
cmd.append("-p" + psw)
|
||||
else:
|
||||
cmd.append("-p-")
|
||||
add_password_arg(cmd, psw, (flags & RAR_FILE_PASSWORD))
|
||||
cmd.append(tmpname)
|
||||
|
||||
p = custom_popen(cmd)
|
||||
@@ -1840,22 +1915,43 @@ def custom_popen(cmd):
|
||||
except OSError:
|
||||
ex = sys.exc_info()[1]
|
||||
if ex.errno == errno.ENOENT:
|
||||
raise RarExecError("Unrar not installed? (rarfile.UNRAR_TOOL=%r)" % UNRAR_TOOL)
|
||||
raise RarCannotExec("Unrar not installed? (rarfile.UNRAR_TOOL=%r)" % UNRAR_TOOL)
|
||||
raise
|
||||
return p
|
||||
|
||||
def custom_check(cmd, ignore_retcode=False):
|
||||
"""Run command, collect output, raise error if needed."""
|
||||
p = custom_popen(cmd)
|
||||
out, err = p.communicate()
|
||||
if p.returncode and not ignore_retcode:
|
||||
raise RarExecError("Check-run failed")
|
||||
return out
|
||||
|
||||
def add_password_arg(cmd, psw, required=False):
|
||||
"""Append password switch to commandline."""
|
||||
if UNRAR_TOOL == ALT_TOOL:
|
||||
return
|
||||
if psw is not None:
|
||||
cmd.append('-p' + psw)
|
||||
else:
|
||||
cmd.append('-p-')
|
||||
|
||||
def check_returncode(p, out):
|
||||
"""Raise exception according to unrar exit code"""
|
||||
|
||||
code = p.returncode
|
||||
if code == 0:
|
||||
return
|
||||
if code == 9:
|
||||
return
|
||||
|
||||
# map return code to exception class
|
||||
errmap = [None,
|
||||
RarWarning, RarFatalError, RarCRCError, RarLockedArchiveError,
|
||||
RarWriteError, RarOpenError, RarUserError, RarMemoryError,
|
||||
RarCreateError, RarNoFilesError] # codes from rar.txt
|
||||
if UNRAR_TOOL == ALT_TOOL:
|
||||
errmap = [None]
|
||||
if code > 0 and code < len(errmap):
|
||||
exc = errmap[code]
|
||||
elif code == 255:
|
||||
@@ -1873,3 +1969,23 @@ def check_returncode(p, out):
|
||||
|
||||
raise exc(msg)
|
||||
|
||||
#
|
||||
# Check if unrar works
|
||||
#
|
||||
|
||||
try:
|
||||
# does UNRAR_TOOL work?
|
||||
custom_check([UNRAR_TOOL], True)
|
||||
except RarCannotExec:
|
||||
try:
|
||||
# does ALT_TOOL work?
|
||||
custom_check([ALT_TOOL] + list(ALT_CHECK_ARGS), True)
|
||||
# replace config
|
||||
UNRAR_TOOL = ALT_TOOL
|
||||
OPEN_ARGS = ALT_OPEN_ARGS
|
||||
EXTRACT_ARGS = ALT_EXTRACT_ARGS
|
||||
TEST_ARGS = ALT_TEST_ARGS
|
||||
except RarCannotExec:
|
||||
# no usable tool, only uncompressed archives work
|
||||
pass
|
||||
|
||||
|
||||
157
kcc/shared.py
Normal file
157
kcc/shared.py
Normal file
@@ -0,0 +1,157 @@
|
||||
# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
|
||||
# Copyright (c) 2013-2015 Pawel Jastrzebski <pawelj@iosphe.re>
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for
|
||||
# any purpose with or without fee is hereby granted, provided that the
|
||||
# above copyright notice and this permission notice appear in all
|
||||
# copies.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
# AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
|
||||
# OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
|
||||
import os
|
||||
from hashlib import md5
|
||||
from html.parser import HTMLParser
|
||||
from distutils.version import StrictVersion
|
||||
from time import sleep
|
||||
from shutil import rmtree, move
|
||||
from tempfile import mkdtemp
|
||||
from zipfile import ZipFile, ZIP_DEFLATED
|
||||
from re import split
|
||||
try:
|
||||
from scandir import walk
|
||||
except ImportError:
|
||||
walk = None
|
||||
|
||||
|
||||
class HTMLStripper(HTMLParser):
|
||||
def __init__(self):
|
||||
HTMLParser.__init__(self)
|
||||
self.reset()
|
||||
self.strict = False
|
||||
self.convert_charrefs = True
|
||||
self.fed = []
|
||||
|
||||
def handle_data(self, d):
|
||||
self.fed.append(d)
|
||||
|
||||
def get_data(self):
|
||||
return ''.join(self.fed)
|
||||
|
||||
|
||||
def getImageFileName(imgfile):
|
||||
name, ext = os.path.splitext(imgfile)
|
||||
ext = ext.lower()
|
||||
if name.startswith('.') or (ext != '.png' and ext != '.jpg' and ext != '.jpeg' and ext != '.gif'):
|
||||
return None
|
||||
return [name, ext]
|
||||
|
||||
|
||||
def walkSort(dirnames, filenames):
|
||||
convert = lambda text: int(text) if text.isdigit() else text
|
||||
alphanum_key = lambda key: [convert(c) for c in split('([0-9]+)', key)]
|
||||
dirnames.sort(key=lambda name: alphanum_key(name.lower()))
|
||||
filenames.sort(key=lambda name: alphanum_key(name.lower()))
|
||||
return dirnames, filenames
|
||||
|
||||
|
||||
def walkLevel(some_dir, level=1):
|
||||
some_dir = some_dir.rstrip(os.path.sep)
|
||||
assert os.path.isdir(some_dir)
|
||||
num_sep = some_dir.count(os.path.sep)
|
||||
for root, dirs, files in walk(some_dir):
|
||||
dirs, files = walkSort(dirs, files)
|
||||
yield root, dirs, files
|
||||
num_sep_this = root.count(os.path.sep)
|
||||
if num_sep + level <= num_sep_this:
|
||||
del dirs[:]
|
||||
|
||||
|
||||
def md5Checksum(filePath):
|
||||
with open(filePath, 'rb') as fh:
|
||||
m = md5()
|
||||
while True:
|
||||
data = fh.read(8192)
|
||||
if not data:
|
||||
break
|
||||
m.update(data)
|
||||
return m.hexdigest()
|
||||
|
||||
|
||||
def check7ZFile(filePath):
|
||||
with open(filePath, 'rb') as fh:
|
||||
header = fh.read(6)
|
||||
return header == b"7z\xbc\xaf'\x1c"
|
||||
|
||||
|
||||
def saferReplace(old, new):
|
||||
for x in range(5):
|
||||
try:
|
||||
os.replace(old, new)
|
||||
except PermissionError:
|
||||
sleep(5)
|
||||
else:
|
||||
break
|
||||
else:
|
||||
raise PermissionError
|
||||
|
||||
|
||||
def removeFromZIP(zipfname, *filenames):
|
||||
tempdir = mkdtemp('', 'KCC-TMP-')
|
||||
try:
|
||||
tempname = os.path.join(tempdir, 'KCC-TMP.zip')
|
||||
with ZipFile(zipfname, 'r') as zipread:
|
||||
with ZipFile(tempname, 'w', compression=ZIP_DEFLATED) as zipwrite:
|
||||
for item in zipread.infolist():
|
||||
if item.filename not in filenames:
|
||||
zipwrite.writestr(item, zipread.read(item.filename))
|
||||
move(tempname, zipfname)
|
||||
finally:
|
||||
rmtree(tempdir)
|
||||
|
||||
|
||||
# noinspection PyUnresolvedReferences
|
||||
def dependencyCheck(level):
|
||||
missing = []
|
||||
if level > 2:
|
||||
try:
|
||||
from PyQt5.QtCore import qVersion as qtVersion
|
||||
if StrictVersion('5.2.0') > StrictVersion(qtVersion()):
|
||||
missing.append('PyQt 5.2.0+')
|
||||
except ImportError:
|
||||
missing.append('PyQt 5.2.0+')
|
||||
if level > 1:
|
||||
try:
|
||||
from psutil import __version__ as psutilVersion
|
||||
if StrictVersion('2.0.0') > StrictVersion(psutilVersion):
|
||||
missing.append('psutil 2.0.0+')
|
||||
except ImportError:
|
||||
missing.append('psutil 2.0.0+')
|
||||
try:
|
||||
from slugify import __version__ as slugifyVersion
|
||||
if StrictVersion('0.1.0') > StrictVersion(slugifyVersion):
|
||||
missing.append('python-slugify 0.1.0+')
|
||||
except ImportError:
|
||||
missing.append('python-slugify 0.1.0+')
|
||||
try:
|
||||
from PIL import PILLOW_VERSION as pillowVersion
|
||||
if StrictVersion('2.7.0') > StrictVersion(pillowVersion):
|
||||
missing.append('Pillow 2.7.0+')
|
||||
except ImportError:
|
||||
missing.append('Pillow 2.7.0+')
|
||||
try:
|
||||
from scandir import __version__ as scandirVersion
|
||||
if StrictVersion('0.9') > StrictVersion(scandirVersion):
|
||||
missing.append('scandir 0.9+')
|
||||
except ImportError:
|
||||
missing.append('scandir 0.9+')
|
||||
if len(missing) > 0:
|
||||
print('ERROR: ' + ', '.join(missing) + ' is not installed!')
|
||||
exit(1)
|
||||
229
other/InstallWarning.rtf
Normal file
229
other/InstallWarning.rtf
Normal file
@@ -0,0 +1,229 @@
|
||||
{\rtf1\adeflang1025\ansi\ansicpg1250\uc1\adeff0\deff0\stshfdbch0\stshfloch31506\stshfhich31506\stshfbi31506\deflang1045\deflangfe1045\themelang1045\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;}
|
||||
{\f0\fbidi \froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f37\fbidi \fswiss\fcharset238\fprq2{\*\panose 020f0502020204030204}Calibri;}
|
||||
{\flomajor\f31500\fbidi \froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fdbmajor\f31501\fbidi \froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;}
|
||||
{\fhimajor\f31502\fbidi \fswiss\fcharset238\fprq2{\*\panose 020f0302020204030204}Calibri Light;}{\fbimajor\f31503\fbidi \froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;}
|
||||
{\flominor\f31504\fbidi \froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fdbminor\f31505\fbidi \froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;}
|
||||
{\fhiminor\f31506\fbidi \fswiss\fcharset238\fprq2{\*\panose 020f0502020204030204}Calibri;}{\fbiminor\f31507\fbidi \froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f41\fbidi \froman\fcharset0\fprq2 Times New Roman;}
|
||||
{\f40\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\f42\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f43\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f44\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
|
||||
{\f45\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f46\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f47\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f41\fbidi \froman\fcharset0\fprq2 Times New Roman;}
|
||||
{\f40\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\f42\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f43\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f44\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
|
||||
{\f45\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f46\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f47\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f411\fbidi \fswiss\fcharset0\fprq2 Calibri;}
|
||||
{\f410\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\f412\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\f413\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\f416\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}
|
||||
{\f417\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\flomajor\f31510\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
|
||||
{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
|
||||
{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
|
||||
{\fdbmajor\f31520\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}
|
||||
{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
|
||||
{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhimajor\f31530\fbidi \fswiss\fcharset0\fprq2 Calibri Light;}
|
||||
{\fhimajor\f31529\fbidi \fswiss\fcharset204\fprq2 Calibri Light Cyr;}{\fhimajor\f31531\fbidi \fswiss\fcharset161\fprq2 Calibri Light Greek;}{\fhimajor\f31532\fbidi \fswiss\fcharset162\fprq2 Calibri Light Tur;}
|
||||
{\fhimajor\f31535\fbidi \fswiss\fcharset186\fprq2 Calibri Light Baltic;}{\fhimajor\f31536\fbidi \fswiss\fcharset163\fprq2 Calibri Light (Vietnamese);}{\fbimajor\f31540\fbidi \froman\fcharset0\fprq2 Times New Roman;}
|
||||
{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}
|
||||
{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}
|
||||
{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\flominor\f31550\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
|
||||
{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
|
||||
{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
|
||||
{\fdbminor\f31560\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}
|
||||
{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
|
||||
{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31570\fbidi \fswiss\fcharset0\fprq2 Calibri;}
|
||||
{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}
|
||||
{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\fbiminor\f31580\fbidi \froman\fcharset0\fprq2 Times New Roman;}
|
||||
{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}
|
||||
{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}
|
||||
{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;
|
||||
\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;
|
||||
\chyperlink\ctint255\cshade255\red5\green99\blue193;\cfollowedhyperlink\ctint255\cshade255\red149\green79\blue114;}{\*\defchp \f31506\fs22\lang1045\langfe1033\langfenp1033 }{\*\defpap \ql \li0\ri0\sa160\sl259\slmult1
|
||||
\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\sa160\sl259\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0
|
||||
\f31506\fs22\lang1045\langfe1033\cgrid\langnp1045\langfenp1033 \snext0 \sqformat \spriority0 Normal;}{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\*
|
||||
\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa160\sl259\slmult1
|
||||
\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31506\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1045\langfe1033\cgrid\langnp1045\langfenp1033 \snext11 \ssemihidden \sunhideused Normal Table;}{\*\cs15 \additive
|
||||
\rtlch\fcs1 \af0 \ltrch\fcs0 \ul\cf17 \sbasedon10 \sunhideused \styrsid3562894 Hyperlink;}{\*\cs16 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \ul\cf18 \sbasedon10 \ssemihidden \sunhideused \styrsid7678248 FollowedHyperlink;}}{\*\rsidtbl \rsid1081196
|
||||
\rsid3146412\rsid3562894\rsid5731975\rsid7678248\rsid9265883\rsid11107340\rsid12600926\rsid13187577}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info
|
||||
{\author Pawe\'b3 Jastrz\'eabski}{\operator Pawe\'b3 Jastrz\'eabski}{\creatim\yr2013\mo10\dy29\hr15\min17}{\revtim\yr2013\mo10\dy29\hr15\min28}{\version8}{\edmins8}{\nofpages1}{\nofwords33}{\nofchars200}{\nofcharsws232}{\vern57435}}{\*\xmlnstbl {\xmlns1 h
|
||||
ttp://schemas.microsoft.com/office/word/2003/wordml}}\paperw11906\paperh16838\margl1417\margr1417\margt1417\margb1417\gutter0\ltrsect
|
||||
\deftab708\widowctrl\ftnbj\aenddoc\hyphhotz425\trackmoves0\trackformatting1\donotembedsysfont1\relyonvml0\donotembedlingdata0\grfdocevents0\validatexml1\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0
|
||||
\showxmlerrors1\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\formshade\horzdoc\dgmargin\dghspace180\dgvspace180\dghorigin1417\dgvorigin1417\dghshow1\dgvshow1
|
||||
\jexpand\viewkind1\viewscale100\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel\wrppunct
|
||||
\asianbrkrule\rsidroot11107340\newtblstyruls\nogrowautofit\usenormstyforlist\noindnmbrts\felnbrelev\nocxsptable\indrlsweleven\noafcnsttbl\afelev\utinl\hwelev\spltpgpar\notcvasp\notbrkcnstfrctbl\notvatxbx\krnprsnet\cachedcolbal \nouicompat \fet0
|
||||
{\*\wgrffmtfilter 2450}\nofeaturethrottle1\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\headery708\footery708\colsx708\endnhere\sectlinegrid360\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2
|
||||
\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6
|
||||
\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang
|
||||
{\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\ql \li0\ri0\sa160\sl259\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0
|
||||
\f31506\fs22\lang1045\langfe1033\cgrid\langnp1045\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \b\fs52\cf6\lang2057\langfe1033\langnp2057\insrsid3562894\charrsid3562894 Warning!}{\rtlch\fcs1 \af0 \ltrch\fcs0
|
||||
\b\fs52\cf6\lang2057\langfe1033\langnp2057\insrsid13187577\charrsid3562894
|
||||
\par }{\rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \fs28\lang2057\langfe1033\langnp2057\insrsid1081196 Creation of}{\rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \fs28\lang2057\langfe1033\langnp2057\insrsid3562894\charrsid12600926 }{\rtlch\fcs1 \af0\afs24 \ltrch\fcs0
|
||||
\b\fs28\lang2057\langfe1033\langnp2057\insrsid3562894\charrsid12600926 MOBI}{\rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \fs28\lang2057\langfe1033\langnp2057\insrsid3562894\charrsid12600926 files }{\rtlch\fcs1 \af0\afs24 \ltrch\fcs0
|
||||
\fs28\lang2057\langfe1033\langnp2057\insrsid5731975\charrsid12600926 require additional software.}{\rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \fs28\lang2057\langfe1033\langnp2057\insrsid3562894\charrsid12600926
|
||||
\par }{\rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \b\fs28\lang2057\langfe1033\langnp2057\insrsid3562894\charrsid12600926 Please download: }{\field\flddirty{\*\fldinst {\rtlch\fcs1 \af0\afs24 \ltrch\fcs0
|
||||
\b\fs28\lang2057\langfe1033\langnp2057\insrsid3562894\charrsid12600926 HYPERLINK "http://www.amazon.com/gp/feature.html?ie=UTF8&docId=1000765211" }{\rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \b\fs28\lang2057\langfe1033\langnp2057\insrsid3562894\charrsid12600926
|
||||
{\*\datafield
|
||||
00d0c9ea79f9bace118c8200aa004ba90b0200000003000000e0c9ea79f9bace118c8200aa004ba90b9600000068007400740070003a002f002f007700770077002e0061006d0061007a006f006e002e0063006f006d002f00670070002f0066006500610074007500720065002e00680074006d006c003f00690065003d00
|
||||
5500540046003800260064006f006300490064003d0031003000300030003700360035003200310031000000795881f43b1d7f48af2c825dc485276300000000a5ab000000}}}{\fldrslt {\rtlch\fcs1 \af0\afs24 \ltrch\fcs0
|
||||
\cs15\b\fs28\ul\cf17\lang2057\langfe1033\langnp2057\insrsid3562894\charrsid12600926 KindleGen}}}\sectd \ltrsect\linex0\headery708\footery708\colsx708\endnhere\sectlinegrid360\sectdefaultcl\sftnbj {\rtlch\fcs1 \af0\afs24 \ltrch\fcs0
|
||||
\b\fs28\lang2057\langfe1033\langnp2057\insrsid3562894\charrsid12600926
|
||||
\par }{\rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \fs28\lang2057\langfe1033\langnp2057\insrsid3562894\charrsid12600926 And place }{\rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \i\fs28\lang2057\langfe1033\langnp2057\insrsid5731975\charrsid12600926 kindlegen.exe}{\rtlch\fcs1
|
||||
\af0\afs24 \ltrch\fcs0 \fs28\lang2057\langfe1033\langnp2057\insrsid5731975\charrsid12600926 }{\rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \fs28\lang2057\langfe1033\langnp2057\insrsid3562894\charrsid12600926 inside }{\rtlch\fcs1 \af0\afs24 \ltrch\fcs0
|
||||
\b\fs28\lang2057\langfe1033\langnp2057\insrsid3146412\charrsid3146412 Kindle}{\rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \b\fs28\lang2057\langfe1033\langnp2057\insrsid3146412 }{\rtlch\fcs1 \af0\afs24 \ltrch\fcs0
|
||||
\b\fs28\lang2057\langfe1033\langnp2057\insrsid3146412\charrsid3146412 Comic}{\rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \b\fs28\lang2057\langfe1033\langnp2057\insrsid3146412 }{\rtlch\fcs1 \af0\afs24 \ltrch\fcs0
|
||||
\b\fs28\lang2057\langfe1033\langnp2057\insrsid3146412\charrsid3146412 Converter}{\rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \b\fs28\lang2057\langfe1033\langnp2057\insrsid3146412 }{\rtlch\fcs1 \af0\afs24 \ltrch\fcs0
|
||||
\fs28\lang2057\langfe1033\langnp2057\insrsid3562894\charrsid12600926 directory.
|
||||
\par }{\*\themedata 504b030414000600080000002100e9de0fbfff0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb4ec3301045f748fc83e52d4a
|
||||
9cb2400825e982c78ec7a27cc0c8992416c9d8b2a755fbf74cd25442a820166c2cd933f79e3be372bd1f07b5c3989ca74aaff2422b24eb1b475da5df374fd9ad
|
||||
5689811a183c61a50f98f4babebc2837878049899a52a57be670674cb23d8e90721f90a4d2fa3802cb35762680fd800ecd7551dc18eb899138e3c943d7e503b6
|
||||
b01d583deee5f99824e290b4ba3f364eac4a430883b3c092d4eca8f946c916422ecab927f52ea42b89a1cd59c254f919b0e85e6535d135a8de20f20b8c12c3b0
|
||||
0c895fcf6720192de6bf3b9e89ecdbd6596cbcdd8eb28e7c365ecc4ec1ff1460f53fe813d3cc7f5b7f020000ffff0300504b030414000600080000002100a5d6
|
||||
a7e7c0000000360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4f
|
||||
c7060abb0884a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b6309512
|
||||
0f88d94fbc52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462
|
||||
a1a82fe353bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f746865
|
||||
6d652f7468656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b
|
||||
4b0d592c9c070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b
|
||||
4757e8d3f729e245eb2b260a0238fd010000ffff0300504b030414000600080000002100b7e72e45da060000a81a0000160000007468656d652f7468656d652f
|
||||
7468656d65312e786d6cec595d8b1b37147d2ff43f0cf3eef86bc61f4bbcc11edbd936bbc9123b2979d4dab24759cdc88ce4dd981028c963a1509a963e34d0b7
|
||||
3e94b68104fa92fe9a6d53da14f2177aa5198f255bdb4d96149692352c63f9dcaba37bef9cab195dbe722fa2ce114e386171cb2d5f2ab90e8e476c4ce269cbbd
|
||||
35ec171aaec3058ac788b218b7dc05e6ee95ed0f3fb88cb6448823ec807dccb750cb0d85986d158b7c04c3885f62331cc36f13964448c0d7645a1c27e818fc46
|
||||
b45829956ac50891d875621481db3d2616c7ce0c1d122ce6ce8dc9848cb0bbbd9ca44761a658703930a2c9404e8133cb7d65a39b8c0fcb12c8173ca089738468
|
||||
cb8569c7ec7888ef09d7a1880bf8a1e596d49f5bdcbe5c445b991115a7d86a767df597d96506e3c38a9a33991ee4937a9eefd5dab97f05a06213d7abf76abd5a
|
||||
ee4f01d068040b4eb9e83efd4eb3d3f533ac064a2f2dbebbf56eb56ce035ffd50dce6d5f7e0cbc02a5febd0d7cbf1f40140dbc02a5787f03ef79f54ae0197805
|
||||
4af1b50d7cbdd4ee7a7503af402125f1e106bae4d7aac172b53964c2e88e15def4bd7ebd92395fa1a01af22293534c582cce28b908dd65491f70124f9120b123
|
||||
16333c4123a8ed005172901067974c43a8bf198a1987e152a5d42f55e1bffc78ea4a05066d61a4594b7a40886f0c495a0e1f2564265aeec7e0d5d520af5ffcf8
|
||||
fac533e7e4e1f39387bf9c3c7a74f2f0e7d49161b583e2a96ef5eafb2ffe7ef2a9f3d7b3ef5e3dfeca8ee73afef79f3efbedd72fed4058e92a042fbf7efac7f3
|
||||
a72fbff9fccf1f1e5be0ed041de8f021893077aee363e7268b60612a0426737c90bc9dc5304444b768c7538e622467b1f8ef89d0405f5f208a2cb80e3623783b
|
||||
01a5b101afceef1a8407613217c4e2f15a1819c03dc6688725d6285c937369611ecee3a97df264aee36e2274649b3b40b191dfde7c064a4b6c2e83101b34f729
|
||||
8a059ae2180b47fec60e31b6acee0e21465cf7c828619c4d847387381d44ac21199203a39a56463b2482bc2c6c0421df466cf66e3b1d466dabeee22313097705
|
||||
a216f2434c8d305e457381229bcb218aa81ef05d24421bc9c12219e9b81e1790e929a6cce98d31e7369b1b09ac574bfa3590177bdaf7e8223291892087369fbb
|
||||
88311dd965874188a2990d3b2071a8633fe28750a2c8d967c206df63e61d22bf431e507c6aba6fc31e409fe06c35b805caaa5bac0a44fe324f2cb9bc8a9951bf
|
||||
83059d20aca406f4dfd0f388c4678afb9aacfbffadac8390befcf68965551755d0db09b1de513b6b327e1a6e5dbc03968cc9c5d7ee2e9ac7fb186e97cd06f65e
|
||||
badf4bb7fbbf97eed3eee7772fd82b8d06f9965bc574c7aef6efd159dbf709a174201614ef72b583e7d0a0c67d1894e6ea8116e74f75b3102ee50d0df318b869
|
||||
82948d9330f10911e1204433d8e6975de964ca33d753eecc1887ddbf1ab6fa96783a8ff6d8387d782d97e5836aaa211c89d578c9cfc7e18943a4e85a7df54096
|
||||
bb576ca7eaf9794940dabe0d096d329344d542a2be1c9441524feb10340b09b5b277c2a26961d190ee97a9da6001d4f2acc00eca817d57cbf53d30012378b042
|
||||
148f659ed2542fb3ab92f92e337d5a308d0a80edc4b20256996e4aaea72e4fae2e2db537c8b441422b3793848a8c6a653c44639c55a71c7d131a6f9bebe62aa5
|
||||
063d190a351f94d68a46bdf16f2cce9b6bb05bd7061aeb4a4163e7b8e5d6aa3e94cc08cd5aee049efee1329a41ed70b9f345740a2fd64622496ff8f328cb2ce1
|
||||
a28b7898065c894eaa061111387128895aae5c7e9e061a2b0d51dcca1510840b4bae09b272d1c841d2cd24e3c9048f849e766d44463afd0a0a9f6a85f557657e
|
||||
7eb0b4647348f7201c1f3b07749edc4450627ebd2c0338261c5e0295d3688e09bcdccc856c557f6b8d29935dfdeda2aaa1741cd15988b28ea28b790a57529ed3
|
||||
51dff21868dfb2354340b590648df0602a1bac1e54a39be65d23e5706ad73ddb48464e13cd55cf345445764dbb8a19332cdbc05a2ccfd7e43556cb1083a6e91d
|
||||
3e95ee75c96d2eb56e6d9f90770908781e3f4bd77d8386a0515b4d6650938c3765586a76366af68ee502cfa0f6264d4253fddad2ed5adcf21e619d0e06cfd5f9
|
||||
c16ebd6a6168b2dc5eaa48ab4311fdbc821ddc05f1e8c2bbe039155ca5128e2112041ba281da93a4b201b7c83d91dd1a70e5cc13d272ef97fcb61754fca0506a
|
||||
f8bd8257f54a8586dfae16dabe5f2df7fc72a9dba93c80c622c2a8eca707327d78234517d9b18c1adf389a89962fdd2e8d585464eab0a5a888aba39972c5389a
|
||||
490f639ca13c73711d02a273bf56e937abcd4eadd0acb6fb05afdb69149a41ad53e8d6827ab7df0dfc46b3ffc0758e14d86b5703afd66b146ae5202878b592a4
|
||||
df6816ea5ea5d2f6eaed46cf6b3fc8b631b0f2543eb258407815afed7f000000ffff0300504b0304140006000800000021000dd1909fb60000001b0100002700
|
||||
00007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0ad
|
||||
d40384e4350d363f2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b
|
||||
284d262452282e3198720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f16
|
||||
5dfe514173d9850528a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100e9de0fbfff0000001c0200001300000000
|
||||
000000000000000000000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b000000
|
||||
00000000000000000000300100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c00000000000000000000
|
||||
000000190200007468656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d0014000600080000002100b7e72e45da060000a81a000016
|
||||
00000000000000000000000000d60200007468656d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b
|
||||
0100002700000000000000000000000000e40900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000df0a00000000}
|
||||
{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d
|
||||
617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169
|
||||
6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363
|
||||
656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e}
|
||||
{\*\latentstyles\lsdstimax371\lsdlockeddef0\lsdsemihiddendef0\lsdunhideuseddef0\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 1;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 5;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 7;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 8;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 9;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 1;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 2;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 3;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 4;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 5;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 6;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 7;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 8;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 9;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal Indent;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footnote text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 header;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footer;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index heading;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 table of figures;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 envelope address;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 envelope return;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footnote reference;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation reference;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 line number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 page number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 endnote reference;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 endnote text;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 table of authorities;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 macro;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 toa heading;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 3;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 3;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 3;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 5;\lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Closing;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Signature;\lsdsemihidden1 \lsdunhideused1 \lsdpriority1 \lsdlocked0 Default Paragraph Font;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 4;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Message Header;\lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Salutation;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Date;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text First Indent;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text First Indent 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Note Heading;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent 3;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Block Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 FollowedHyperlink;\lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;
|
||||
\lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Document Map;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Plain Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 E-mail Signature;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Top of Form;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Bottom of Form;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal (Web);\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Acronym;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Address;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Cite;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Code;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Definition;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Keyboard;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Preformatted;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Sample;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Typewriter;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Variable;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation subject;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 No List;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 1;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Balloon Text;\lsdpriority39 \lsdlocked0 Table Grid;
|
||||
\lsdsemihidden1 \lsdlocked0 Placeholder Text;\lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing;\lsdpriority60 \lsdlocked0 Light Shading;\lsdpriority61 \lsdlocked0 Light List;\lsdpriority62 \lsdlocked0 Light Grid;
|
||||
\lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdpriority65 \lsdlocked0 Medium List 1;\lsdpriority66 \lsdlocked0 Medium List 2;\lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdpriority68 \lsdlocked0 Medium Grid 2;
|
||||
\lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdpriority70 \lsdlocked0 Dark List;\lsdpriority71 \lsdlocked0 Colorful Shading;\lsdpriority72 \lsdlocked0 Colorful List;\lsdpriority73 \lsdlocked0 Colorful Grid;\lsdpriority60 \lsdlocked0 Light Shading Accent 1;
|
||||
\lsdpriority61 \lsdlocked0 Light List Accent 1;\lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;
|
||||
\lsdsemihidden1 \lsdlocked0 Revision;\lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;
|
||||
\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 1;
|
||||
\lsdpriority72 \lsdlocked0 Colorful List Accent 1;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdpriority60 \lsdlocked0 Light Shading Accent 2;\lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdpriority62 \lsdlocked0 Light Grid Accent 2;
|
||||
\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 2;
|
||||
\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2;\lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;
|
||||
\lsdpriority72 \lsdlocked0 Colorful List Accent 2;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;\lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdpriority61 \lsdlocked0 Light List Accent 3;\lsdpriority62 \lsdlocked0 Light Grid Accent 3;
|
||||
\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;
|
||||
\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdpriority70 \lsdlocked0 Dark List Accent 3;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;
|
||||
\lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 3;\lsdpriority60 \lsdlocked0 Light Shading Accent 4;\lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdpriority62 \lsdlocked0 Light Grid Accent 4;
|
||||
\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 4;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;
|
||||
\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 4;
|
||||
\lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdpriority60 \lsdlocked0 Light Shading Accent 5;\lsdpriority61 \lsdlocked0 Light List Accent 5;\lsdpriority62 \lsdlocked0 Light Grid Accent 5;
|
||||
\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 5;
|
||||
\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5;\lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 5;
|
||||
\lsdpriority72 \lsdlocked0 Colorful List Accent 5;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdpriority61 \lsdlocked0 Light List Accent 6;\lsdpriority62 \lsdlocked0 Light Grid Accent 6;
|
||||
\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 6;
|
||||
\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdpriority70 \lsdlocked0 Dark List Accent 6;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 6;
|
||||
\lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 6;\lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis;
|
||||
\lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference;\lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdsemihidden1 \lsdunhideused1 \lsdpriority37 \lsdlocked0 Bibliography;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;\lsdpriority41 \lsdlocked0 Plain Table 1;\lsdpriority42 \lsdlocked0 Plain Table 2;\lsdpriority43 \lsdlocked0 Plain Table 3;\lsdpriority44 \lsdlocked0 Plain Table 4;
|
||||
\lsdpriority45 \lsdlocked0 Plain Table 5;\lsdpriority40 \lsdlocked0 Grid Table Light;\lsdpriority46 \lsdlocked0 Grid Table 1 Light;\lsdpriority47 \lsdlocked0 Grid Table 2;\lsdpriority48 \lsdlocked0 Grid Table 3;\lsdpriority49 \lsdlocked0 Grid Table 4;
|
||||
\lsdpriority50 \lsdlocked0 Grid Table 5 Dark;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 1;
|
||||
\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 1;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 1;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 1;
|
||||
\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 1;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 2;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 2;
|
||||
\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 2;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 2;
|
||||
\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 3;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 3;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 3;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 3;
|
||||
\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 3;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 4;
|
||||
\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 4;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 4;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 4;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 4;
|
||||
\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 4;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 5;
|
||||
\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 5;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 5;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 5;
|
||||
\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 5;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 6;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 6;
|
||||
\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 6;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 6;
|
||||
\lsdpriority46 \lsdlocked0 List Table 1 Light;\lsdpriority47 \lsdlocked0 List Table 2;\lsdpriority48 \lsdlocked0 List Table 3;\lsdpriority49 \lsdlocked0 List Table 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark;
|
||||
\lsdpriority51 \lsdlocked0 List Table 6 Colorful;\lsdpriority52 \lsdlocked0 List Table 7 Colorful;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 List Table 2 Accent 1;\lsdpriority48 \lsdlocked0 List Table 3 Accent 1;
|
||||
\lsdpriority49 \lsdlocked0 List Table 4 Accent 1;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 1;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 1;
|
||||
\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 List Table 2 Accent 2;\lsdpriority48 \lsdlocked0 List Table 3 Accent 2;\lsdpriority49 \lsdlocked0 List Table 4 Accent 2;
|
||||
\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 2;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 3;
|
||||
\lsdpriority47 \lsdlocked0 List Table 2 Accent 3;\lsdpriority48 \lsdlocked0 List Table 3 Accent 3;\lsdpriority49 \lsdlocked0 List Table 4 Accent 3;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 3;
|
||||
\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 4;\lsdpriority47 \lsdlocked0 List Table 2 Accent 4;
|
||||
\lsdpriority48 \lsdlocked0 List Table 3 Accent 4;\lsdpriority49 \lsdlocked0 List Table 4 Accent 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 4;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 4;
|
||||
\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 List Table 2 Accent 5;\lsdpriority48 \lsdlocked0 List Table 3 Accent 5;
|
||||
\lsdpriority49 \lsdlocked0 List Table 4 Accent 5;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 5;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 5;
|
||||
\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 List Table 2 Accent 6;\lsdpriority48 \lsdlocked0 List Table 3 Accent 6;\lsdpriority49 \lsdlocked0 List Table 4 Accent 6;
|
||||
\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 6;}}{\*\datastore 010500000200000018000000
|
||||
4d73786d6c322e534158584d4c5265616465722e362e30000000000000000000000e0000
|
||||
d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff0900060000000000000000000000010000000100000000000000001000000200000001000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
fffffffffffffffffdffffff04000000feffffff05000000fefffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffff010000000c6ad98892f1d411a65f0040963251e50000000000000000000000006069
|
||||
e214b3d4ce010300000080020000000000004d0073006f004400610074006100530074006f0072006500000000000000000000000000000000000000000000000000000000000000000000000000000000001a000101ffffffffffffffff0200000000000000000000000000000000000000000000006069e214b3d4ce01
|
||||
6069e214b3d4ce010000000000000000000000003500d900ca00dd00ce004400cc00c8005a0045004700c400cd0057004900c500d400c900cb00ce00570051003d003d000000000000000000000000000000000032000101ffffffffffffffff0300000000000000000000000000000000000000000000006069e214b3d4
|
||||
ce016069e214b3d4ce010000000000000000000000004900740065006d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000201ffffffff04000000ffffffff000000000000000000000000000000000000000000000000
|
||||
00000000000000000000000000000000fc00000000000000010000000200000003000000feffffff0500000006000000070000000800000009000000feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3c623a536f75726365732053656c65637465645374796c653d225c415041536978746845646974696f6e4f66666963654f6e6c696e652e78736c22205374796c654e616d653d22415041222056657273696f6e3d22362220786d6c6e733a
|
||||
623d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f6f6666696365446f63756d656e742f323030362f6269626c696f6772617068792220786d6c6e733d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f6f6666696365446f63756d656e74
|
||||
2f323030362f6269626c696f677261706879223e3c2f623a536f75726365733e000000003c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d226e6f223f3e0d0a3c64733a6461746173746f72654974656d2064733a6974656d49443d227b42384244
|
||||
394137462d323833422d343136342d413442352d3632323544323941454535397d2220786d6c6e733a64733d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f6f6666696365446f63756d656e742f323030362f637573746f6d586d6c223e3c64733a736368656d61526566733e3c
|
||||
64733a736368656d615265662064733a7572693d22687474703a2f2f736368656d61732e6f70656e500072006f007000650072007400690065007300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000200ffffffffffffffffffffffff000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000400000055010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000
|
||||
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff
|
||||
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000786d6c666f726d6174732e6f72672f6f6666696365446f63756d656e742f323030362f6269626c696f677261706879222f3e3c2f64733a736368656d61526566733e3c2f64733a6461746173746f
|
||||
72654974656d3e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000105000000000000}}
|
||||
@@ -1,2 +1,3 @@
|
||||
; Qt Configuration file
|
||||
[Paths]
|
||||
Plugins = DumbHackThatFixPY2APP
|
||||
Plugins = PlugIns
|
||||
|
||||
110
setup.py
Normal file → Executable file
110
setup.py
Normal file → Executable file
@@ -1,16 +1,21 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
cx_Freeze build script for KCC.
|
||||
py2exe/py2app build script for KCC.
|
||||
|
||||
Usage (Windows):
|
||||
python setup.py py2exe
|
||||
|
||||
Usage (Mac OS X):
|
||||
python setup.py py2app
|
||||
|
||||
Usage (Windows):
|
||||
python setup.py build
|
||||
"""
|
||||
from sys import platform
|
||||
from sys import platform, version_info
|
||||
from kcc import __version__
|
||||
if version_info[0] != 3:
|
||||
print('ERROR: This is Python 3 script!')
|
||||
exit(1)
|
||||
|
||||
NAME = "KindleComicConverter"
|
||||
VERSION = "3.3"
|
||||
VERSION = __version__
|
||||
MAIN = "kcc.py"
|
||||
|
||||
if platform == "darwin":
|
||||
@@ -22,58 +27,87 @@ if platform == "darwin":
|
||||
py2app=dict(
|
||||
argv_emulation=True,
|
||||
iconfile='icons/comic2ebook.icns',
|
||||
includes=['PIL', 'sip', 'PyQt4', 'PyQt4.QtCore', 'PyQt4.QtGui'],
|
||||
resources=['other/qt.conf', 'LICENSE.txt'],
|
||||
includes=['sip', 'PyQt5.QtPrintSupport'],
|
||||
resources=['LICENSE.txt', 'other/qt.conf', 'other/Additional-LICENSE.txt', 'other/unrar', 'other/7za'],
|
||||
plist=dict(
|
||||
CFBundleName=NAME,
|
||||
CFBundleShortVersionString=VERSION,
|
||||
CFBundleGetInfoString=NAME + " " + VERSION +
|
||||
", written 2012-2013 by Ciro Mattia Gonano and Pawel Jastrzebski",
|
||||
", written 2012-2015 by Ciro Mattia Gonano and Pawel Jastrzebski",
|
||||
CFBundleExecutable=NAME,
|
||||
CFBundleIdentifier='com.github.ciromattia.kcc',
|
||||
CFBundleSignature='dplt',
|
||||
CFBundleDocumentTypes=[
|
||||
dict(
|
||||
CFBundleTypeExtensions=['cbz', 'cbr', 'cb7', 'zip', 'rar', '7z', 'pdf'],
|
||||
CFBundleTypeName='Comics',
|
||||
CFBundleTypeIconFile='comic2ebook.icns',
|
||||
CFBundleTypeRole='Editor',
|
||||
)
|
||||
],
|
||||
LSMinimumSystemVersion='10.8.0',
|
||||
LSEnvironment=dict(
|
||||
PATH='./../Resources:/usr/local/bin:/usr/bin:/bin'
|
||||
),
|
||||
NSHumanReadableCopyright='ISC License (ISCL)'
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
elif platform == "win32":
|
||||
from cx_Freeze import setup, Executable
|
||||
base = "Win32GUI"
|
||||
# noinspection PyUnresolvedReferences
|
||||
import py2exe
|
||||
import platform
|
||||
from distutils.core import setup
|
||||
if platform.architecture()[0] == '64bit':
|
||||
suffix = '_64'
|
||||
else:
|
||||
suffix = ''
|
||||
additional_files = [('platforms', ['C:\Python34' + suffix +
|
||||
'\Lib\site-packages\PyQt5\plugins\platforms\qwindows.dll']),
|
||||
('', ['LICENSE.txt',
|
||||
'other\\7za.exe',
|
||||
'other\\UnRAR.exe',
|
||||
'other\\Additional-LICENSE.txt',
|
||||
'C:\Python34' + suffix + '\Lib\site-packages\PyQt5\libGLESv2.dll',
|
||||
'C:\Python34' + suffix + '\Lib\site-packages\PyQt5\libEGL.dll'])]
|
||||
extra_options = dict(
|
||||
options={"build_exe": {"include_files": ['LICENSE.txt',
|
||||
['other/UnRAR.exe', 'UnRAR.exe'],
|
||||
['other/7za.exe', '7za.exe'],
|
||||
['other/Additional-LICENSE.txt', 'Additional-LICENSE.txt']
|
||||
], "compressed": True}},
|
||||
executables=[Executable(MAIN,
|
||||
base=base,
|
||||
targetName="KCC.exe",
|
||||
icon="icons/comic2ebook.ico",
|
||||
copyDependentFiles=True,
|
||||
appendScriptToExe=True,
|
||||
appendScriptToLibrary=False,
|
||||
compress=True)])
|
||||
options={'py2exe': {"bundle_files": 1,
|
||||
"dist_dir": "dist" + suffix,
|
||||
"compressed": True,
|
||||
"includes": ["sip"],
|
||||
"excludes": ["tkinter"],
|
||||
"optimize": 2}},
|
||||
windows=[{"script": MAIN,
|
||||
"dest_base": "KCC",
|
||||
"version": VERSION,
|
||||
"copyright": "Ciro Mattia Gonano, Pawel Jastrzebski © 2012-2015",
|
||||
"legal_copyright": "ISC License (ISCL)",
|
||||
"product_version": VERSION,
|
||||
"product_name": "Kindle Comic Converter",
|
||||
"file_description": "Kindle Comic Converter",
|
||||
"icon_resources": [(1, "icons\comic2ebook.ico")]}],
|
||||
zipfile=None,
|
||||
data_files=additional_files)
|
||||
else:
|
||||
from cx_Freeze import setup, Executable
|
||||
extra_options = dict(
|
||||
options={"build_exe": {"include_files": ['LICENSE.txt'], "compressed": True}},
|
||||
executables=[Executable(MAIN,
|
||||
icon="icons/comic2ebook.png",
|
||||
copyDependentFiles=True,
|
||||
appendScriptToExe=True,
|
||||
appendScriptToLibrary=False,
|
||||
compress=True)])
|
||||
print('Please use setup.sh to build Linux package.')
|
||||
exit()
|
||||
|
||||
# noinspection PyUnboundLocalVariable
|
||||
setup(
|
||||
name=NAME,
|
||||
version=VERSION,
|
||||
author="Ciro Mattia Gonano, Pawel Jastrzebski",
|
||||
author_email="ciromattia@gmail.com, pawelj@vulturis.eu",
|
||||
description="A tool to convert comics (CBR/CBZ/PDFs/image folders) to MOBI.",
|
||||
author_email="ciromattia@gmail.com, pawelj@iosphe.re",
|
||||
description="Kindle Comic Converter",
|
||||
license="ISC License (ISCL)",
|
||||
keywords="kindle comic mobipocket mobi cbz cbr manga",
|
||||
url="http://github.com/ciromattia/kcc",
|
||||
packages=['kcc'], requires=['Pillow'],
|
||||
**extra_options
|
||||
)
|
||||
|
||||
if platform == "darwin":
|
||||
from os import chmod, makedirs
|
||||
from shutil import copyfile
|
||||
makedirs('dist/' + NAME + '.app/Contents/PlugIns/platforms')
|
||||
copyfile('other/libqcocoa.dylib', 'dist/' + NAME + '.app/Contents/PlugIns/platforms/libqcocoa.dylib')
|
||||
chmod('dist/' + NAME + '.app/Contents/Resources/unrar', 0o777)
|
||||
chmod('dist/' + NAME + '.app/Contents/Resources/7za', 0o777)
|
||||
25
setup.sh
Executable file
25
setup.sh
Executable file
@@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
# Linux Python package build script
|
||||
|
||||
VERSION="4.5"
|
||||
|
||||
cp kcc.py __main__.py
|
||||
zip kcc.zip __main__.py kcc/*.py
|
||||
echo "#!/usr/bin/env python3" > kcc-bin
|
||||
cat kcc.zip >> kcc-bin
|
||||
chmod +x kcc-bin
|
||||
|
||||
cp kcc-c2e.py __main__.py
|
||||
zip kcc-c2e.zip __main__.py kcc/*.py
|
||||
echo "#!/usr/bin/env python3" > kcc-c2e-bin
|
||||
cat kcc-c2e.zip >> kcc-c2e-bin
|
||||
chmod +x kcc-c2e-bin
|
||||
|
||||
cp kcc-c2p.py __main__.py
|
||||
zip kcc-c2p.zip __main__.py kcc/*.py
|
||||
echo "#!/usr/bin/env python3" > kcc-c2p-bin
|
||||
cat kcc-c2p.zip >> kcc-c2p-bin
|
||||
chmod +x kcc-c2p-bin
|
||||
|
||||
tar --xform s:^.*/:: --xform s/kcc-bin/kcc/ --xform s/kcc-c2p-bin/kcc-c2p/ --xform s/kcc-c2e-bin/kcc-c2e/ --xform s/comic2ebook/kcc/ -czf KindleComicConverter_linux_${VERSION}.tar.gz kcc-bin kcc-c2e-bin kcc-c2p-bin LICENSE.txt icons/comic2ebook.png
|
||||
rm __main__.py kcc.zip kcc-c2e.zip kcc-c2p.zip kcc-bin kcc-c2e-bin kcc-c2p-bin
|
||||
Reference in New Issue
Block a user