1
0
mirror of https://github.com/ciromattia/kcc synced 2026-04-17 14:38:47 +00:00

Compare commits

..

69 Commits
3.7.2 ... 4.0.2

Author SHA1 Message Date
Paweł Jastrzębski
dc312f36c2 Updated OSX libs 2014-03-19 10:14:56 +01:00
Paweł Jastrzębski
4573ff6ec2 README update 2014-03-19 09:25:45 +01:00
Paweł Jastrzębski
d77498405b Updated to psutil 2.0 2014-03-13 21:58:15 +01:00
Paweł Jastrzębski
e491fca445 Version bump + README update 2014-03-13 21:26:26 +01:00
Paweł Jastrzębski
d22ee1a488 Tweaked HQ mode 2014-02-18 12:56:27 +01:00
Paweł Jastrzębski
7ebcccd8a2 Replaced os.rename with atomic os.replace
This should eliminate last problems with file locks on Windows
2014-02-13 18:35:17 +01:00
Paweł Jastrzębski
9a691c3c63 Windows: Fixed sys.stdout and sys.stderr 2014-02-06 11:45:37 +01:00
Paweł Jastrzębski
2b04a0298e Windows: Fixed abnormalities with version check
CX_Freeze working very, very strange with Python 3.3.3
2014-02-02 08:56:50 +01:00
Paweł Jastrzębski
9867f63d00 Version bump + README update 2014-02-01 19:13:03 +01:00
Paweł Jastrzębski
866f8898be Windows: Hopefully fixed all problems with file locks 2014-02-01 18:11:16 +01:00
Paweł Jastrzębski
9f2ac7a176 Windows: Truncated tracebacks 2014-02-01 16:14:23 +01:00
Paweł Jastrzębski
634213f380 WebToons: Improved performance of directory merger 2014-02-01 14:09:25 +01:00
Paweł Jastrzębski
ce82b5ec66 Tweaked margin color detection 2014-01-31 11:15:03 +01:00
Moshev
062b239f2f Fixed errors in image.py introduced from the different handling of division between python 2 and 3 2014-01-29 08:14:00 +01:00
Paweł Jastrzębski
f5f5c05f1e Merge pull request #82 from ciromattia/python3
Python3 + Qt5
2014-01-28 03:11:33 -08:00
Paweł Jastrzębski
a229ba44bf README update 2014-01-28 12:10:33 +01:00
Paweł Jastrzębski
27e5cc3b00 Removed redundant output 2014-01-27 20:51:13 +01:00
Paweł Jastrzębski
63d752280a Margin color detection tweaks 2014-01-26 10:25:26 +01:00
Paweł Jastrzębski
60b7a90589 Improved Panel View logic 2014-01-25 17:46:10 +01:00
Paweł Jastrzębski
63413fa4ba GUI: Link to important tips appear now 5 times 2014-01-25 10:57:18 +01:00
Paweł Jastrzębski
3a536df626 Code cleanup 2014-01-25 10:42:38 +01:00
Paweł Jastrzębski
35bc4a2987 Added MD5 check to update mechanism 2014-01-24 22:54:16 +01:00
Paweł Jastrzębski
3bb8cc7778 Great Index: Using MD5 checksums instead file paths.
Performance impact is negligible, it simplify the code and is much more error resistant.
2014-01-24 22:43:24 +01:00
Paweł Jastrzębski
bd53c6108d Great Index: Slugification fix 2014-01-24 09:08:39 +01:00
Paweł Jastrzębski
3d8bcb4020 Image flags are not part of filename anymore 2014-01-23 18:06:14 +01:00
Paweł Jastrzębski
162c146bed Windows: Fixed possible problems with file locks
OSX: Tweaked last fix
2014-01-23 11:23:58 +01:00
Paweł Jastrzębski
e4750fc965 OSX: Fixed 7zip parsing 2014-01-22 21:02:06 +01:00
Paweł Jastrzębski
ebe7d910de Reverting setup changes 2014-01-22 17:43:19 +01:00
Paweł Jastrzębski
aa96381eb5 Added experimental Linux setup 2014-01-22 16:47:55 +01:00
Paweł Jastrzębski
a2b9b5aa8b Linux/OSX: Drag&Drop fix 2014-01-21 22:02:15 +01:00
Paweł Jastrzębski
1e5bfc9f66 OSX: Fixed file association (close #65) 2014-01-21 18:09:22 +01:00
Paweł Jastrzębski
25a68ebdea Reformated tooltips 2014-01-21 10:57:54 +01:00
Paweł Jastrzębski
786d2a9e1f Added option to select output directory 2014-01-20 22:26:50 +01:00
Paweł Jastrzębski
4133cd21ba Linux: Completly disabled QSystemTrayIcon
Not showing tray was not enought. Even creating object cause instability.
2014-01-20 21:26:18 +01:00
Paweł Jastrzębski
237ef728e1 Hotfixed cx_freeze packing 2014-01-20 12:07:26 +01:00
Paweł Jastrzębski
991bf5d4a9 Miscellaneous tweaks 2014-01-20 11:58:15 +01:00
Paweł Jastrzębski
aa8b78b4e4 Autoupdater for Windows (#68) 2014-01-20 11:16:25 +01:00
Paweł Jastrzębski
c2e6a0b791 README update 2014-01-19 10:53:00 +01:00
Paweł Jastrzębski
42cf9e099f Updated Linux installer 2014-01-18 12:24:16 +01:00
Paweł Jastrzębski
d99064596a Detect Python 2 + README update 2014-01-18 12:15:45 +01:00
Paweł Jastrzębski
b1e7a88353 Removing QFileDialog hack
Now when KCC support drag&drop we can return to native dialog.
2014-01-18 11:14:14 +01:00
Paweł Jastrzębski
f8610e1cd7 Linux: Disabling systray icon 2014-01-18 10:20:43 +01:00
Paweł Jastrzębski
562dad02fa Miscellaneous GUI tweaks 2014-01-18 09:51:17 +01:00
Paweł Jastrzębski
66b867c1ca Various multi-os tweaks 2014-01-17 19:37:35 +01:00
Paweł Jastrzębski
b46ada9596 Drag & drop for OSX and Linux 2014-01-17 16:19:54 +01:00
Paweł Jastrzębski
aaa2de81fc Updated Inno Setup 2014-01-17 14:37:58 +01:00
Paweł Jastrzębski
b0c6315fee Updated Windows setup + OSX fix 2014-01-17 12:34:05 +01:00
Paweł Jastrzębski
509d78c0a6 Updated OSX setup 2014-01-17 12:25:20 +01:00
Paweł Jastrzębski
65ef77bace Improved NCX creation (close #79) 2014-01-17 09:31:51 +01:00
Paweł Jastrzębski
170064853c Added drag & drop support 2014-01-16 22:11:06 +01:00
Paweł Jastrzębski
c7e9d883fa Manga mode is now always available (close #78) 2014-01-16 19:17:49 +01:00
Paweł Jastrzębski
a8521dbc9a Fixed multi-instance lock 2014-01-16 18:49:51 +01:00
Paweł Jastrzębski
0f44629273 Dropping unnecessary debug 2014-01-16 13:56:37 +01:00
Paweł Jastrzębski
f12361e7cf kindlesplit: Python3 update 2014-01-16 13:37:36 +01:00
Paweł Jastrzębski
450076e6e8 pdfjpgextract: Python3 update 2014-01-16 12:48:04 +01:00
Paweł Jastrzębski
6d445ae151 Fully implemented new slugify library 2014-01-16 12:34:36 +01:00
Paweł Jastrzębski
921511dcf2 Full UTF-8 awareness (close #74)
Tested only on Windows. But he had the biggest problems with it.
2014-01-16 11:40:49 +01:00
Paweł Jastrzębski
d76a624a82 Bucket #3 2014-01-16 08:48:29 +01:00
Paweł Jastrzębski
cf3df581e1 Moved dependiences check out of module 2014-01-15 14:58:45 +01:00
Paweł Jastrzębski
87009f27a6 Preliminary QT5 update 2014-01-15 14:09:40 +01:00
Paweł Jastrzębski
cccbd36463 And one more bucket... 2014-01-15 11:32:29 +01:00
Paweł Jastrzębski
19b438844d Bucket of various tweaks 2014-01-15 10:24:31 +01:00
Paweł Jastrzębski
878e92b527 Added proper startup scripts
Hacks that allow standalone startup of script inside module are messy.
2014-01-15 10:23:44 +01:00
Paweł Jastrzębski
116dce09fd Updated rarfile 2014-01-15 10:00:05 +01:00
Paweł Jastrzębski
3af30faee9 Merge branch 'master' into python3 2014-01-15 09:33:35 +01:00
Ciro Mattia Gonano
89d31cb8e5 Merge master into python3 2013-12-16 22:37:37 +01:00
Ciro Mattia Gonano
fa94e18a6a Merge branch 'master' into python3 2013-12-04 10:15:25 +01:00
Ciro Mattia Gonano
9f68e009f1 Merge branch 'master' into python3 2013-11-19 12:49:58 +01:00
Ciro Mattia Gonano
d33c53b691 Version 4.0 - first draft for Python3 conversion 2013-11-14 15:49:46 +01:00
29 changed files with 4297 additions and 4060 deletions

View File

@@ -71,7 +71,7 @@
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>Disable image optimizations.</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Disable image optimizations.&lt;br/&gt;Input images must be already resized.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>No optimisation</string> <string>No optimisation</string>
@@ -110,7 +110,7 @@
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Enable auto-splitting of webtoons like &lt;span style=&quot; font-style:italic;&quot;&gt;Tower of God&lt;/span&gt; or &lt;span style=&quot; font-style:italic;&quot;&gt;Noblesse&lt;/span&gt;.&lt;br/&gt;Pages with a low width, high height and vertical panel flow.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Enable auto-splitting of webtoons like &lt;span style=&quot; font-style:italic;&quot;&gt;Tower of God&lt;/span&gt; or &lt;span style=&quot; font-style:italic;&quot;&gt;Noblesse&lt;/span&gt;.&lt;br/&gt;Pages with a low width, high height and vertical panel flow.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>Webtoon mode</string> <string>Webtoon mode</string>
@@ -128,7 +128,7 @@
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Create PNG files instead JPEG.&lt;br/&gt;Quality increase is not noticeable on most of devices.&lt;br/&gt;Output files &lt;span style=&quot; font-weight:600;&quot;&gt;might&lt;/span&gt; be smaller.&lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;MOBI conversion will be much slower.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Create PNG files instead JPEG.&lt;br/&gt;Quality increase is not noticeable on most of devices.&lt;br/&gt;Output files &lt;span style=&quot; font-weight:600;&quot;&gt;might&lt;/span&gt; be smaller.&lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;MOBI conversion will be much slower.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>PNG output</string> <string>PNG output</string>
@@ -167,7 +167,7 @@
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Disable splitting and rotation.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Disable splitting and rotation.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>No split/rotate</string> <string>No split/rotate</string>
@@ -195,7 +195,7 @@
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>Target device.</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Target device.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
</widget> </widget>
<widget class="QComboBox" name="FormatBox"> <widget class="QComboBox" name="FormatBox">
@@ -217,7 +217,7 @@
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>Output format.</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Output format.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
</widget> </widget>
<widget class="QPushButton" name="ConvertButton"> <widget class="QPushButton" name="ConvertButton">
@@ -240,6 +240,9 @@
<property name="focusPolicy"> <property name="focusPolicy">
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Shift+Click to select the output directory.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text"> <property name="text">
<string>Convert</string> <string>Convert</string>
</property> </property>
@@ -359,7 +362,7 @@
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>Enable right-to-left reading.</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Enable right-to-left reading.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>Manga mode</string> <string>Manga mode</string>
@@ -383,13 +386,7 @@
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt; <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Unchecked - Normal quality mode&lt;br/&gt;&lt;/span&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;Use it when Panel View support is not needed.&lt;br/&gt;&lt;/span&gt;- Maximum quality when zoom is not enabled.&lt;br/&gt;- Poor quality when zoom is enabled.&lt;br/&gt;- Lowest file size.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Indeterminate - High quality mode&lt;br/&gt;&lt;/span&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;Not zoomed images &lt;/span&gt;&lt;span style=&quot; font-weight:600; font-style:italic;&quot;&gt;might&lt;/span&gt;&lt;span style=&quot; font-style:italic;&quot;&gt; be blurry.&lt;br/&gt;&lt;/span&gt;- High quality when zoom is not enabled.&lt;br/&gt;- Maximum quality when zoom is enabled.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Checked - Ultra quality mode&lt;br/&gt;&lt;/span&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;Maximum possible quality.&lt;br/&gt;&lt;/span&gt;- Maximum quality when zoom is not enabled.&lt;br/&gt;- Maximum quality when zoom is enabled.&lt;br/&gt;- Very high file size.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-weight:600; text-decoration: underline;&quot;&gt;Unchecked - Normal quality mode&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-style:italic;&quot;&gt;Use it when Panel View support is not needed.&lt;/span&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-weight:600; text-decoration: underline;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2';&quot;&gt;- Maximum quality when zoom is not enabled.&lt;br /&gt;- Poor quality when zoom is enabled.&lt;br /&gt;- Lowest file size.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-weight:600; text-decoration: underline;&quot;&gt;Indeterminate - High quality mode&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-style:italic;&quot;&gt;Not zoomed image &lt;/span&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-weight:600; font-style:italic;&quot;&gt;might &lt;/span&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-style:italic;&quot;&gt;be a little blurry.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-style:italic;&quot;&gt;Smaller images might be forcefully upscaled in this mode.&lt;/span&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-weight:600; text-decoration: underline;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2';&quot;&gt;- Medium/High quality when zoom is not enabled.&lt;br /&gt;- Maximum quality when zoom is enabled.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-weight:600; text-decoration: underline;&quot;&gt;Checked - Ultra quality mode&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-style:italic;&quot;&gt;Maximum possible quality.&lt;/span&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-weight:600; text-decoration: underline;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2';&quot;&gt;- Maximum quality when zoom is not enabled.&lt;br /&gt;- Maximum quality when zoom is enabled.&lt;br /&gt;- Very high file size.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>High/Ultra quality</string> <string>High/Ultra quality</string>
@@ -416,7 +413,7 @@ p, li { white-space: pre-wrap; }
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Disable splitting of two-page spreads.&lt;br/&gt;They will be rotated instead.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Disable splitting of two-page spreads.&lt;br/&gt;They will be rotated instead.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>Horizontal mode</string> <string>Horizontal mode</string>
@@ -635,7 +632,7 @@ p, li { white-space: pre-wrap; }
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Don't convert images to grayscale.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Don't convert images to grayscale.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>Color mode</string> <string>Color mode</string>
@@ -664,7 +661,7 @@ p, li { white-space: pre-wrap; }
</font> </font>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>Resolution of target device.</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Resolution of target device.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>Custom width: </string> <string>Custom width: </string>
@@ -697,10 +694,10 @@ p, li { white-space: pre-wrap; }
<bool>false</bool> <bool>false</bool>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>Resolution of target device.</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Resolution of target device.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="inputMask"> <property name="inputMask">
<string>0000; </string> <string>0000</string>
</property> </property>
<property name="maxLength"> <property name="maxLength">
<number>4</number> <number>4</number>
@@ -715,7 +712,7 @@ p, li { white-space: pre-wrap; }
</font> </font>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>Resolution of target device.</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Resolution of target device.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>Custom height: </string> <string>Custom height: </string>
@@ -748,10 +745,10 @@ p, li { white-space: pre-wrap; }
<bool>false</bool> <bool>false</bool>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>Resolution of target device.</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Resolution of target device.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="inputMask"> <property name="inputMask">
<string>0000; </string> <string>0000</string>
</property> </property>
<property name="maxLength"> <property name="maxLength">
<number>4</number> <number>4</number>

View File

@@ -69,7 +69,7 @@
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;Disable image optimizations.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Disable image optimizations.&lt;br/&gt;Input images must be already resized.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>No optimisation</string> <string>No optimisation</string>
@@ -88,7 +88,7 @@
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:12pt; font-weight:600; text-decoration: underline;&quot;&gt;Unchecked - Nothing&lt;br/&gt;&lt;/span&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;Images smaller than device resolution will not be resized.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-size:12pt; font-weight:600; text-decoration: underline;&quot;&gt;Indeterminate - Stretching&lt;br/&gt;&lt;/span&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;Images smaller than device resolution will be resized. Aspect ratio will be not preserved.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-size:12pt; font-weight:600; text-decoration: underline;&quot;&gt;Checked - Upscaling&lt;br/&gt;&lt;/span&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;Images smaller than device resolution will be resized. Aspect ratio will be preserved.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Unchecked - Nothing&lt;br/&gt;&lt;/span&gt;Images smaller than device resolution will not be resized.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Indeterminate - Stretching&lt;br/&gt;&lt;/span&gt;Images smaller than device resolution will be resized. Aspect ratio will be not preserved.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Checked - Upscaling&lt;br/&gt;&lt;/span&gt;Images smaller than device resolution will be resized. Aspect ratio will be preserved.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>Stretch/Upscale</string> <string>Stretch/Upscale</string>
@@ -110,7 +110,7 @@
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;Enable auto-splitting of webtoons like &lt;/span&gt;&lt;span style=&quot; font-size:12pt; font-style:italic;&quot;&gt;Tower of God&lt;/span&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt; or &lt;/span&gt;&lt;span style=&quot; font-size:12pt; font-style:italic;&quot;&gt;Noblesse&lt;/span&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;.&lt;br/&gt;Pages with a low width, high height and vertical panel flow.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Enable auto-splitting of webtoons like &lt;span style=&quot; font-style:italic;&quot;&gt;Tower of God&lt;/span&gt; or &lt;span style=&quot; font-style:italic;&quot;&gt;Noblesse&lt;/span&gt;.&lt;br/&gt;Pages with a low width, high height and vertical panel flow.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>Webtoon mode</string> <string>Webtoon mode</string>
@@ -129,7 +129,7 @@
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;Create PNG files instead JPEG.&lt;br/&gt;Quality increase is not noticeable on most of devices.&lt;br/&gt;Output files &lt;/span&gt;&lt;span style=&quot; font-size:12pt; font-weight:600;&quot;&gt;might&lt;/span&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt; be smaller.&lt;br/&gt;&lt;/span&gt;&lt;span style=&quot; font-size:12pt; font-weight:600;&quot;&gt;MOBI conversion will be much slower.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Create PNG files instead JPEG.&lt;br/&gt;Quality increase is not noticeable on most of devices.&lt;br/&gt;Output files &lt;span style=&quot; font-weight:600;&quot;&gt;might&lt;/span&gt; be smaller.&lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;MOBI conversion will be much slower.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>PNG output</string> <string>PNG output</string>
@@ -148,7 +148,7 @@
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:12pt; font-weight:600; text-decoration: underline;&quot;&gt;Unchecked - Autodetection&lt;br/&gt;&lt;/span&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;Color of margins fill will be detected automatically.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-size:12pt; font-weight:600; text-decoration: underline;&quot;&gt;Indeterminate - White&lt;br/&gt;&lt;/span&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;Margins will be filled with white color.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-size:12pt; font-weight:600; text-decoration: underline;&quot;&gt;Checked - Black&lt;br/&gt;&lt;/span&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;Margins will be filled with black color.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Unchecked - Autodetection&lt;br/&gt;&lt;/span&gt;Color of margins fill will be detected automatically.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Indeterminate - White&lt;br/&gt;&lt;/span&gt;Margins will be filled with white color.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Checked - Black&lt;br/&gt;&lt;/span&gt;Margins will be filled with black color.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>W/B margins</string> <string>W/B margins</string>
@@ -170,7 +170,7 @@
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;Disable splitting and rotation.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Disable splitting and rotation.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>No split/rotate</string> <string>No split/rotate</string>
@@ -198,7 +198,7 @@
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;Target device.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Target device.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
</widget> </widget>
<widget class="QComboBox" name="FormatBox"> <widget class="QComboBox" name="FormatBox">
@@ -220,7 +220,7 @@
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;Output format.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Output format.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
</widget> </widget>
<widget class="QPushButton" name="ConvertButton"> <widget class="QPushButton" name="ConvertButton">
@@ -243,6 +243,9 @@
<property name="focusPolicy"> <property name="focusPolicy">
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Shift+Click to select the output directory.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text"> <property name="text">
<string>Convert</string> <string>Convert</string>
</property> </property>
@@ -363,7 +366,7 @@
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;Enable right-to-left reading.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Enable right-to-left reading.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>Manga mode</string> <string>Manga mode</string>
@@ -388,7 +391,7 @@
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:12pt; font-weight:600; text-decoration: underline;&quot;&gt;Unchecked - Normal quality mode&lt;br/&gt;&lt;/span&gt;&lt;span style=&quot; font-size:12pt; font-style:italic;&quot;&gt;Use it when Panel View support is not needed.&lt;/span&gt;&lt;span style=&quot; font-size:12pt; font-weight:600; text-decoration: underline;&quot;&gt;&lt;br/&gt;&lt;/span&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;- Maximum quality when zoom is not enabled.&lt;br/&gt;- Poor quality when zoom is enabled.&lt;br/&gt;- Lowest file size.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-size:12pt; font-weight:600; text-decoration: underline;&quot;&gt;Indeterminate - High quality mode&lt;br/&gt;&lt;/span&gt;&lt;span style=&quot; font-size:12pt; font-style:italic;&quot;&gt;Not zoomed image &lt;/span&gt;&lt;span style=&quot; font-size:12pt; font-weight:600; font-style:italic;&quot;&gt;might &lt;/span&gt;&lt;span style=&quot; font-size:12pt; font-style:italic;&quot;&gt;be a little blurry.&lt;br/&gt;Smaller images might be forcefully upscaled in this mode.&lt;/span&gt;&lt;span style=&quot; font-size:12pt; font-weight:600; text-decoration: underline;&quot;&gt;&lt;br/&gt;&lt;/span&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;- Medium/High quality when zoom is not enabled.&lt;br/&gt;- Maximum quality when zoom is enabled.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-size:12pt; font-weight:600; text-decoration: underline;&quot;&gt;Checked - Ultra quality mode&lt;br/&gt;&lt;/span&gt;&lt;span style=&quot; font-size:12pt; font-style:italic;&quot;&gt;Maximum possible quality.&lt;/span&gt;&lt;span style=&quot; font-size:12pt; font-weight:600; text-decoration: underline;&quot;&gt;&lt;br/&gt;&lt;/span&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;- Maximum quality when zoom is not enabled.&lt;br/&gt;- Maximum quality when zoom is enabled.&lt;br/&gt;- Very high file size.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Unchecked - Normal quality mode&lt;br/&gt;&lt;/span&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;Use it when Panel View support is not needed.&lt;br/&gt;&lt;/span&gt;- Maximum quality when zoom is not enabled.&lt;br/&gt;- Poor quality when zoom is enabled.&lt;br/&gt;- Lowest file size.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Indeterminate - High quality mode&lt;br/&gt;&lt;/span&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;Not zoomed image &lt;/span&gt;&lt;span style=&quot; font-weight:600; font-style:italic;&quot;&gt;might&lt;/span&gt;&lt;span style=&quot; font-style:italic;&quot;&gt; be a little blurry.&lt;br/&gt;&lt;/span&gt;- High quality when zoom is not enabled.&lt;br/&gt;- Maximum quality when zoom is enabled.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Checked - Ultra quality mode&lt;br/&gt;&lt;/span&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;Maximum possible quality.&lt;br/&gt;&lt;/span&gt;- Maximum quality when zoom is not enabled.&lt;br/&gt;- Maximum quality when zoom is enabled.&lt;br/&gt;- Very high file size.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>High/Ultra quality</string> <string>High/Ultra quality</string>
@@ -416,7 +419,7 @@
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;Disable splitting of two-page spreads.&lt;br/&gt;They will be rotated instead.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Disable splitting of two-page spreads.&lt;br/&gt;They will be rotated instead.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>Horizontal mode</string> <string>Horizontal mode</string>
@@ -581,7 +584,7 @@
<x>10</x> <x>10</x>
<y>10</y> <y>10</y>
<width>401</width> <width>401</width>
<height>35</height> <height>29</height>
</rect> </rect>
</property> </property>
<property name="font"> <property name="font">
@@ -592,9 +595,6 @@
<bold>true</bold> <bold>true</bold>
</font> </font>
</property> </property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="value"> <property name="value">
<number>0</number> <number>0</number>
</property> </property>
@@ -639,7 +639,7 @@
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;Don't convert images to grayscale.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Don't convert images to grayscale.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>Color mode</string> <string>Color mode</string>
@@ -671,7 +671,7 @@
</font> </font>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;Resolution of target device.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Resolution of target device.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>Custom width: </string> <string>Custom width: </string>
@@ -705,10 +705,10 @@
<bool>false</bool> <bool>false</bool>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;Resolution of target device.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Resolution of target device.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="inputMask"> <property name="inputMask">
<string>0000; </string> <string>0000</string>
</property> </property>
<property name="maxLength"> <property name="maxLength">
<number>4</number> <number>4</number>
@@ -726,7 +726,7 @@
</font> </font>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;Resolution of target device.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Resolution of target device.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>Custom height: </string> <string>Custom height: </string>
@@ -760,10 +760,10 @@
<bool>false</bool> <bool>false</bool>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;Resolution of target device.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Resolution of target device.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="inputMask"> <property name="inputMask">
<string>0000; </string> <string>0000</string>
</property> </property>
<property name="maxLength"> <property name="maxLength">
<number>4</number> <number>4</number>

41
KCC.ui
View File

@@ -65,7 +65,7 @@
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>Disable image optimizations.</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Disable image optimizations.&lt;br/&gt;Input images must be already resized.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>No optimisation</string> <string>No optimisation</string>
@@ -94,7 +94,7 @@
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Enable auto-splitting of webtoons like &lt;span style=&quot; font-style:italic;&quot;&gt;Tower of God&lt;/span&gt; or &lt;span style=&quot; font-style:italic;&quot;&gt;Noblesse&lt;/span&gt;.&lt;br/&gt;Pages with a low width, high height and vertical panel flow.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Enable auto-splitting of webtoons like &lt;span style=&quot; font-style:italic;&quot;&gt;Tower of God&lt;/span&gt; or &lt;span style=&quot; font-style:italic;&quot;&gt;Noblesse&lt;/span&gt;.&lt;br/&gt;Pages with a low width, high height and vertical panel flow.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>Webtoon mode</string> <string>Webtoon mode</string>
@@ -107,7 +107,7 @@
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Create PNG files instead JPEG.&lt;br/&gt;Quality increase is not noticeable on most of devices.&lt;br/&gt;Output files &lt;span style=&quot; font-weight:600;&quot;&gt;might&lt;/span&gt; be smaller.&lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;MOBI conversion will be much slower.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Create PNG files instead JPEG.&lt;br/&gt;Quality increase is not noticeable on most of devices.&lt;br/&gt;Output files &lt;span style=&quot; font-weight:600;&quot;&gt;might&lt;/span&gt; be smaller.&lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;MOBI conversion will be much slower.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>PNG output</string> <string>PNG output</string>
@@ -136,7 +136,7 @@
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Disable splitting and rotation.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Disable splitting and rotation.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>No split/rotate</string> <string>No split/rotate</string>
@@ -163,7 +163,7 @@
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>Target device.</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Target device.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
</widget> </widget>
<widget class="QComboBox" name="FormatBox"> <widget class="QComboBox" name="FormatBox">
@@ -184,7 +184,7 @@
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>Output format.</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Output format.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
</widget> </widget>
<widget class="QPushButton" name="ConvertButton"> <widget class="QPushButton" name="ConvertButton">
@@ -206,6 +206,9 @@
<property name="focusPolicy"> <property name="focusPolicy">
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Shift+Click to select the output directory.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text"> <property name="text">
<string>Convert</string> <string>Convert</string>
</property> </property>
@@ -316,7 +319,7 @@
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>Enable right-to-left reading.</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Enable right-to-left reading.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>Manga mode</string> <string>Manga mode</string>
@@ -335,13 +338,7 @@
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt; <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Unchecked - Normal quality mode&lt;br/&gt;&lt;/span&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;Use it when Panel View support is not needed.&lt;/span&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;&lt;br/&gt;&lt;/span&gt;- Maximum quality when zoom is not enabled.&lt;br/&gt;- Poor quality when zoom is enabled.&lt;br/&gt;- Lowest file size.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Indeterminate - High quality mode&lt;br/&gt;&lt;/span&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;Not zoomed images &lt;/span&gt;&lt;span style=&quot; font-weight:600; font-style:italic;&quot;&gt;might &lt;/span&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;be blurry.&lt;/span&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;&lt;br/&gt;&lt;/span&gt;- High quality when zoom is not enabled.&lt;br/&gt;- Maximum quality when zoom is enabled.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Checked - Ultra quality mode&lt;br/&gt;&lt;/span&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;Maximum possible quality.&lt;/span&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;&lt;br/&gt;&lt;/span&gt;- Maximum quality when zoom is not enabled.&lt;br/&gt;- Maximum quality when zoom is enabled.&lt;br/&gt;- Very high file size.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Unchecked - Normal quality mode&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;Use it when Panel View support is not needed.&lt;/span&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;&lt;br /&gt;&lt;/span&gt;- Maximum quality when zoom is not enabled.&lt;br /&gt;- Poor quality when zoom is enabled.&lt;br /&gt;- Lowest file size.&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Indeterminate - High quality mode&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;Not zoomed image &lt;/span&gt;&lt;span style=&quot; font-weight:600; font-style:italic;&quot;&gt;might &lt;/span&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;be a little blurry.&lt;br /&gt;Smaller images might be forcefully upscaled in this mode.&lt;/span&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;&lt;br /&gt;&lt;/span&gt;- Medium/High quality when zoom is not enabled.&lt;br /&gt;- Maximum quality when zoom is enabled.&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Checked - Ultra quality mode&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;Maximum possible quality.&lt;/span&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;&lt;br /&gt;&lt;/span&gt;- Maximum quality when zoom is not enabled.&lt;br /&gt;- Maximum quality when zoom is enabled.&lt;br /&gt;- Very high file size.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>High/Ultra quality</string> <string>High/Ultra quality</string>
@@ -363,7 +360,7 @@ p, li { white-space: pre-wrap; }
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Disable splitting of two-page spreads.&lt;br/&gt;They will be rotated instead.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Disable splitting of two-page spreads.&lt;br/&gt;They will be rotated instead.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>Horizontal mode</string> <string>Horizontal mode</string>
@@ -549,7 +546,7 @@ p, li { white-space: pre-wrap; }
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Don't convert images to grayscale.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Don't convert images to grayscale.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>Color mode</string> <string>Color mode</string>
@@ -568,7 +565,7 @@ p, li { white-space: pre-wrap; }
<item row="0" column="0"> <item row="0" column="0">
<widget class="QLabel" name="wLabel"> <widget class="QLabel" name="wLabel">
<property name="toolTip"> <property name="toolTip">
<string>Resolution of target device.</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Resolution of target device.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>Custom width: </string> <string>Custom width: </string>
@@ -596,10 +593,10 @@ p, li { white-space: pre-wrap; }
<bool>false</bool> <bool>false</bool>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>Resolution of target device.</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Resolution of target device.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="inputMask"> <property name="inputMask">
<string>0000; </string> <string>0000</string>
</property> </property>
<property name="maxLength"> <property name="maxLength">
<number>4</number> <number>4</number>
@@ -609,7 +606,7 @@ p, li { white-space: pre-wrap; }
<item row="0" column="2"> <item row="0" column="2">
<widget class="QLabel" name="hLabel"> <widget class="QLabel" name="hLabel">
<property name="toolTip"> <property name="toolTip">
<string>Resolution of target device.</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Resolution of target device.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>Custom height: </string> <string>Custom height: </string>
@@ -637,10 +634,10 @@ p, li { white-space: pre-wrap; }
<bool>false</bool> <bool>false</bool>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>Resolution of target device.</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Resolution of target device.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="inputMask"> <property name="inputMask">
<string>0000; </string> <string>0000</string>
</property> </property>
<property name="maxLength"> <property name="maxLength">
<number>4</number> <number>4</number>

View File

@@ -1,7 +1,7 @@
ISC LICENSE ISC LICENSE
Copyright (c) 2013 Ciro Mattia Gonano <ciromattia@gmail.com> Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
Copyright (c) 2013 Paweł Jastrzębski <pawelj@vulturis.eu> Copyright (c) 2013-2014 Paweł Jastrzębski <pawelj@vulturis.eu>
Permission to use, copy, modify, and/or distribute this software for Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the any purpose with or without fee is hereby granted, provided that the

View File

@@ -24,7 +24,7 @@ If you find **KCC** valuable you can consider donating to the authors:
You can find the latest released binary at the following links: You can find the latest released binary at the following links:
- **Windows:** [http://kcc.vulturis.eu/Windows/](http://kcc.vulturis.eu/Windows/) - **Windows:** [http://kcc.vulturis.eu/Windows/](http://kcc.vulturis.eu/Windows/)
- **Linux:** [http://kcc.vulturis.eu/Linux/](http://kcc.vulturis.eu/Linux/) - **Linux:** [http://kcc.vulturis.eu/Linux/](http://kcc.vulturis.eu/Linux/)
- **OS X 10.8+:** [http://kcc.vulturis.eu/OSX/](http://kcc.vulturis.eu/OSX/) - **OS X (10.8+):** [http://kcc.vulturis.eu/OSX/](http://kcc.vulturis.eu/OSX/)
## INPUT FORMATS ## INPUT FORMATS
**KCC** can understand and convert, at the moment, the following input types: **KCC** can understand and convert, at the moment, the following input types:
@@ -39,12 +39,22 @@ You can find the latest released binary at the following links:
- [UnRAR](http://www.rarlab.com/download.htm) *(For CBR/RAR support)* - [UnRAR](http://www.rarlab.com/download.htm) *(For CBR/RAR support)*
- [7za](http://www.7-zip.org/download.html) *(For 7z/CB7 support)* - [7za](http://www.7-zip.org/download.html) *(For 7z/CB7 support)*
### For compiling/running from source: ### For 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. - Python 3.3
- [PyQt4](http://www.riverbankcomputing.co.uk/software/pyqt/download) - Please refer to official documentation for installing into your system. - [PyQt5](http://www.riverbankcomputing.co.uk/software/pyqt/download5)
- [Pillow](http://pypi.python.org/pypi/Pillow/) 2.3.0+ - For comic optimizations. Please refer to official documentation for installing into your system. - [Pillow](http://pypi.python.org/pypi/Pillow/) 2.3.0+
- [Psutil](https://code.google.com/p/psutil/) - Please refer to official documentation for installing into your system. - [psutil](https://pypi.python.org/pypi/psutil) 2.0+
- **To build OS X release you need a modified QT:** [patch](https://github.com/ciromattia/kcc/blob/master/other/QT-4.8.5-QListWidget.patch) - [python-slugify](http://pypi.python.org/pypi/python-slugify)
On Debian based distributions these two commands should install all dependencies:
```
sudo apt-get install python3 python3-dev python3-pip python3-pyqt5 libtiff-dev libpng-dev libjpeg-dev p7zip-full unrar
sudo pip3 install pillow python-slugify psutil
```
### For freezing code:
- Windows - [cx_Freeze](https://bitbucket.org/anthony_tuininga/cx_freeze) HEAD version with [this](https://bitbucket.org/anthony_tuininga/cx_freeze/pull-request/29/conversions-to-support-untranslated-wide) patchset.
- OS X - [py2app](https://bitbucket.org/ronaldoussoren/py2app) 0.8+
## USAGE ## USAGE
@@ -53,10 +63,10 @@ After completed conversion you should find ready file alongside the original inp
Please check [our wiki](https://github.com/ciromattia/kcc/wiki/) for more details. Please check [our wiki](https://github.com/ciromattia/kcc/wiki/) for more details.
### Standalone `comic2ebook.py` usage: ### Standalone `kcc-c2e.py` usage:
``` ```
Usage: comic2ebook.py [options] comic_file|comic_folder Usage: kcc-c2e [options] comic_file|comic_folder
Options: Options:
MAIN: MAIN:
@@ -95,14 +105,13 @@ Options:
Replace screen height provided by device profile Replace screen height provided by device profile
OTHER: OTHER:
-v, --verbose Verbose output
-h, --help Show this help message and exit -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: Options:
MANDATORY: MANDATORY:
@@ -312,7 +321,31 @@ The app relies and includes the following scripts/binaries:
####3.7.2: ####3.7.2:
* Fixed problems with HQ mode * Fixed problems with HQ mode
## COPYRIGHT ####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
Copyright (c) 2012-2013 Ciro Mattia Gonano and Paweł Jastrzębski. ####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
####4.0.2:
* Fixed some Windows and OSX specific bugs
* Fixed problem with marigns when using HQ mode
## KNOWN ISSUES
Please check [wiki page](https://github.com/ciromattia/kcc/wiki/Known-issues).
## COPYRIGHT
Copyright (c) 2012-2014 Ciro Mattia Gonano and Paweł Jastrzębski.
**KCC** is released under ISC LICENSE; see LICENSE.txt for further details. **KCC** is released under ISC LICENSE; see LICENSE.txt for further details.

70
kcc-c2e.py Executable file
View File

@@ -0,0 +1,70 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
# Copyright (c) 2013-2014 Pawel Jastrzebski <pawelj@vulturis.eu>
#
# 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.
__version__ = '4.0.2'
__license__ = 'ISC'
__copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
__docformat__ = 'restructuredtext en'
import sys
if sys.version_info[0] != 3:
print('ERROR: This is Python 3 script!')
exit(1)
# Dependiences check
missing = []
try:
# noinspection PyUnresolvedReferences
from psutil import virtual_memory, Popen
except ImportError:
missing.append('psutil')
try:
# noinspection PyUnresolvedReferences
from slugify import slugify
except ImportError:
missing.append('python-slugify')
try:
# noinspection PyUnresolvedReferences
from PIL import Image, ImageOps, ImageStat, ImageChops
if tuple(map(int, ('2.3.0'.split(".")))) > tuple(map(int, (Image.PILLOW_VERSION.split(".")))):
missing.append('Pillow 2.3.0+')
except ImportError:
missing.append('Pillow 2.3.0+')
if len(missing) > 0:
try:
# noinspection PyUnresolvedReferences
import tkinter
# noinspection PyUnresolvedReferences
import tkinter.messagebox
importRoot = tkinter.Tk()
importRoot.withdraw()
tkinter.messagebox.showerror('KCC - Error', 'ERROR: ' + ', '.join(missing) + ' is not installed!')
except ImportError:
print('ERROR: ' + ', '.join(missing) + ' is not installed!')
exit(1)
from multiprocessing import freeze_support
from kcc.comic2ebook import main, Copyright
if __name__ == "__main__":
freeze_support()
Copyright()
main(sys.argv[1:])
sys.exit(0)

60
kcc-c2p.py Executable file
View File

@@ -0,0 +1,60 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
# Copyright (c) 2013-2014 Pawel Jastrzebski <pawelj@vulturis.eu>
#
# 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)
__version__ = '4.0.2'
__license__ = 'ISC'
__copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
__docformat__ = 'restructuredtext en'
# Dependiences check
missing = []
try:
# noinspection PyUnresolvedReferences
from PIL import Image, ImageOps, ImageStat, ImageChops
if tuple(map(int, ('2.3.0'.split(".")))) > tuple(map(int, (Image.PILLOW_VERSION.split(".")))):
missing.append('Pillow 2.3.0+')
except ImportError:
missing.append('Pillow 2.3.0+')
if len(missing) > 0:
try:
# noinspection PyUnresolvedReferences
import tkinter
# noinspection PyUnresolvedReferences
import tkinter.messagebox
importRoot = tkinter.Tk()
importRoot.withdraw()
tkinter.messagebox.showerror('KCC - Error', 'ERROR: ' + ', '.join(missing) + ' is not installed!')
except ImportError:
print('ERROR: ' + ', '.join(missing) + ' is not installed!')
exit(1)
from multiprocessing import freeze_support
from kcc.comic2panel import main, Copyright
if __name__ == "__main__":
freeze_support()
Copyright()
main(sys.argv[1:])
sys.exit(0)

68
kcc.iss
View File

@@ -1,5 +1,5 @@
#define MyAppName "Kindle Comic Converter" #define MyAppName "Kindle Comic Converter"
#define MyAppVersion "3.7.2" #define MyAppVersion "4.0.2"
#define MyAppPublisher "Ciro Mattia Gonano, Paweł Jastrzębski" #define MyAppPublisher "Ciro Mattia Gonano, Paweł Jastrzębski"
#define MyAppURL "http://kcc.vulturis.eu/" #define MyAppURL "http://kcc.vulturis.eu/"
#define MyAppExeName "KCC.exe" #define MyAppExeName "KCC.exe"
@@ -12,7 +12,7 @@ AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL} AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL} AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL} AppUpdatesURL={#MyAppURL}
AppCopyright=Copyright (C) 2012-2013 Ciro Mattia Gonano and Paweł Jastrzębski AppCopyright=Copyright (C) 2012-2014 Ciro Mattia Gonano and Paweł Jastrzębski
DefaultDirName={pf}\{#MyAppName} DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName} DefaultGroupName={#MyAppName}
AllowNoIcons=yes AllowNoIcons=yes
@@ -42,56 +42,18 @@ Name: "CB7association"; Description: "CB7"; GroupDescription: "File associations
[Files] [Files]
; x64 files ; x64 files
Source: "build\exe.win-amd64-2.7\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion; Check: Is64BitInstallMode Source: "build\exe.win-amd64-3.3\imageformats\*"; DestDir: "{app}\imageformats\"; Flags: ignoreversion; Check: Is64BitInstallMode
Source: "build\exe.win-amd64-2.7\_ctypes.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: Is64BitInstallMode Source: "build\exe.win-amd64-3.3\platforms\*"; DestDir: "{app}\platforms\"; Flags: ignoreversion; Check: Is64BitInstallMode
Source: "build\exe.win-amd64-2.7\_hashlib.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: Is64BitInstallMode Source: "build\exe.win-amd64-3.3\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion; Check: Is64BitInstallMode
Source: "build\exe.win-amd64-2.7\_multiprocessing.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: Is64BitInstallMode Source: "build\exe.win-amd64-3.3\*.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: Is64BitInstallMode
Source: "build\exe.win-amd64-2.7\_socket.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: Is64BitInstallMode Source: "build\exe.win-amd64-3.3\*.dll"; DestDir: "{app}"; Flags: ignoreversion; Check: Is64BitInstallMode
Source: "build\exe.win-amd64-2.7\_ssl.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: Is64BitInstallMode
Source: "build\exe.win-amd64-2.7\bz2.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: Is64BitInstallMode
Source: "build\exe.win-amd64-2.7\LIBEAY32.dll"; DestDir: "{app}"; Flags: ignoreversion; Check: Is64BitInstallMode
Source: "build\exe.win-amd64-2.7\library.zip"; DestDir: "{app}"; Flags: ignoreversion; Check: Is64BitInstallMode
Source: "build\exe.win-amd64-2.7\PIL._imaging.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: Is64BitInstallMode
Source: "build\exe.win-amd64-2.7\PIL._imagingft.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: Is64BitInstallMode
Source: "build\exe.win-amd64-2.7\pyexpat.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: Is64BitInstallMode
Source: "build\exe.win-amd64-2.7\PyQt4.QtCore.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: Is64BitInstallMode
Source: "build\exe.win-amd64-2.7\PyQt4.QtGui.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: Is64BitInstallMode
Source: "build\exe.win-amd64-2.7\PyQt4.QtNetwork.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: Is64BitInstallMode
Source: "build\exe.win-amd64-2.7\python27.dll"; DestDir: "{app}"; Flags: ignoreversion; Check: Is64BitInstallMode
Source: "build\exe.win-amd64-2.7\QtCore4.dll"; DestDir: "{app}"; Flags: ignoreversion; Check: Is64BitInstallMode
Source: "build\exe.win-amd64-2.7\QtGui4.dll"; DestDir: "{app}"; Flags: ignoreversion; Check: Is64BitInstallMode
Source: "build\exe.win-amd64-2.7\QtNetwork4.dll"; DestDir: "{app}"; Flags: ignoreversion; Check: Is64BitInstallMode
Source: "build\exe.win-amd64-2.7\select.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: Is64BitInstallMode
Source: "build\exe.win-amd64-2.7\sip.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: Is64BitInstallMode
Source: "build\exe.win-amd64-2.7\SSLEAY32.dll"; DestDir: "{app}"; Flags: ignoreversion; Check: Is64BitInstallMode
Source: "build\exe.win-amd64-2.7\unicodedata.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: Is64BitInstallMode
Source: "build\exe.win-amd64-2.7\_psutil_mswindows.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: Is64BitInstallMode
Source: "other\vcredist_x64.exe"; DestDir: "{tmp}"; Flags: ignoreversion deleteafterinstall; Check: Is64BitInstallMode Source: "other\vcredist_x64.exe"; DestDir: "{tmp}"; Flags: ignoreversion deleteafterinstall; Check: Is64BitInstallMode
; x86 files ; x86 files
Source: "build\exe.win32-2.7\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion solidbreak; Check: not Is64BitInstallMode Source: "build\exe.win32-3.3\imageformats\*"; DestDir: "{app}\imageformats\"; Flags: ignoreversion; Check: not Is64BitInstallMode
Source: "build\exe.win32-2.7\_ctypes.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: not Is64BitInstallMode Source: "build\exe.win32-3.3\platforms\*"; DestDir: "{app}\platforms\"; Flags: ignoreversion; Check: not Is64BitInstallMode
Source: "build\exe.win32-2.7\_hashlib.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: not Is64BitInstallMode Source: "build\exe.win32-3.3\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion; Check: not Is64BitInstallMode
Source: "build\exe.win32-2.7\_multiprocessing.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: not Is64BitInstallMode Source: "build\exe.win32-3.3\*.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: not Is64BitInstallMode
Source: "build\exe.win32-2.7\_socket.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: not Is64BitInstallMode Source: "build\exe.win32-3.3\*.dll"; DestDir: "{app}"; Flags: ignoreversion; Check: not Is64BitInstallMode
Source: "build\exe.win32-2.7\_ssl.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: not Is64BitInstallMode
Source: "build\exe.win32-2.7\bz2.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: not Is64BitInstallMode
Source: "build\exe.win32-2.7\LIBEAY32.dll"; DestDir: "{app}"; Flags: ignoreversion; Check: not Is64BitInstallMode
Source: "build\exe.win32-2.7\library.zip"; DestDir: "{app}"; Flags: ignoreversion; Check: not Is64BitInstallMode
Source: "build\exe.win32-2.7\PIL._imaging.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: not Is64BitInstallMode
Source: "build\exe.win32-2.7\PIL._imagingft.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: not Is64BitInstallMode
Source: "build\exe.win32-2.7\pyexpat.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: not Is64BitInstallMode
Source: "build\exe.win32-2.7\PyQt4.QtCore.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: not Is64BitInstallMode
Source: "build\exe.win32-2.7\PyQt4.QtGui.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: not Is64BitInstallMode
Source: "build\exe.win32-2.7\PyQt4.QtNetwork.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: not Is64BitInstallMode
Source: "build\exe.win32-2.7\python27.dll"; DestDir: "{app}"; Flags: ignoreversion; Check: not Is64BitInstallMode
Source: "build\exe.win32-2.7\QtCore4.dll"; DestDir: "{app}"; Flags: ignoreversion; Check: not Is64BitInstallMode
Source: "build\exe.win32-2.7\QtGui4.dll"; DestDir: "{app}"; Flags: ignoreversion; Check: not Is64BitInstallMode
Source: "build\exe.win32-2.7\QtNetwork4.dll"; DestDir: "{app}"; Flags: ignoreversion; Check: not Is64BitInstallMode
Source: "build\exe.win32-2.7\select.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: not Is64BitInstallMode
Source: "build\exe.win32-2.7\sip.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: not Is64BitInstallMode
Source: "build\exe.win32-2.7\SSLEAY32.dll"; DestDir: "{app}"; Flags: ignoreversion; Check: not Is64BitInstallMode
Source: "build\exe.win32-2.7\unicodedata.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: not Is64BitInstallMode
Source: "build\exe.win32-2.7\_psutil_mswindows.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: not Is64BitInstallMode
Source: "other\vcredist_x86.exe"; DestDir: "{tmp}"; Flags: ignoreversion deleteafterinstall; Check: not Is64BitInstallMode Source: "other\vcredist_x86.exe"; DestDir: "{tmp}"; Flags: ignoreversion deleteafterinstall; Check: not Is64BitInstallMode
; Common files ; Common files
Source: "LICENSE.txt"; DestDir: "{app}"; Flags: ignoreversion solidbreak Source: "LICENSE.txt"; DestDir: "{app}"; Flags: ignoreversion solidbreak
@@ -105,9 +67,9 @@ Name: "{group}\Readme"; Filename: "https://github.com/ciromattia/kcc#kcc"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
[Run] [Run]
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent 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++ 2008 Redistributable Package..."; Check: Is64BitInstallMode 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++ 2008 Redistributable Package..."; Check: not 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] [Messages]
WelcomeLabel1=Welcome to the KCC Setup Wizard WelcomeLabel1=Welcome to the KCC Setup Wizard

138
kcc.py Normal file → Executable file
View File

@@ -1,8 +1,8 @@
#!/usr/bin/env python2 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
# Copyright (c) 2012-2013 Ciro Mattia Gonano <ciromattia@gmail.com> # Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
# Copyright (c) 2013 Pawel Jastrzebski <pawelj@vulturis.eu> # Copyright (c) 2013-2014 Pawel Jastrzebski <pawelj@vulturis.eu>
# #
# Permission to use, copy, modify, and/or distribute this software for # Permission to use, copy, modify, and/or distribute this software for
# any purpose with or without fee is hereby granted, provided that the # any purpose with or without fee is hereby granted, provided that the
@@ -18,27 +18,56 @@
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE. # PERFORMANCE OF THIS SOFTWARE.
__version__ = '3.7.2' __version__ = '4.0.2'
__license__ = 'ISC' __license__ = 'ISC'
__copyright__ = '2012-2013, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>' __copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
import sys import sys
import os if sys.version_info[0] != 3:
print('ERROR: This is Python 3 script!')
exit(1)
# Dependiences check
missing = []
try: try:
# noinspection PyUnresolvedReferences # noinspection PyUnresolvedReferences
from PyQt4 import QtCore, QtGui, QtNetwork from PyQt5 import QtCore, QtGui, QtNetwork, QtWidgets
except ImportError: except ImportError:
print "ERROR: PyQT4 is not installed!" missing.append('PyQt5')
if sys.platform.startswith('linux'): try:
import Tkinter # noinspection PyUnresolvedReferences
import tkMessageBox from psutil import virtual_memory, Popen
importRoot = Tkinter.Tk() except ImportError:
missing.append('psutil')
try:
# noinspection PyUnresolvedReferences
from slugify import slugify
except ImportError:
missing.append('python-slugify')
try:
# noinspection PyUnresolvedReferences
from PIL import Image, ImageOps, ImageStat, ImageChops
if tuple(map(int, ('2.3.0'.split(".")))) > tuple(map(int, (Image.PILLOW_VERSION.split(".")))):
missing.append('Pillow 2.3.0+')
except ImportError:
missing.append('Pillow 2.3.0+')
if len(missing) > 0:
try:
# noinspection PyUnresolvedReferences
import tkinter
# noinspection PyUnresolvedReferences
import tkinter.messagebox
importRoot = tkinter.Tk()
importRoot.withdraw() importRoot.withdraw()
tkMessageBox.showerror("KCC - Error", "PyQT4 is not installed!") tkinter.messagebox.showerror('KCC - Error', 'ERROR: ' + ', '.join(missing) + ' is not installed!')
except ImportError:
print('ERROR: ' + ', '.join(missing) + ' is not installed!')
exit(1) exit(1)
from kcc import KCC_gui
import os
from multiprocessing import freeze_support from multiprocessing import freeze_support
from kcc import KCC_gui
# OS specific PATH variable workarounds # OS specific PATH variable workarounds
if sys.platform.startswith('darwin'): if sys.platform.startswith('darwin'):
@@ -49,23 +78,34 @@ if sys.platform.startswith('darwin'):
elif sys.platform.startswith('win'): elif sys.platform.startswith('win'):
if getattr(sys, 'frozen', False): if getattr(sys, 'frozen', False):
os.chdir(os.path.dirname(os.path.abspath(sys.executable))) 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: else:
os.environ['PATH'] = os.path.dirname(os.path.abspath(__file__)) + '/other/;' + os.environ['PATH'] os.environ['PATH'] = os.path.dirname(os.path.abspath(__file__)) + '/other/;' + os.environ['PATH']
os.chdir(os.path.dirname(os.path.abspath(__file__))) os.chdir(os.path.dirname(os.path.abspath(__file__)))
# Implementing detection of already running KCC instance and forwarding argv to it # Implementing detection of already running KCC instance and forwarding argv to it
class QApplicationMessaging(QtGui.QApplication): class QApplicationMessaging(QtWidgets.QApplication):
messageFromOtherInstance = QtCore.pyqtSignal(bytes)
def __init__(self, argv): def __init__(self, argv):
QtGui.QApplication.__init__(self, argv) QtWidgets.QApplication.__init__(self, argv)
self._memory = QtCore.QSharedMemory(self) self._memory = QtCore.QSharedMemory(self)
self._memory.setKey('KCC') self._memory.setKey('KCC')
if self._memory.attach(): if self._memory.attach():
self._running = True self._running = True
else: else:
self._running = False self._running = False
if not self._memory.create(1): self._memory.create(1)
raise RuntimeError(self._memory.errorString().toLocal8Bit().data())
self._key = 'KCC' self._key = 'KCC'
self._timeout = 1000 self._timeout = 1000
self._server = QtNetwork.QLocalServer(self) self._server = QtNetwork.QLocalServer(self)
@@ -73,13 +113,26 @@ class QApplicationMessaging(QtGui.QApplication):
self._server.newConnection.connect(self.handleMessage) self._server.newConnection.connect(self.handleMessage)
self._server.listen(self._key) self._server.listen(self._key)
def __del__(self):
if self._memory.isAttached():
self._memory.detach()
self._server.close()
def event(self, e):
if e.type() == QtCore.QEvent.FileOpen:
# noinspection PyArgumentList
self.messageFromOtherInstance.emit(bytes(e.file(), 'UTF-8'))
return True
else:
return QtWidgets.QApplication.event(self, e)
def isRunning(self): def isRunning(self):
return self._running return self._running
def handleMessage(self): def handleMessage(self):
socket = self._server.nextPendingConnection() socket = self._server.nextPendingConnection()
if socket.waitForReadyRead(self._timeout): if socket.waitForReadyRead(self._timeout):
self.emit(QtCore.SIGNAL('messageFromOtherInstance'), socket.readAll().data().decode('utf8')) self.messageFromOtherInstance.emit(socket.readAll().data())
def sendMessage(self, message): def sendMessage(self, message):
if self.isRunning(): if self.isRunning():
@@ -87,28 +140,39 @@ class QApplicationMessaging(QtGui.QApplication):
socket.connectToServer(self._key, QtCore.QIODevice.WriteOnly) socket.connectToServer(self._key, QtCore.QIODevice.WriteOnly)
if not socket.waitForConnected(self._timeout): if not socket.waitForConnected(self._timeout):
return False return False
socket.write(message.encode('utf8')) # noinspection PyArgumentList
socket.write(bytes(message, 'UTF-8'))
if not socket.waitForBytesWritten(self._timeout): if not socket.waitForBytesWritten(self._timeout):
return False return False
socket.disconnectFromServer() socket.disconnectFromServer()
return True return True
return False return False
freeze_support()
KCCAplication = QApplicationMessaging(sys.argv) # Adding signals to QMainWindow
if KCCAplication.isRunning(): class QMainWindowKCC(QtWidgets.QMainWindow):
progressBarTick = QtCore.pyqtSignal(str)
modeConvert = QtCore.pyqtSignal(int)
addMessage = QtCore.pyqtSignal(str, str, bool)
addTrayMessage = QtCore.pyqtSignal(str, str)
showDialog = QtCore.pyqtSignal(str, str)
hideProgressBar = QtCore.pyqtSignal()
forceShutdown = QtCore.pyqtSignal()
dialogAnswer = QtCore.pyqtSignal(int)
if __name__ == "__main__":
freeze_support()
KCCAplication = QApplicationMessaging(sys.argv)
if KCCAplication.isRunning():
if len(sys.argv) > 1:
KCCAplication.sendMessage(sys.argv[1])
sys.exit(0)
else:
KCCAplication.sendMessage('ARISE')
sys.exit(0)
KCCWindow = QMainWindowKCC()
KCCUI = KCC_gui.KCCGUI(KCCAplication, KCCWindow)
if len(sys.argv) > 1: if len(sys.argv) > 1:
KCCAplication.sendMessage(sys.argv[1].decode(sys.getfilesystemencoding())) KCCUI.handleMessage(sys.argv[1])
sys.exit(0) sys.exit(KCCAplication.exec_())
else:
messageBox = QtGui.QMessageBox()
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(':/Icon/icons/comic2ebook.png'), QtGui.QIcon.Normal, QtGui.QIcon.Off)
messageBox.setWindowIcon(icon)
QtGui.QMessageBox.critical(messageBox, 'KCC - Error', 'KCC is already running!', QtGui.QMessageBox.Ok)
sys.exit(1)
KCCWindow = QtGui.QMainWindow()
KCCUI = KCC_gui.KCCGUI(KCCAplication, KCCWindow)
if len(sys.argv) > 1:
KCCUI.handleMessage(sys.argv[1].decode(sys.getfilesystemencoding()))
sys.exit(KCCAplication.exec_())

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -2,30 +2,16 @@
# Form implementation generated from reading ui file 'KCC.ui' # Form implementation generated from reading ui file 'KCC.ui'
# #
# Created: Tue Jan 14 15:50:02 2014 # Created: Sat Jan 25 17:36:53 2014
# by: PyQt4 UI code generator 4.10.3 # by: PyQt5 UI code generator 5.2
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui from PyQt5 import QtCore, QtGui, QtWidgets
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)
class Ui_KCC(object): class Ui_KCC(object):
def setupUi(self, KCC): def setupUi(self, KCC):
KCC.setObjectName(_fromUtf8("KCC")) KCC.setObjectName("KCC")
KCC.resize(420, 397) KCC.resize(420, 397)
KCC.setMinimumSize(QtCore.QSize(420, 397)) KCC.setMinimumSize(QtCore.QSize(420, 397))
KCC.setMaximumSize(QtCore.QSize(420, 397)) KCC.setMaximumSize(QtCore.QSize(420, 397))
@@ -33,62 +19,62 @@ class Ui_KCC(object):
font.setPointSize(9) font.setPointSize(9)
KCC.setFont(font) KCC.setFont(font)
icon = QtGui.QIcon() 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.setWindowIcon(icon)
KCC.setLocale(QtCore.QLocale(QtCore.QLocale.C, QtCore.QLocale.AnyCountry)) KCC.setLocale(QtCore.QLocale(QtCore.QLocale.C, QtCore.QLocale.AnyCountry))
self.Form = QtGui.QWidget(KCC) self.Form = QtWidgets.QWidget(KCC)
self.Form.setObjectName(_fromUtf8("Form")) self.Form.setObjectName("Form")
self.OptionsAdvanced = QtGui.QFrame(self.Form) self.OptionsAdvanced = QtWidgets.QFrame(self.Form)
self.OptionsAdvanced.setEnabled(True) self.OptionsAdvanced.setEnabled(True)
self.OptionsAdvanced.setGeometry(QtCore.QRect(10, 254, 421, 61)) self.OptionsAdvanced.setGeometry(QtCore.QRect(10, 254, 421, 61))
font = QtGui.QFont() font = QtGui.QFont()
font.setPointSize(9) font.setPointSize(9)
self.OptionsAdvanced.setFont(font) self.OptionsAdvanced.setFont(font)
self.OptionsAdvanced.setObjectName(_fromUtf8("OptionsAdvanced")) self.OptionsAdvanced.setObjectName("OptionsAdvanced")
self.gridLayout = QtGui.QGridLayout(self.OptionsAdvanced) self.gridLayout = QtWidgets.QGridLayout(self.OptionsAdvanced)
self.gridLayout.setContentsMargins(9, -1, -1, -1) self.gridLayout.setContentsMargins(9, -1, -1, -1)
self.gridLayout.setObjectName(_fromUtf8("gridLayout")) self.gridLayout.setObjectName("gridLayout")
self.ProcessingBox = QtGui.QCheckBox(self.OptionsAdvanced) self.ProcessingBox = QtWidgets.QCheckBox(self.OptionsAdvanced)
self.ProcessingBox.setFocusPolicy(QtCore.Qt.NoFocus) 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.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.setFocusPolicy(QtCore.Qt.NoFocus)
self.UpscaleBox.setTristate(True) self.UpscaleBox.setTristate(True)
self.UpscaleBox.setObjectName(_fromUtf8("UpscaleBox")) self.UpscaleBox.setObjectName("UpscaleBox")
self.gridLayout.addWidget(self.UpscaleBox, 1, 1, 1, 1) 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.setFocusPolicy(QtCore.Qt.NoFocus)
self.WebtoonBox.setObjectName(_fromUtf8("WebtoonBox")) self.WebtoonBox.setObjectName("WebtoonBox")
self.gridLayout.addWidget(self.WebtoonBox, 3, 1, 1, 1) 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.setFocusPolicy(QtCore.Qt.NoFocus)
self.NoDitheringBox.setObjectName(_fromUtf8("NoDitheringBox")) self.NoDitheringBox.setObjectName("NoDitheringBox")
self.gridLayout.addWidget(self.NoDitheringBox, 3, 2, 1, 1) 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.setFocusPolicy(QtCore.Qt.NoFocus)
self.BorderBox.setTristate(True) self.BorderBox.setTristate(True)
self.BorderBox.setObjectName(_fromUtf8("BorderBox")) self.BorderBox.setObjectName("BorderBox")
self.gridLayout.addWidget(self.BorderBox, 3, 0, 1, 1) 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.setFocusPolicy(QtCore.Qt.NoFocus)
self.NoRotateBox.setObjectName(_fromUtf8("NoRotateBox")) self.NoRotateBox.setObjectName("NoRotateBox")
self.gridLayout.addWidget(self.NoRotateBox, 1, 2, 1, 1) 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)) self.DeviceBox.setGeometry(QtCore.QRect(10, 200, 141, 31))
font = QtGui.QFont() font = QtGui.QFont()
font.setPointSize(8) font.setPointSize(8)
self.DeviceBox.setFont(font) self.DeviceBox.setFont(font)
self.DeviceBox.setFocusPolicy(QtCore.Qt.NoFocus) self.DeviceBox.setFocusPolicy(QtCore.Qt.NoFocus)
self.DeviceBox.setObjectName(_fromUtf8("DeviceBox")) self.DeviceBox.setObjectName("DeviceBox")
self.FormatBox = QtGui.QComboBox(self.Form) self.FormatBox = QtWidgets.QComboBox(self.Form)
self.FormatBox.setGeometry(QtCore.QRect(260, 200, 151, 31)) self.FormatBox.setGeometry(QtCore.QRect(260, 200, 151, 31))
font = QtGui.QFont() font = QtGui.QFont()
font.setPointSize(8) font.setPointSize(8)
self.FormatBox.setFont(font) self.FormatBox.setFont(font)
self.FormatBox.setFocusPolicy(QtCore.Qt.NoFocus) self.FormatBox.setFocusPolicy(QtCore.Qt.NoFocus)
self.FormatBox.setObjectName(_fromUtf8("FormatBox")) self.FormatBox.setObjectName("FormatBox")
self.ConvertButton = QtGui.QPushButton(self.Form) self.ConvertButton = QtWidgets.QPushButton(self.Form)
self.ConvertButton.setGeometry(QtCore.QRect(160, 200, 91, 32)) self.ConvertButton.setGeometry(QtCore.QRect(160, 200, 91, 32))
font = QtGui.QFont() font = QtGui.QFont()
font.setPointSize(9) font.setPointSize(9)
@@ -97,99 +83,99 @@ class Ui_KCC(object):
self.ConvertButton.setFont(font) self.ConvertButton.setFont(font)
self.ConvertButton.setFocusPolicy(QtCore.Qt.NoFocus) self.ConvertButton.setFocusPolicy(QtCore.Qt.NoFocus)
icon1 = QtGui.QIcon() 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.setIcon(icon1)
self.ConvertButton.setObjectName(_fromUtf8("ConvertButton")) self.ConvertButton.setObjectName("ConvertButton")
self.DirectoryButton = QtGui.QPushButton(self.Form) self.DirectoryButton = QtWidgets.QPushButton(self.Form)
self.DirectoryButton.setGeometry(QtCore.QRect(10, 160, 141, 32)) self.DirectoryButton.setGeometry(QtCore.QRect(10, 160, 141, 32))
font = QtGui.QFont() font = QtGui.QFont()
font.setPointSize(8) font.setPointSize(8)
self.DirectoryButton.setFont(font) self.DirectoryButton.setFont(font)
self.DirectoryButton.setFocusPolicy(QtCore.Qt.NoFocus) self.DirectoryButton.setFocusPolicy(QtCore.Qt.NoFocus)
icon2 = QtGui.QIcon() 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.setIcon(icon2)
self.DirectoryButton.setObjectName(_fromUtf8("DirectoryButton")) self.DirectoryButton.setObjectName("DirectoryButton")
self.FileButton = QtGui.QPushButton(self.Form) self.FileButton = QtWidgets.QPushButton(self.Form)
self.FileButton.setGeometry(QtCore.QRect(260, 160, 151, 32)) self.FileButton.setGeometry(QtCore.QRect(260, 160, 151, 32))
font = QtGui.QFont() font = QtGui.QFont()
font.setPointSize(8) font.setPointSize(8)
self.FileButton.setFont(font) self.FileButton.setFont(font)
self.FileButton.setFocusPolicy(QtCore.Qt.NoFocus) self.FileButton.setFocusPolicy(QtCore.Qt.NoFocus)
icon3 = QtGui.QIcon() 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.setIcon(icon3)
self.FileButton.setObjectName(_fromUtf8("FileButton")) self.FileButton.setObjectName("FileButton")
self.ClearButton = QtGui.QPushButton(self.Form) self.ClearButton = QtWidgets.QPushButton(self.Form)
self.ClearButton.setGeometry(QtCore.QRect(160, 160, 91, 32)) self.ClearButton.setGeometry(QtCore.QRect(160, 160, 91, 32))
font = QtGui.QFont() font = QtGui.QFont()
font.setPointSize(8) font.setPointSize(8)
self.ClearButton.setFont(font) self.ClearButton.setFont(font)
self.ClearButton.setFocusPolicy(QtCore.Qt.NoFocus) self.ClearButton.setFocusPolicy(QtCore.Qt.NoFocus)
icon4 = QtGui.QIcon() 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.setIcon(icon4)
self.ClearButton.setObjectName(_fromUtf8("ClearButton")) self.ClearButton.setObjectName("ClearButton")
self.OptionsBasic = QtGui.QFrame(self.Form) self.OptionsBasic = QtWidgets.QFrame(self.Form)
self.OptionsBasic.setGeometry(QtCore.QRect(10, 230, 421, 41)) self.OptionsBasic.setGeometry(QtCore.QRect(10, 230, 421, 41))
font = QtGui.QFont() font = QtGui.QFont()
font.setPointSize(9) font.setPointSize(9)
self.OptionsBasic.setFont(font) self.OptionsBasic.setFont(font)
self.OptionsBasic.setObjectName(_fromUtf8("OptionsBasic")) self.OptionsBasic.setObjectName("OptionsBasic")
self.MangaBox = QtGui.QCheckBox(self.OptionsBasic) self.MangaBox = QtWidgets.QCheckBox(self.OptionsBasic)
self.MangaBox.setGeometry(QtCore.QRect(9, 10, 130, 18)) self.MangaBox.setGeometry(QtCore.QRect(9, 10, 130, 18))
self.MangaBox.setFocusPolicy(QtCore.Qt.NoFocus) self.MangaBox.setFocusPolicy(QtCore.Qt.NoFocus)
self.MangaBox.setObjectName(_fromUtf8("MangaBox")) self.MangaBox.setObjectName("MangaBox")
self.QualityBox = QtGui.QCheckBox(self.OptionsBasic) self.QualityBox = QtWidgets.QCheckBox(self.OptionsBasic)
self.QualityBox.setGeometry(QtCore.QRect(282, 10, 130, 18)) self.QualityBox.setGeometry(QtCore.QRect(282, 10, 130, 18))
self.QualityBox.setFocusPolicy(QtCore.Qt.NoFocus) self.QualityBox.setFocusPolicy(QtCore.Qt.NoFocus)
self.QualityBox.setTristate(True) self.QualityBox.setTristate(True)
self.QualityBox.setObjectName(_fromUtf8("QualityBox")) self.QualityBox.setObjectName("QualityBox")
self.RotateBox = QtGui.QCheckBox(self.OptionsBasic) self.RotateBox = QtWidgets.QCheckBox(self.OptionsBasic)
self.RotateBox.setGeometry(QtCore.QRect(145, 10, 130, 18)) self.RotateBox.setGeometry(QtCore.QRect(145, 10, 130, 18))
self.RotateBox.setFocusPolicy(QtCore.Qt.NoFocus) self.RotateBox.setFocusPolicy(QtCore.Qt.NoFocus)
self.RotateBox.setObjectName(_fromUtf8("RotateBox")) self.RotateBox.setObjectName("RotateBox")
self.JobList = QtGui.QListWidget(self.Form) self.JobList = QtWidgets.QListWidget(self.Form)
self.JobList.setGeometry(QtCore.QRect(10, 50, 401, 101)) self.JobList.setGeometry(QtCore.QRect(10, 50, 401, 101))
self.JobList.setFocusPolicy(QtCore.Qt.NoFocus) self.JobList.setFocusPolicy(QtCore.Qt.NoFocus)
self.JobList.setStyleSheet(_fromUtf8("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.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.setProperty("showDropIndicator", False)
self.JobList.setSelectionMode(QtGui.QAbstractItemView.NoSelection) self.JobList.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
self.JobList.setVerticalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel) self.JobList.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
self.JobList.setHorizontalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel) self.JobList.setHorizontalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
self.JobList.setObjectName(_fromUtf8("JobList")) self.JobList.setObjectName("JobList")
self.BasicModeButton = QtGui.QPushButton(self.Form) self.BasicModeButton = QtWidgets.QPushButton(self.Form)
self.BasicModeButton.setGeometry(QtCore.QRect(10, 10, 195, 32)) self.BasicModeButton.setGeometry(QtCore.QRect(10, 10, 195, 32))
font = QtGui.QFont() font = QtGui.QFont()
font.setPointSize(9) font.setPointSize(9)
self.BasicModeButton.setFont(font) self.BasicModeButton.setFont(font)
self.BasicModeButton.setFocusPolicy(QtCore.Qt.NoFocus) self.BasicModeButton.setFocusPolicy(QtCore.Qt.NoFocus)
self.BasicModeButton.setObjectName(_fromUtf8("BasicModeButton")) self.BasicModeButton.setObjectName("BasicModeButton")
self.AdvModeButton = QtGui.QPushButton(self.Form) self.AdvModeButton = QtWidgets.QPushButton(self.Form)
self.AdvModeButton.setGeometry(QtCore.QRect(217, 10, 195, 32)) self.AdvModeButton.setGeometry(QtCore.QRect(217, 10, 195, 32))
font = QtGui.QFont() font = QtGui.QFont()
font.setPointSize(9) font.setPointSize(9)
self.AdvModeButton.setFont(font) self.AdvModeButton.setFont(font)
self.AdvModeButton.setFocusPolicy(QtCore.Qt.NoFocus) self.AdvModeButton.setFocusPolicy(QtCore.Qt.NoFocus)
self.AdvModeButton.setObjectName(_fromUtf8("AdvModeButton")) self.AdvModeButton.setObjectName("AdvModeButton")
self.OptionsAdvancedGamma = QtGui.QFrame(self.Form) self.OptionsAdvancedGamma = QtWidgets.QFrame(self.Form)
self.OptionsAdvancedGamma.setEnabled(True) self.OptionsAdvancedGamma.setEnabled(True)
self.OptionsAdvancedGamma.setGeometry(QtCore.QRect(10, 305, 401, 41)) self.OptionsAdvancedGamma.setGeometry(QtCore.QRect(10, 305, 401, 41))
font = QtGui.QFont() font = QtGui.QFont()
font.setPointSize(9) font.setPointSize(9)
self.OptionsAdvancedGamma.setFont(font) self.OptionsAdvancedGamma.setFont(font)
self.OptionsAdvancedGamma.setObjectName(_fromUtf8("OptionsAdvancedGamma")) self.OptionsAdvancedGamma.setObjectName("OptionsAdvancedGamma")
self.GammaLabel = QtGui.QLabel(self.OptionsAdvancedGamma) self.GammaLabel = QtWidgets.QLabel(self.OptionsAdvancedGamma)
self.GammaLabel.setGeometry(QtCore.QRect(15, 0, 100, 40)) self.GammaLabel.setGeometry(QtCore.QRect(15, 0, 100, 40))
self.GammaLabel.setObjectName(_fromUtf8("GammaLabel")) self.GammaLabel.setObjectName("GammaLabel")
self.GammaSlider = QtGui.QSlider(self.OptionsAdvancedGamma) self.GammaSlider = QtWidgets.QSlider(self.OptionsAdvancedGamma)
self.GammaSlider.setGeometry(QtCore.QRect(110, 10, 270, 22)) self.GammaSlider.setGeometry(QtCore.QRect(110, 10, 270, 22))
self.GammaSlider.setFocusPolicy(QtCore.Qt.ClickFocus) self.GammaSlider.setFocusPolicy(QtCore.Qt.ClickFocus)
self.GammaSlider.setMaximum(500) self.GammaSlider.setMaximum(500)
self.GammaSlider.setSingleStep(5) self.GammaSlider.setSingleStep(5)
self.GammaSlider.setOrientation(QtCore.Qt.Horizontal) self.GammaSlider.setOrientation(QtCore.Qt.Horizontal)
self.GammaSlider.setObjectName(_fromUtf8("GammaSlider")) self.GammaSlider.setObjectName("GammaSlider")
self.ProgressBar = QtGui.QProgressBar(self.Form) self.ProgressBar = QtWidgets.QProgressBar(self.Form)
self.ProgressBar.setGeometry(QtCore.QRect(10, 10, 401, 31)) self.ProgressBar.setGeometry(QtCore.QRect(10, 10, 401, 31))
font = QtGui.QFont() font = QtGui.QFont()
font.setPointSize(10) font.setPointSize(10)
@@ -198,28 +184,28 @@ class Ui_KCC(object):
self.ProgressBar.setFont(font) self.ProgressBar.setFont(font)
self.ProgressBar.setProperty("value", 0) self.ProgressBar.setProperty("value", 0)
self.ProgressBar.setAlignment(QtCore.Qt.AlignJustify|QtCore.Qt.AlignVCenter) self.ProgressBar.setAlignment(QtCore.Qt.AlignJustify|QtCore.Qt.AlignVCenter)
self.ProgressBar.setFormat(_fromUtf8("")) self.ProgressBar.setFormat("")
self.ProgressBar.setObjectName(_fromUtf8("ProgressBar")) self.ProgressBar.setObjectName("ProgressBar")
self.OptionsExpert = QtGui.QFrame(self.Form) self.OptionsExpert = QtWidgets.QFrame(self.Form)
self.OptionsExpert.setGeometry(QtCore.QRect(10, 337, 421, 41)) self.OptionsExpert.setGeometry(QtCore.QRect(10, 337, 421, 41))
font = QtGui.QFont() font = QtGui.QFont()
font.setPointSize(9) font.setPointSize(9)
self.OptionsExpert.setFont(font) self.OptionsExpert.setFont(font)
self.OptionsExpert.setObjectName(_fromUtf8("OptionsExpert")) self.OptionsExpert.setObjectName("OptionsExpert")
self.ColorBox = QtGui.QCheckBox(self.OptionsExpert) self.ColorBox = QtWidgets.QCheckBox(self.OptionsExpert)
self.ColorBox.setGeometry(QtCore.QRect(9, 11, 130, 18)) self.ColorBox.setGeometry(QtCore.QRect(9, 11, 130, 18))
self.ColorBox.setFocusPolicy(QtCore.Qt.NoFocus) self.ColorBox.setFocusPolicy(QtCore.Qt.NoFocus)
self.ColorBox.setObjectName(_fromUtf8("ColorBox")) self.ColorBox.setObjectName("ColorBox")
self.OptionsExpertInternal = QtGui.QFrame(self.OptionsExpert) self.OptionsExpertInternal = QtWidgets.QFrame(self.OptionsExpert)
self.OptionsExpertInternal.setGeometry(QtCore.QRect(100, 0, 295, 40)) self.OptionsExpertInternal.setGeometry(QtCore.QRect(100, 0, 295, 40))
self.OptionsExpertInternal.setObjectName(_fromUtf8("OptionsExpertInternal")) self.OptionsExpertInternal.setObjectName("OptionsExpertInternal")
self.gridLayout_2 = QtGui.QGridLayout(self.OptionsExpertInternal) self.gridLayout_2 = QtWidgets.QGridLayout(self.OptionsExpertInternal)
self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2")) self.gridLayout_2.setObjectName("gridLayout_2")
self.wLabel = QtGui.QLabel(self.OptionsExpertInternal) self.wLabel = QtWidgets.QLabel(self.OptionsExpertInternal)
self.wLabel.setObjectName(_fromUtf8("wLabel")) self.wLabel.setObjectName("wLabel")
self.gridLayout_2.addWidget(self.wLabel, 0, 0, 1, 1) self.gridLayout_2.addWidget(self.wLabel, 0, 0, 1, 1)
self.customWidth = QtGui.QLineEdit(self.OptionsExpertInternal) self.customWidth = QtWidgets.QLineEdit(self.OptionsExpertInternal)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.customWidth.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(self.customWidth.sizePolicy().hasHeightForWidth())
@@ -228,13 +214,13 @@ class Ui_KCC(object):
self.customWidth.setFocusPolicy(QtCore.Qt.ClickFocus) self.customWidth.setFocusPolicy(QtCore.Qt.ClickFocus)
self.customWidth.setAcceptDrops(False) self.customWidth.setAcceptDrops(False)
self.customWidth.setMaxLength(4) self.customWidth.setMaxLength(4)
self.customWidth.setObjectName(_fromUtf8("customWidth")) self.customWidth.setObjectName("customWidth")
self.gridLayout_2.addWidget(self.customWidth, 0, 1, 1, 1) self.gridLayout_2.addWidget(self.customWidth, 0, 1, 1, 1)
self.hLabel = QtGui.QLabel(self.OptionsExpertInternal) self.hLabel = QtWidgets.QLabel(self.OptionsExpertInternal)
self.hLabel.setObjectName(_fromUtf8("hLabel")) self.hLabel.setObjectName("hLabel")
self.gridLayout_2.addWidget(self.hLabel, 0, 2, 1, 1) self.gridLayout_2.addWidget(self.hLabel, 0, 2, 1, 1)
self.customHeight = QtGui.QLineEdit(self.OptionsExpertInternal) self.customHeight = QtWidgets.QLineEdit(self.OptionsExpertInternal)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.customHeight.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(self.customHeight.sizePolicy().hasHeightForWidth())
@@ -243,27 +229,27 @@ class Ui_KCC(object):
self.customHeight.setFocusPolicy(QtCore.Qt.ClickFocus) self.customHeight.setFocusPolicy(QtCore.Qt.ClickFocus)
self.customHeight.setAcceptDrops(False) self.customHeight.setAcceptDrops(False)
self.customHeight.setMaxLength(4) self.customHeight.setMaxLength(4)
self.customHeight.setObjectName(_fromUtf8("customHeight")) self.customHeight.setObjectName("customHeight")
self.gridLayout_2.addWidget(self.customHeight, 0, 3, 1, 1) self.gridLayout_2.addWidget(self.customHeight, 0, 3, 1, 1)
KCC.setCentralWidget(self.Form) KCC.setCentralWidget(self.Form)
self.statusBar = QtGui.QStatusBar(KCC) self.statusBar = QtWidgets.QStatusBar(KCC)
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("MS Shell Dlg 2")) font.setFamily("MS Shell Dlg 2")
font.setPointSize(8) font.setPointSize(8)
self.statusBar.setFont(font) self.statusBar.setFont(font)
self.statusBar.setSizeGripEnabled(False) self.statusBar.setSizeGripEnabled(False)
self.statusBar.setObjectName(_fromUtf8("statusBar")) self.statusBar.setObjectName("statusBar")
KCC.setStatusBar(self.statusBar) KCC.setStatusBar(self.statusBar)
self.ActionBasic = QtGui.QAction(KCC) self.ActionBasic = QtWidgets.QAction(KCC)
self.ActionBasic.setCheckable(True) self.ActionBasic.setCheckable(True)
self.ActionBasic.setChecked(False) self.ActionBasic.setChecked(False)
font = QtGui.QFont() font = QtGui.QFont()
font.setPointSize(9) font.setPointSize(9)
self.ActionBasic.setFont(font) self.ActionBasic.setFont(font)
self.ActionBasic.setObjectName(_fromUtf8("ActionBasic")) self.ActionBasic.setObjectName("ActionBasic")
self.ActionAdvanced = QtGui.QAction(KCC) self.ActionAdvanced = QtWidgets.QAction(KCC)
self.ActionAdvanced.setCheckable(True) self.ActionAdvanced.setCheckable(True)
self.ActionAdvanced.setObjectName(_fromUtf8("ActionAdvanced")) self.ActionAdvanced.setObjectName("ActionAdvanced")
self.retranslateUi(KCC) self.retranslateUi(KCC)
QtCore.QMetaObject.connectSlotsByName(KCC) QtCore.QMetaObject.connectSlotsByName(KCC)
@@ -272,51 +258,47 @@ class Ui_KCC(object):
KCC.setTabOrder(self.ConvertButton, self.ClearButton) KCC.setTabOrder(self.ConvertButton, self.ClearButton)
def retranslateUi(self, KCC): def retranslateUi(self, KCC):
KCC.setWindowTitle(_translate("KCC", "Kindle Comic Converter", None)) _translate = QtCore.QCoreApplication.translate
self.ProcessingBox.setToolTip(_translate("KCC", "Disable image optimizations.", None)) KCC.setWindowTitle(_translate("KCC", "Kindle Comic Converter"))
self.ProcessingBox.setText(_translate("KCC", "No optimisation", None)) self.ProcessingBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Disable image optimizations.<br/>Input images must be already resized.</p></body></html>"))
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.ProcessingBox.setText(_translate("KCC", "No optimisation"))
self.UpscaleBox.setText(_translate("KCC", "Stretch/Upscale", 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>"))
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.UpscaleBox.setText(_translate("KCC", "Stretch/Upscale"))
self.WebtoonBox.setText(_translate("KCC", "Webtoon mode", None)) self.WebtoonBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>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>"))
self.NoDitheringBox.setToolTip(_translate("KCC", "<html><head/><body><p>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>", None)) self.WebtoonBox.setText(_translate("KCC", "Webtoon mode"))
self.NoDitheringBox.setText(_translate("KCC", "PNG output", None)) 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.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.NoDitheringBox.setText(_translate("KCC", "PNG output"))
self.BorderBox.setText(_translate("KCC", "W/B margins", 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>"))
self.NoRotateBox.setToolTip(_translate("KCC", "<html><head/><body><p>Disable splitting and rotation.</p></body></html>", None)) self.BorderBox.setText(_translate("KCC", "W/B margins"))
self.NoRotateBox.setText(_translate("KCC", "No split/rotate", None)) self.NoRotateBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Disable splitting and rotation.</p></body></html>"))
self.DeviceBox.setToolTip(_translate("KCC", "Target device.", None)) self.NoRotateBox.setText(_translate("KCC", "No split/rotate"))
self.FormatBox.setToolTip(_translate("KCC", "Output format.", None)) self.DeviceBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Target device.</p></body></html>"))
self.ConvertButton.setText(_translate("KCC", "Convert", None)) self.FormatBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Output format.</p></body></html>"))
self.DirectoryButton.setText(_translate("KCC", "Add directory", None)) self.ConvertButton.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Shift+Click to select the output directory.</p></body></html>"))
self.FileButton.setText(_translate("KCC", "Add file", None)) self.ConvertButton.setText(_translate("KCC", "Convert"))
self.ClearButton.setText(_translate("KCC", "Clear list", None)) self.DirectoryButton.setText(_translate("KCC", "Add directory"))
self.MangaBox.setToolTip(_translate("KCC", "Enable right-to-left reading.", None)) self.FileButton.setText(_translate("KCC", "Add file"))
self.MangaBox.setText(_translate("KCC", "Manga mode", None)) self.ClearButton.setText(_translate("KCC", "Clear list"))
self.QualityBox.setToolTip(_translate("KCC", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n" self.MangaBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Enable right-to-left reading.</p></body></html>"))
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n" self.MangaBox.setText(_translate("KCC", "Manga mode"))
"p, li { white-space: pre-wrap; }\n" self.QualityBox.setToolTip(_translate("KCC", "<html><head/><body><p><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><span style=\" font-weight:600; text-decoration: underline;\">Indeterminate - High quality mode<br/></span><span style=\" font-style:italic;\">Not zoomed images </span><span style=\" font-weight:600; font-style:italic;\">might </span><span style=\" font-style:italic;\">be blurry.</span><span style=\" font-weight:600; text-decoration: underline;\"><br/></span>- High quality when zoom is not enabled.<br/>- Maximum quality when zoom is enabled.</p><p><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>"))
"</style></head><body style=\" font-family:\'MS Shell Dlg 2\'; font-size:8pt; font-weight:400; font-style:normal;\">\n" self.QualityBox.setText(_translate("KCC", "High/Ultra quality"))
"<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" 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>"))
"<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 a little blurry.<br />Smaller images might be forcefully upscaled in this mode.</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" self.RotateBox.setText(_translate("KCC", "Horizontal mode"))
"<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.BasicModeButton.setText(_translate("KCC", "Basic"))
self.QualityBox.setText(_translate("KCC", "High/Ultra quality", None)) self.AdvModeButton.setText(_translate("KCC", "Advanced"))
self.RotateBox.setToolTip(_translate("KCC", "<html><head/><body><p>Disable splitting of two-page spreads.<br/>They will be rotated instead.</p></body></html>", None)) self.GammaLabel.setText(_translate("KCC", "Gamma: Auto"))
self.RotateBox.setText(_translate("KCC", "Horizontal mode", None)) self.ColorBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Don\'t convert images to grayscale.</p></body></html>"))
self.BasicModeButton.setText(_translate("KCC", "Basic", None)) self.ColorBox.setText(_translate("KCC", "Color mode"))
self.AdvModeButton.setText(_translate("KCC", "Advanced", None)) self.wLabel.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Resolution of target device.</p></body></html>"))
self.GammaLabel.setText(_translate("KCC", "Gamma: Auto", None)) self.wLabel.setText(_translate("KCC", "Custom width: "))
self.ColorBox.setToolTip(_translate("KCC", "<html><head/><body><p>Don\'t convert images to grayscale.</p></body></html>", None)) self.customWidth.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Resolution of target device.</p></body></html>"))
self.ColorBox.setText(_translate("KCC", "Color mode", None)) self.customWidth.setInputMask(_translate("KCC", "0000"))
self.wLabel.setToolTip(_translate("KCC", "Resolution of target device.", None)) self.hLabel.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: ", None)) self.hLabel.setText(_translate("KCC", "Custom height: "))
self.customWidth.setToolTip(_translate("KCC", "Resolution of target device.", None)) self.customHeight.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Resolution of target device.</p></body></html>"))
self.customWidth.setInputMask(_translate("KCC", "0000; ", None)) self.customHeight.setInputMask(_translate("KCC", "0000"))
self.hLabel.setToolTip(_translate("KCC", "Resolution of target device.", None)) self.ActionBasic.setText(_translate("KCC", "Basic"))
self.hLabel.setText(_translate("KCC", "Custom height: ", None)) self.ActionAdvanced.setText(_translate("KCC", "Advanced"))
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))
import KCC_rc from . import KCC_rc

View File

@@ -2,30 +2,16 @@
# Form implementation generated from reading ui file 'KCC-Linux.ui' # Form implementation generated from reading ui file 'KCC-Linux.ui'
# #
# Created: Tue Jan 14 15:50:14 2014 # Created: Sat Jan 25 17:37:02 2014
# by: PyQt4 UI code generator 4.10.3 # by: PyQt5 UI code generator 5.2
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui from PyQt5 import QtCore, QtGui, QtWidgets
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)
class Ui_KCC(object): class Ui_KCC(object):
def setupUi(self, KCC): def setupUi(self, KCC):
KCC.setObjectName(_fromUtf8("KCC")) KCC.setObjectName("KCC")
KCC.resize(420, 397) KCC.resize(420, 397)
KCC.setMinimumSize(QtCore.QSize(420, 397)) KCC.setMinimumSize(QtCore.QSize(420, 397))
KCC.setMaximumSize(QtCore.QSize(420, 397)) KCC.setMaximumSize(QtCore.QSize(420, 397))
@@ -33,306 +19,306 @@ class Ui_KCC(object):
font.setPointSize(9) font.setPointSize(9)
KCC.setFont(font) KCC.setFont(font)
icon = QtGui.QIcon() 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.setWindowIcon(icon)
KCC.setLocale(QtCore.QLocale(QtCore.QLocale.C, QtCore.QLocale.AnyCountry)) KCC.setLocale(QtCore.QLocale(QtCore.QLocale.C, QtCore.QLocale.AnyCountry))
self.Form = QtGui.QWidget(KCC) self.Form = QtWidgets.QWidget(KCC)
self.Form.setObjectName(_fromUtf8("Form")) self.Form.setObjectName("Form")
self.OptionsAdvanced = QtGui.QFrame(self.Form) self.OptionsAdvanced = QtWidgets.QFrame(self.Form)
self.OptionsAdvanced.setEnabled(True) self.OptionsAdvanced.setEnabled(True)
self.OptionsAdvanced.setGeometry(QtCore.QRect(1, 254, 421, 61)) self.OptionsAdvanced.setGeometry(QtCore.QRect(1, 254, 421, 61))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("DejaVu Sans")) font.setFamily("DejaVu Sans")
font.setPointSize(9) font.setPointSize(9)
self.OptionsAdvanced.setFont(font) self.OptionsAdvanced.setFont(font)
self.OptionsAdvanced.setObjectName(_fromUtf8("OptionsAdvanced")) self.OptionsAdvanced.setObjectName("OptionsAdvanced")
self.gridLayout = QtGui.QGridLayout(self.OptionsAdvanced) self.gridLayout = QtWidgets.QGridLayout(self.OptionsAdvanced)
self.gridLayout.setContentsMargins(9, -1, -1, -1) self.gridLayout.setContentsMargins(9, -1, -1, -1)
self.gridLayout.setObjectName(_fromUtf8("gridLayout")) self.gridLayout.setObjectName("gridLayout")
self.ProcessingBox = QtGui.QCheckBox(self.OptionsAdvanced) self.ProcessingBox = QtWidgets.QCheckBox(self.OptionsAdvanced)
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("DejaVu Sans")) font.setFamily("DejaVu Sans")
self.ProcessingBox.setFont(font) self.ProcessingBox.setFont(font)
self.ProcessingBox.setFocusPolicy(QtCore.Qt.NoFocus) 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.gridLayout.addWidget(self.ProcessingBox, 1, 0, 1, 1)
self.UpscaleBox = QtGui.QCheckBox(self.OptionsAdvanced) self.UpscaleBox = QtWidgets.QCheckBox(self.OptionsAdvanced)
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("DejaVu Sans")) font.setFamily("DejaVu Sans")
self.UpscaleBox.setFont(font) self.UpscaleBox.setFont(font)
self.UpscaleBox.setFocusPolicy(QtCore.Qt.NoFocus) self.UpscaleBox.setFocusPolicy(QtCore.Qt.NoFocus)
self.UpscaleBox.setTristate(True) self.UpscaleBox.setTristate(True)
self.UpscaleBox.setObjectName(_fromUtf8("UpscaleBox")) self.UpscaleBox.setObjectName("UpscaleBox")
self.gridLayout.addWidget(self.UpscaleBox, 1, 1, 1, 1) 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 = QtGui.QFont()
font.setFamily(_fromUtf8("DejaVu Sans")) font.setFamily("DejaVu Sans")
self.WebtoonBox.setFont(font) self.WebtoonBox.setFont(font)
self.WebtoonBox.setFocusPolicy(QtCore.Qt.NoFocus) 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.gridLayout.addWidget(self.WebtoonBox, 3, 1, 1, 1)
self.NoDitheringBox = QtGui.QCheckBox(self.OptionsAdvanced) self.NoDitheringBox = QtWidgets.QCheckBox(self.OptionsAdvanced)
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("DejaVu Sans")) font.setFamily("DejaVu Sans")
self.NoDitheringBox.setFont(font) self.NoDitheringBox.setFont(font)
self.NoDitheringBox.setFocusPolicy(QtCore.Qt.NoFocus) 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.gridLayout.addWidget(self.NoDitheringBox, 3, 2, 1, 1)
self.BorderBox = QtGui.QCheckBox(self.OptionsAdvanced) self.BorderBox = QtWidgets.QCheckBox(self.OptionsAdvanced)
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("DejaVu Sans")) font.setFamily("DejaVu Sans")
self.BorderBox.setFont(font) self.BorderBox.setFont(font)
self.BorderBox.setFocusPolicy(QtCore.Qt.NoFocus) self.BorderBox.setFocusPolicy(QtCore.Qt.NoFocus)
self.BorderBox.setTristate(True) self.BorderBox.setTristate(True)
self.BorderBox.setObjectName(_fromUtf8("BorderBox")) self.BorderBox.setObjectName("BorderBox")
self.gridLayout.addWidget(self.BorderBox, 3, 0, 1, 1) 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 = QtGui.QFont()
font.setFamily(_fromUtf8("DejaVu Sans")) font.setFamily("DejaVu Sans")
self.NoRotateBox.setFont(font) self.NoRotateBox.setFont(font)
self.NoRotateBox.setFocusPolicy(QtCore.Qt.NoFocus) 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.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)) self.DeviceBox.setGeometry(QtCore.QRect(10, 200, 141, 31))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("DejaVu Sans")) font.setFamily("DejaVu Sans")
font.setPointSize(8) font.setPointSize(8)
self.DeviceBox.setFont(font) self.DeviceBox.setFont(font)
self.DeviceBox.setFocusPolicy(QtCore.Qt.NoFocus) self.DeviceBox.setFocusPolicy(QtCore.Qt.NoFocus)
self.DeviceBox.setObjectName(_fromUtf8("DeviceBox")) self.DeviceBox.setObjectName("DeviceBox")
self.FormatBox = QtGui.QComboBox(self.Form) self.FormatBox = QtWidgets.QComboBox(self.Form)
self.FormatBox.setGeometry(QtCore.QRect(260, 200, 151, 31)) self.FormatBox.setGeometry(QtCore.QRect(260, 200, 151, 31))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("DejaVu Sans")) font.setFamily("DejaVu Sans")
font.setPointSize(8) font.setPointSize(8)
self.FormatBox.setFont(font) self.FormatBox.setFont(font)
self.FormatBox.setFocusPolicy(QtCore.Qt.NoFocus) self.FormatBox.setFocusPolicy(QtCore.Qt.NoFocus)
self.FormatBox.setObjectName(_fromUtf8("FormatBox")) self.FormatBox.setObjectName("FormatBox")
self.ConvertButton = QtGui.QPushButton(self.Form) self.ConvertButton = QtWidgets.QPushButton(self.Form)
self.ConvertButton.setGeometry(QtCore.QRect(160, 200, 91, 32)) self.ConvertButton.setGeometry(QtCore.QRect(160, 200, 91, 32))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("DejaVu Sans")) font.setFamily("DejaVu Sans")
font.setPointSize(9) font.setPointSize(9)
font.setBold(True) font.setBold(True)
font.setWeight(75) font.setWeight(75)
self.ConvertButton.setFont(font) self.ConvertButton.setFont(font)
self.ConvertButton.setFocusPolicy(QtCore.Qt.NoFocus) self.ConvertButton.setFocusPolicy(QtCore.Qt.NoFocus)
icon1 = QtGui.QIcon() 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.setIcon(icon1)
self.ConvertButton.setObjectName(_fromUtf8("ConvertButton")) self.ConvertButton.setObjectName("ConvertButton")
self.DirectoryButton = QtGui.QPushButton(self.Form) self.DirectoryButton = QtWidgets.QPushButton(self.Form)
self.DirectoryButton.setGeometry(QtCore.QRect(10, 160, 141, 32)) self.DirectoryButton.setGeometry(QtCore.QRect(10, 160, 141, 32))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("DejaVu Sans")) font.setFamily("DejaVu Sans")
font.setPointSize(8) font.setPointSize(8)
self.DirectoryButton.setFont(font) self.DirectoryButton.setFont(font)
self.DirectoryButton.setFocusPolicy(QtCore.Qt.NoFocus) self.DirectoryButton.setFocusPolicy(QtCore.Qt.NoFocus)
icon2 = QtGui.QIcon() 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.setIcon(icon2)
self.DirectoryButton.setObjectName(_fromUtf8("DirectoryButton")) self.DirectoryButton.setObjectName("DirectoryButton")
self.FileButton = QtGui.QPushButton(self.Form) self.FileButton = QtWidgets.QPushButton(self.Form)
self.FileButton.setGeometry(QtCore.QRect(260, 160, 151, 32)) self.FileButton.setGeometry(QtCore.QRect(260, 160, 151, 32))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("DejaVu Sans")) font.setFamily("DejaVu Sans")
font.setPointSize(8) font.setPointSize(8)
self.FileButton.setFont(font) self.FileButton.setFont(font)
self.FileButton.setFocusPolicy(QtCore.Qt.NoFocus) self.FileButton.setFocusPolicy(QtCore.Qt.NoFocus)
icon3 = QtGui.QIcon() 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.setIcon(icon3)
self.FileButton.setObjectName(_fromUtf8("FileButton")) self.FileButton.setObjectName("FileButton")
self.ClearButton = QtGui.QPushButton(self.Form) self.ClearButton = QtWidgets.QPushButton(self.Form)
self.ClearButton.setGeometry(QtCore.QRect(160, 160, 91, 32)) self.ClearButton.setGeometry(QtCore.QRect(160, 160, 91, 32))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("DejaVu Sans")) font.setFamily("DejaVu Sans")
font.setPointSize(8) font.setPointSize(8)
self.ClearButton.setFont(font) self.ClearButton.setFont(font)
self.ClearButton.setFocusPolicy(QtCore.Qt.NoFocus) self.ClearButton.setFocusPolicy(QtCore.Qt.NoFocus)
icon4 = QtGui.QIcon() 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.setIcon(icon4)
self.ClearButton.setObjectName(_fromUtf8("ClearButton")) self.ClearButton.setObjectName("ClearButton")
self.OptionsBasic = QtGui.QFrame(self.Form) self.OptionsBasic = QtWidgets.QFrame(self.Form)
self.OptionsBasic.setGeometry(QtCore.QRect(1, 230, 421, 41)) self.OptionsBasic.setGeometry(QtCore.QRect(1, 230, 421, 41))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("DejaVu Sans")) font.setFamily("DejaVu Sans")
font.setPointSize(9) font.setPointSize(9)
self.OptionsBasic.setFont(font) self.OptionsBasic.setFont(font)
self.OptionsBasic.setObjectName(_fromUtf8("OptionsBasic")) self.OptionsBasic.setObjectName("OptionsBasic")
self.MangaBox = QtGui.QCheckBox(self.OptionsBasic) self.MangaBox = QtWidgets.QCheckBox(self.OptionsBasic)
self.MangaBox.setGeometry(QtCore.QRect(9, 10, 130, 18)) self.MangaBox.setGeometry(QtCore.QRect(9, 10, 130, 18))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("DejaVu Sans")) font.setFamily("DejaVu Sans")
self.MangaBox.setFont(font) self.MangaBox.setFont(font)
self.MangaBox.setFocusPolicy(QtCore.Qt.NoFocus) self.MangaBox.setFocusPolicy(QtCore.Qt.NoFocus)
self.MangaBox.setObjectName(_fromUtf8("MangaBox")) self.MangaBox.setObjectName("MangaBox")
self.QualityBox = QtGui.QCheckBox(self.OptionsBasic) self.QualityBox = QtWidgets.QCheckBox(self.OptionsBasic)
self.QualityBox.setGeometry(QtCore.QRect(282, 10, 135, 18)) self.QualityBox.setGeometry(QtCore.QRect(282, 10, 135, 18))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("DejaVu Sans")) font.setFamily("DejaVu Sans")
self.QualityBox.setFont(font) self.QualityBox.setFont(font)
self.QualityBox.setFocusPolicy(QtCore.Qt.NoFocus) self.QualityBox.setFocusPolicy(QtCore.Qt.NoFocus)
self.QualityBox.setTristate(True) self.QualityBox.setTristate(True)
self.QualityBox.setObjectName(_fromUtf8("QualityBox")) self.QualityBox.setObjectName("QualityBox")
self.RotateBox = QtGui.QCheckBox(self.OptionsBasic) self.RotateBox = QtWidgets.QCheckBox(self.OptionsBasic)
self.RotateBox.setGeometry(QtCore.QRect(145, 10, 130, 18)) self.RotateBox.setGeometry(QtCore.QRect(145, 10, 130, 18))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("DejaVu Sans")) font.setFamily("DejaVu Sans")
self.RotateBox.setFont(font) self.RotateBox.setFont(font)
self.RotateBox.setFocusPolicy(QtCore.Qt.NoFocus) self.RotateBox.setFocusPolicy(QtCore.Qt.NoFocus)
self.RotateBox.setObjectName(_fromUtf8("RotateBox")) self.RotateBox.setObjectName("RotateBox")
self.JobList = QtGui.QListWidget(self.Form) self.JobList = QtWidgets.QListWidget(self.Form)
self.JobList.setGeometry(QtCore.QRect(10, 50, 401, 101)) self.JobList.setGeometry(QtCore.QRect(10, 50, 401, 101))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("DejaVu Sans")) font.setFamily("DejaVu Sans")
font.setPointSize(8) font.setPointSize(8)
font.setItalic(False) font.setItalic(False)
self.JobList.setFont(font) self.JobList.setFont(font)
self.JobList.setFocusPolicy(QtCore.Qt.NoFocus) self.JobList.setFocusPolicy(QtCore.Qt.NoFocus)
self.JobList.setStyleSheet(_fromUtf8("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.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.setProperty("showDropIndicator", False)
self.JobList.setSelectionMode(QtGui.QAbstractItemView.NoSelection) self.JobList.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
self.JobList.setIconSize(QtCore.QSize(18, 18)) self.JobList.setIconSize(QtCore.QSize(18, 18))
self.JobList.setVerticalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel) self.JobList.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
self.JobList.setHorizontalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel) self.JobList.setHorizontalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
self.JobList.setObjectName(_fromUtf8("JobList")) self.JobList.setObjectName("JobList")
self.BasicModeButton = QtGui.QPushButton(self.Form) self.BasicModeButton = QtWidgets.QPushButton(self.Form)
self.BasicModeButton.setGeometry(QtCore.QRect(10, 10, 195, 32)) self.BasicModeButton.setGeometry(QtCore.QRect(10, 10, 195, 32))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("DejaVu Sans")) font.setFamily("DejaVu Sans")
font.setPointSize(9) font.setPointSize(9)
self.BasicModeButton.setFont(font) self.BasicModeButton.setFont(font)
self.BasicModeButton.setFocusPolicy(QtCore.Qt.NoFocus) self.BasicModeButton.setFocusPolicy(QtCore.Qt.NoFocus)
self.BasicModeButton.setObjectName(_fromUtf8("BasicModeButton")) self.BasicModeButton.setObjectName("BasicModeButton")
self.AdvModeButton = QtGui.QPushButton(self.Form) self.AdvModeButton = QtWidgets.QPushButton(self.Form)
self.AdvModeButton.setGeometry(QtCore.QRect(217, 10, 195, 32)) self.AdvModeButton.setGeometry(QtCore.QRect(217, 10, 195, 32))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("DejaVu Sans")) font.setFamily("DejaVu Sans")
font.setPointSize(9) font.setPointSize(9)
self.AdvModeButton.setFont(font) self.AdvModeButton.setFont(font)
self.AdvModeButton.setFocusPolicy(QtCore.Qt.NoFocus) self.AdvModeButton.setFocusPolicy(QtCore.Qt.NoFocus)
self.AdvModeButton.setObjectName(_fromUtf8("AdvModeButton")) self.AdvModeButton.setObjectName("AdvModeButton")
self.OptionsAdvancedGamma = QtGui.QFrame(self.Form) self.OptionsAdvancedGamma = QtWidgets.QFrame(self.Form)
self.OptionsAdvancedGamma.setEnabled(True) self.OptionsAdvancedGamma.setEnabled(True)
self.OptionsAdvancedGamma.setGeometry(QtCore.QRect(10, 305, 401, 41)) self.OptionsAdvancedGamma.setGeometry(QtCore.QRect(10, 305, 401, 41))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("DejaVu Sans")) font.setFamily("DejaVu Sans")
font.setPointSize(9) font.setPointSize(9)
self.OptionsAdvancedGamma.setFont(font) self.OptionsAdvancedGamma.setFont(font)
self.OptionsAdvancedGamma.setObjectName(_fromUtf8("OptionsAdvancedGamma")) self.OptionsAdvancedGamma.setObjectName("OptionsAdvancedGamma")
self.GammaLabel = QtGui.QLabel(self.OptionsAdvancedGamma) self.GammaLabel = QtWidgets.QLabel(self.OptionsAdvancedGamma)
self.GammaLabel.setGeometry(QtCore.QRect(15, 0, 100, 40)) self.GammaLabel.setGeometry(QtCore.QRect(15, 0, 100, 40))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("DejaVu Sans")) font.setFamily("DejaVu Sans")
self.GammaLabel.setFont(font) self.GammaLabel.setFont(font)
self.GammaLabel.setObjectName(_fromUtf8("GammaLabel")) self.GammaLabel.setObjectName("GammaLabel")
self.GammaSlider = QtGui.QSlider(self.OptionsAdvancedGamma) self.GammaSlider = QtWidgets.QSlider(self.OptionsAdvancedGamma)
self.GammaSlider.setGeometry(QtCore.QRect(110, 10, 275, 22)) self.GammaSlider.setGeometry(QtCore.QRect(110, 10, 275, 22))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("DejaVu Sans")) font.setFamily("DejaVu Sans")
self.GammaSlider.setFont(font) self.GammaSlider.setFont(font)
self.GammaSlider.setFocusPolicy(QtCore.Qt.ClickFocus) self.GammaSlider.setFocusPolicy(QtCore.Qt.ClickFocus)
self.GammaSlider.setMaximum(500) self.GammaSlider.setMaximum(500)
self.GammaSlider.setSingleStep(5) self.GammaSlider.setSingleStep(5)
self.GammaSlider.setOrientation(QtCore.Qt.Horizontal) self.GammaSlider.setOrientation(QtCore.Qt.Horizontal)
self.GammaSlider.setObjectName(_fromUtf8("GammaSlider")) self.GammaSlider.setObjectName("GammaSlider")
self.ProgressBar = QtGui.QProgressBar(self.Form) self.ProgressBar = QtWidgets.QProgressBar(self.Form)
self.ProgressBar.setGeometry(QtCore.QRect(10, 10, 401, 31)) self.ProgressBar.setGeometry(QtCore.QRect(10, 10, 401, 31))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("DejaVu Sans")) font.setFamily("DejaVu Sans")
font.setPointSize(10) font.setPointSize(10)
font.setBold(True) font.setBold(True)
font.setWeight(75) font.setWeight(75)
self.ProgressBar.setFont(font) self.ProgressBar.setFont(font)
self.ProgressBar.setProperty("value", 0) self.ProgressBar.setProperty("value", 0)
self.ProgressBar.setAlignment(QtCore.Qt.AlignJustify|QtCore.Qt.AlignVCenter) self.ProgressBar.setAlignment(QtCore.Qt.AlignJustify|QtCore.Qt.AlignVCenter)
self.ProgressBar.setFormat(_fromUtf8("")) self.ProgressBar.setFormat("")
self.ProgressBar.setObjectName(_fromUtf8("ProgressBar")) self.ProgressBar.setObjectName("ProgressBar")
self.OptionsExpert = QtGui.QFrame(self.Form) self.OptionsExpert = QtWidgets.QFrame(self.Form)
self.OptionsExpert.setGeometry(QtCore.QRect(1, 337, 421, 41)) self.OptionsExpert.setGeometry(QtCore.QRect(1, 337, 421, 41))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("DejaVu Sans")) font.setFamily("DejaVu Sans")
font.setPointSize(9) font.setPointSize(9)
self.OptionsExpert.setFont(font) self.OptionsExpert.setFont(font)
self.OptionsExpert.setObjectName(_fromUtf8("OptionsExpert")) self.OptionsExpert.setObjectName("OptionsExpert")
self.ColorBox = QtGui.QCheckBox(self.OptionsExpert) self.ColorBox = QtWidgets.QCheckBox(self.OptionsExpert)
self.ColorBox.setGeometry(QtCore.QRect(9, 11, 130, 18)) self.ColorBox.setGeometry(QtCore.QRect(9, 11, 130, 18))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("DejaVu Sans")) font.setFamily("DejaVu Sans")
self.ColorBox.setFont(font) self.ColorBox.setFont(font)
self.ColorBox.setFocusPolicy(QtCore.Qt.NoFocus) self.ColorBox.setFocusPolicy(QtCore.Qt.NoFocus)
self.ColorBox.setObjectName(_fromUtf8("ColorBox")) self.ColorBox.setObjectName("ColorBox")
self.OptionsExpertInternal = QtGui.QFrame(self.OptionsExpert) self.OptionsExpertInternal = QtWidgets.QFrame(self.OptionsExpert)
self.OptionsExpertInternal.setGeometry(QtCore.QRect(105, 0, 295, 40)) self.OptionsExpertInternal.setGeometry(QtCore.QRect(105, 0, 295, 40))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("DejaVu Sans")) font.setFamily("DejaVu Sans")
self.OptionsExpertInternal.setFont(font) self.OptionsExpertInternal.setFont(font)
self.OptionsExpertInternal.setObjectName(_fromUtf8("OptionsExpertInternal")) self.OptionsExpertInternal.setObjectName("OptionsExpertInternal")
self.gridLayout_2 = QtGui.QGridLayout(self.OptionsExpertInternal) self.gridLayout_2 = QtWidgets.QGridLayout(self.OptionsExpertInternal)
self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2")) self.gridLayout_2.setObjectName("gridLayout_2")
self.wLabel = QtGui.QLabel(self.OptionsExpertInternal) self.wLabel = QtWidgets.QLabel(self.OptionsExpertInternal)
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("DejaVu Sans")) font.setFamily("DejaVu Sans")
self.wLabel.setFont(font) self.wLabel.setFont(font)
self.wLabel.setObjectName(_fromUtf8("wLabel")) self.wLabel.setObjectName("wLabel")
self.gridLayout_2.addWidget(self.wLabel, 0, 0, 1, 1) self.gridLayout_2.addWidget(self.wLabel, 0, 0, 1, 1)
self.customWidth = QtGui.QLineEdit(self.OptionsExpertInternal) self.customWidth = QtWidgets.QLineEdit(self.OptionsExpertInternal)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.customWidth.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(self.customWidth.sizePolicy().hasHeightForWidth())
self.customWidth.setSizePolicy(sizePolicy) self.customWidth.setSizePolicy(sizePolicy)
self.customWidth.setMaximumSize(QtCore.QSize(40, 16777215)) self.customWidth.setMaximumSize(QtCore.QSize(40, 16777215))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("DejaVu Sans")) font.setFamily("DejaVu Sans")
self.customWidth.setFont(font) self.customWidth.setFont(font)
self.customWidth.setFocusPolicy(QtCore.Qt.ClickFocus) self.customWidth.setFocusPolicy(QtCore.Qt.ClickFocus)
self.customWidth.setAcceptDrops(False) self.customWidth.setAcceptDrops(False)
self.customWidth.setMaxLength(4) self.customWidth.setMaxLength(4)
self.customWidth.setObjectName(_fromUtf8("customWidth")) self.customWidth.setObjectName("customWidth")
self.gridLayout_2.addWidget(self.customWidth, 0, 1, 1, 1) 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 = QtGui.QFont()
font.setFamily(_fromUtf8("DejaVu Sans")) font.setFamily("DejaVu Sans")
self.hLabel.setFont(font) self.hLabel.setFont(font)
self.hLabel.setObjectName(_fromUtf8("hLabel")) self.hLabel.setObjectName("hLabel")
self.gridLayout_2.addWidget(self.hLabel, 0, 2, 1, 1) self.gridLayout_2.addWidget(self.hLabel, 0, 2, 1, 1)
self.customHeight = QtGui.QLineEdit(self.OptionsExpertInternal) self.customHeight = QtWidgets.QLineEdit(self.OptionsExpertInternal)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.customHeight.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(self.customHeight.sizePolicy().hasHeightForWidth())
self.customHeight.setSizePolicy(sizePolicy) self.customHeight.setSizePolicy(sizePolicy)
self.customHeight.setMaximumSize(QtCore.QSize(40, 16777215)) self.customHeight.setMaximumSize(QtCore.QSize(40, 16777215))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("DejaVu Sans")) font.setFamily("DejaVu Sans")
self.customHeight.setFont(font) self.customHeight.setFont(font)
self.customHeight.setFocusPolicy(QtCore.Qt.ClickFocus) self.customHeight.setFocusPolicy(QtCore.Qt.ClickFocus)
self.customHeight.setAcceptDrops(False) self.customHeight.setAcceptDrops(False)
self.customHeight.setMaxLength(4) self.customHeight.setMaxLength(4)
self.customHeight.setObjectName(_fromUtf8("customHeight")) self.customHeight.setObjectName("customHeight")
self.gridLayout_2.addWidget(self.customHeight, 0, 3, 1, 1) self.gridLayout_2.addWidget(self.customHeight, 0, 3, 1, 1)
KCC.setCentralWidget(self.Form) KCC.setCentralWidget(self.Form)
self.statusBar = QtGui.QStatusBar(KCC) self.statusBar = QtWidgets.QStatusBar(KCC)
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("DejaVu Sans")) font.setFamily("DejaVu Sans")
font.setPointSize(8) font.setPointSize(8)
self.statusBar.setFont(font) self.statusBar.setFont(font)
self.statusBar.setSizeGripEnabled(False) self.statusBar.setSizeGripEnabled(False)
self.statusBar.setObjectName(_fromUtf8("statusBar")) self.statusBar.setObjectName("statusBar")
KCC.setStatusBar(self.statusBar) KCC.setStatusBar(self.statusBar)
self.ActionBasic = QtGui.QAction(KCC) self.ActionBasic = QtWidgets.QAction(KCC)
self.ActionBasic.setCheckable(True) self.ActionBasic.setCheckable(True)
self.ActionBasic.setChecked(False) self.ActionBasic.setChecked(False)
font = QtGui.QFont() font = QtGui.QFont()
self.ActionBasic.setFont(font) self.ActionBasic.setFont(font)
self.ActionBasic.setObjectName(_fromUtf8("ActionBasic")) self.ActionBasic.setObjectName("ActionBasic")
self.ActionAdvanced = QtGui.QAction(KCC) self.ActionAdvanced = QtWidgets.QAction(KCC)
self.ActionAdvanced.setCheckable(True) self.ActionAdvanced.setCheckable(True)
self.ActionAdvanced.setObjectName(_fromUtf8("ActionAdvanced")) self.ActionAdvanced.setObjectName("ActionAdvanced")
self.retranslateUi(KCC) self.retranslateUi(KCC)
QtCore.QMetaObject.connectSlotsByName(KCC) QtCore.QMetaObject.connectSlotsByName(KCC)
@@ -341,51 +327,47 @@ class Ui_KCC(object):
KCC.setTabOrder(self.ConvertButton, self.ClearButton) KCC.setTabOrder(self.ConvertButton, self.ClearButton)
def retranslateUi(self, KCC): def retranslateUi(self, KCC):
KCC.setWindowTitle(_translate("KCC", "Kindle Comic Converter", None)) _translate = QtCore.QCoreApplication.translate
self.ProcessingBox.setToolTip(_translate("KCC", "Disable image optimizations.", None)) KCC.setWindowTitle(_translate("KCC", "Kindle Comic Converter"))
self.ProcessingBox.setText(_translate("KCC", "No optimisation", None)) self.ProcessingBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Disable image optimizations.<br/>Input images must be already resized.</p></body></html>"))
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.ProcessingBox.setText(_translate("KCC", "No optimisation"))
self.UpscaleBox.setText(_translate("KCC", "Stretch/Upscale", 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>"))
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.UpscaleBox.setText(_translate("KCC", "Stretch/Upscale"))
self.WebtoonBox.setText(_translate("KCC", "Webtoon mode", None)) self.WebtoonBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>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>"))
self.NoDitheringBox.setToolTip(_translate("KCC", "<html><head/><body><p>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>", None)) self.WebtoonBox.setText(_translate("KCC", "Webtoon mode"))
self.NoDitheringBox.setText(_translate("KCC", "PNG output", None)) 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.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.NoDitheringBox.setText(_translate("KCC", "PNG output"))
self.BorderBox.setText(_translate("KCC", "W/B margins", 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>"))
self.NoRotateBox.setToolTip(_translate("KCC", "<html><head/><body><p>Disable splitting and rotation.</p></body></html>", None)) self.BorderBox.setText(_translate("KCC", "W/B margins"))
self.NoRotateBox.setText(_translate("KCC", "No split/rotate", None)) self.NoRotateBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Disable splitting and rotation.</p></body></html>"))
self.DeviceBox.setToolTip(_translate("KCC", "Target device.", None)) self.NoRotateBox.setText(_translate("KCC", "No split/rotate"))
self.FormatBox.setToolTip(_translate("KCC", "Output format.", None)) self.DeviceBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Target device.</p></body></html>"))
self.ConvertButton.setText(_translate("KCC", "Convert", None)) self.FormatBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Output format.</p></body></html>"))
self.DirectoryButton.setText(_translate("KCC", "Add directory", None)) self.ConvertButton.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Shift+Click to select the output directory.</p></body></html>"))
self.FileButton.setText(_translate("KCC", "Add file", None)) self.ConvertButton.setText(_translate("KCC", "Convert"))
self.ClearButton.setText(_translate("KCC", "Clear list", None)) self.DirectoryButton.setText(_translate("KCC", "Add directory"))
self.MangaBox.setToolTip(_translate("KCC", "Enable right-to-left reading.", None)) self.FileButton.setText(_translate("KCC", "Add file"))
self.MangaBox.setText(_translate("KCC", "Manga mode", None)) self.ClearButton.setText(_translate("KCC", "Clear list"))
self.QualityBox.setToolTip(_translate("KCC", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n" self.MangaBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Enable right-to-left reading.</p></body></html>"))
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n" self.MangaBox.setText(_translate("KCC", "Manga mode"))
"p, li { white-space: pre-wrap; }\n" self.QualityBox.setToolTip(_translate("KCC", "<html><head/><body><p><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.<br/></span>- Maximum quality when zoom is not enabled.<br/>- Poor quality when zoom is enabled.<br/>- Lowest file size.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Indeterminate - High quality mode<br/></span><span style=\" font-style:italic;\">Not zoomed images </span><span style=\" font-weight:600; font-style:italic;\">might</span><span style=\" font-style:italic;\"> be blurry.<br/></span>- High quality when zoom is not enabled.<br/>- Maximum quality when zoom is enabled.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - Ultra quality mode<br/></span><span style=\" font-style:italic;\">Maximum possible quality.<br/></span>- Maximum quality when zoom is not enabled.<br/>- Maximum quality when zoom is enabled.<br/>- Very high file size.</p></body></html>"))
"</style></head><body style=\" font-family:\'Sans\'; font-size:9pt; font-weight:400; font-style:normal;\">\n" self.QualityBox.setText(_translate("KCC", "High/Ultra quality"))
"<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" 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>"))
"<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.<br /></span><span style=\" font-family:\'MS Shell Dlg 2\'; font-style:italic;\">Smaller images might be forcefully upscaled in this mode.</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" self.RotateBox.setText(_translate("KCC", "Horizontal mode"))
"<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.BasicModeButton.setText(_translate("KCC", "Basic"))
self.QualityBox.setText(_translate("KCC", "High/Ultra quality", None)) self.AdvModeButton.setText(_translate("KCC", "Advanced"))
self.RotateBox.setToolTip(_translate("KCC", "<html><head/><body><p>Disable splitting of two-page spreads.<br/>They will be rotated instead.</p></body></html>", None)) self.GammaLabel.setText(_translate("KCC", "Gamma: Auto"))
self.RotateBox.setText(_translate("KCC", "Horizontal mode", None)) self.ColorBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Don\'t convert images to grayscale.</p></body></html>"))
self.BasicModeButton.setText(_translate("KCC", "Basic", None)) self.ColorBox.setText(_translate("KCC", "Color mode"))
self.AdvModeButton.setText(_translate("KCC", "Advanced", None)) self.wLabel.setToolTip(_translate("KCC", "<html><head/><body><p>Resolution of target device.</p></body></html>"))
self.GammaLabel.setText(_translate("KCC", "Gamma: Auto", None)) self.wLabel.setText(_translate("KCC", "Custom width: "))
self.ColorBox.setToolTip(_translate("KCC", "<html><head/><body><p>Don\'t convert images to grayscale.</p></body></html>", None)) self.customWidth.setToolTip(_translate("KCC", "<html><head/><body><p>Resolution of target device.</p></body></html>"))
self.ColorBox.setText(_translate("KCC", "Color mode", None)) self.customWidth.setInputMask(_translate("KCC", "0000"))
self.wLabel.setToolTip(_translate("KCC", "Resolution of target device.", None)) self.hLabel.setToolTip(_translate("KCC", "<html><head/><body><p>Resolution of target device.</p></body></html>"))
self.wLabel.setText(_translate("KCC", "Custom width: ", None)) self.hLabel.setText(_translate("KCC", "Custom height: "))
self.customWidth.setToolTip(_translate("KCC", "Resolution of target device.", None)) self.customHeight.setToolTip(_translate("KCC", "<html><head/><body><p>Resolution of target device.</p></body></html>"))
self.customWidth.setInputMask(_translate("KCC", "0000; ", None)) self.customHeight.setInputMask(_translate("KCC", "0000"))
self.hLabel.setToolTip(_translate("KCC", "Resolution of target device.", None)) self.ActionBasic.setText(_translate("KCC", "Basic"))
self.hLabel.setText(_translate("KCC", "Custom height: ", None)) self.ActionAdvanced.setText(_translate("KCC", "Advanced"))
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))
import KCC_rc from . import KCC_rc

View File

@@ -2,30 +2,16 @@
# Form implementation generated from reading ui file 'KCC-OSX.ui' # Form implementation generated from reading ui file 'KCC-OSX.ui'
# #
# Created: Tue Jan 14 15:50:25 2014 # Created: Sat Jan 25 17:37:10 2014
# by: PyQt4 UI code generator 4.10.3 # by: PyQt5 UI code generator 5.2
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui from PyQt5 import QtCore, QtGui, QtWidgets
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)
class Ui_KCC(object): class Ui_KCC(object):
def setupUi(self, KCC): def setupUi(self, KCC):
KCC.setObjectName(_fromUtf8("KCC")) KCC.setObjectName("KCC")
KCC.resize(420, 397) KCC.resize(420, 397)
KCC.setMinimumSize(QtCore.QSize(420, 397)) KCC.setMinimumSize(QtCore.QSize(420, 397))
KCC.setMaximumSize(QtCore.QSize(420, 397)) KCC.setMaximumSize(QtCore.QSize(420, 397))
@@ -33,330 +19,329 @@ class Ui_KCC(object):
font.setPointSize(9) font.setPointSize(9)
KCC.setFont(font) KCC.setFont(font)
icon = QtGui.QIcon() 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.setWindowIcon(icon)
KCC.setLocale(QtCore.QLocale(QtCore.QLocale.C, QtCore.QLocale.AnyCountry)) KCC.setLocale(QtCore.QLocale(QtCore.QLocale.C, QtCore.QLocale.AnyCountry))
self.Form = QtGui.QWidget(KCC) self.Form = QtWidgets.QWidget(KCC)
self.Form.setObjectName(_fromUtf8("Form")) self.Form.setObjectName("Form")
self.OptionsAdvanced = QtGui.QFrame(self.Form) self.OptionsAdvanced = QtWidgets.QFrame(self.Form)
self.OptionsAdvanced.setEnabled(True) self.OptionsAdvanced.setEnabled(True)
self.OptionsAdvanced.setGeometry(QtCore.QRect(4, 253, 421, 61)) self.OptionsAdvanced.setGeometry(QtCore.QRect(4, 253, 421, 61))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("Lucida Grande")) font.setFamily("Lucida Grande")
font.setPointSize(9) font.setPointSize(9)
self.OptionsAdvanced.setFont(font) self.OptionsAdvanced.setFont(font)
self.OptionsAdvanced.setObjectName(_fromUtf8("OptionsAdvanced")) self.OptionsAdvanced.setObjectName("OptionsAdvanced")
self.gridLayout = QtGui.QGridLayout(self.OptionsAdvanced) self.gridLayout = QtWidgets.QGridLayout(self.OptionsAdvanced)
self.gridLayout.setObjectName(_fromUtf8("gridLayout")) self.gridLayout.setObjectName("gridLayout")
self.ProcessingBox = QtGui.QCheckBox(self.OptionsAdvanced) self.ProcessingBox = QtWidgets.QCheckBox(self.OptionsAdvanced)
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("Lucida Grande")) font.setFamily("Lucida Grande")
font.setPointSize(12) font.setPointSize(12)
self.ProcessingBox.setFont(font) self.ProcessingBox.setFont(font)
self.ProcessingBox.setFocusPolicy(QtCore.Qt.NoFocus) 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.gridLayout.addWidget(self.ProcessingBox, 1, 0, 1, 1)
self.UpscaleBox = QtGui.QCheckBox(self.OptionsAdvanced) self.UpscaleBox = QtWidgets.QCheckBox(self.OptionsAdvanced)
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("Lucida Grande")) font.setFamily("Lucida Grande")
font.setPointSize(12) font.setPointSize(12)
self.UpscaleBox.setFont(font) self.UpscaleBox.setFont(font)
self.UpscaleBox.setFocusPolicy(QtCore.Qt.NoFocus) self.UpscaleBox.setFocusPolicy(QtCore.Qt.NoFocus)
self.UpscaleBox.setTristate(True) self.UpscaleBox.setTristate(True)
self.UpscaleBox.setObjectName(_fromUtf8("UpscaleBox")) self.UpscaleBox.setObjectName("UpscaleBox")
self.gridLayout.addWidget(self.UpscaleBox, 1, 1, 1, 1) 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 = QtGui.QFont()
font.setFamily(_fromUtf8("Lucida Grande")) font.setFamily("Lucida Grande")
font.setPointSize(12) font.setPointSize(12)
self.WebtoonBox.setFont(font) self.WebtoonBox.setFont(font)
self.WebtoonBox.setFocusPolicy(QtCore.Qt.NoFocus) 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.gridLayout.addWidget(self.WebtoonBox, 3, 1, 1, 1)
self.NoDitheringBox = QtGui.QCheckBox(self.OptionsAdvanced) self.NoDitheringBox = QtWidgets.QCheckBox(self.OptionsAdvanced)
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("Lucida Grande")) font.setFamily("Lucida Grande")
font.setPointSize(12) font.setPointSize(12)
self.NoDitheringBox.setFont(font) self.NoDitheringBox.setFont(font)
self.NoDitheringBox.setFocusPolicy(QtCore.Qt.NoFocus) 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.gridLayout.addWidget(self.NoDitheringBox, 3, 2, 1, 1)
self.BorderBox = QtGui.QCheckBox(self.OptionsAdvanced) self.BorderBox = QtWidgets.QCheckBox(self.OptionsAdvanced)
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("Lucida Grande")) font.setFamily("Lucida Grande")
font.setPointSize(12) font.setPointSize(12)
self.BorderBox.setFont(font) self.BorderBox.setFont(font)
self.BorderBox.setFocusPolicy(QtCore.Qt.NoFocus) self.BorderBox.setFocusPolicy(QtCore.Qt.NoFocus)
self.BorderBox.setTristate(True) self.BorderBox.setTristate(True)
self.BorderBox.setObjectName(_fromUtf8("BorderBox")) self.BorderBox.setObjectName("BorderBox")
self.gridLayout.addWidget(self.BorderBox, 3, 0, 1, 1) 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 = QtGui.QFont()
font.setFamily(_fromUtf8("Lucida Grande")) font.setFamily("Lucida Grande")
font.setPointSize(12) font.setPointSize(12)
self.NoRotateBox.setFont(font) self.NoRotateBox.setFont(font)
self.NoRotateBox.setFocusPolicy(QtCore.Qt.NoFocus) 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.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(8, 201, 151, 34)) self.DeviceBox.setGeometry(QtCore.QRect(8, 201, 151, 34))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("Lucida Grande")) font.setFamily("Lucida Grande")
font.setPointSize(11) font.setPointSize(11)
self.DeviceBox.setFont(font) self.DeviceBox.setFont(font)
self.DeviceBox.setFocusPolicy(QtCore.Qt.NoFocus) self.DeviceBox.setFocusPolicy(QtCore.Qt.NoFocus)
self.DeviceBox.setObjectName(_fromUtf8("DeviceBox")) self.DeviceBox.setObjectName("DeviceBox")
self.FormatBox = QtGui.QComboBox(self.Form) self.FormatBox = QtWidgets.QComboBox(self.Form)
self.FormatBox.setGeometry(QtCore.QRect(262, 201, 152, 34)) self.FormatBox.setGeometry(QtCore.QRect(262, 201, 152, 34))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("Lucida Grande")) font.setFamily("Lucida Grande")
font.setPointSize(11) font.setPointSize(11)
self.FormatBox.setFont(font) self.FormatBox.setFont(font)
self.FormatBox.setFocusPolicy(QtCore.Qt.NoFocus) self.FormatBox.setFocusPolicy(QtCore.Qt.NoFocus)
self.FormatBox.setObjectName(_fromUtf8("FormatBox")) self.FormatBox.setObjectName("FormatBox")
self.ConvertButton = QtGui.QPushButton(self.Form) self.ConvertButton = QtWidgets.QPushButton(self.Form)
self.ConvertButton.setGeometry(QtCore.QRect(160, 200, 101, 41)) self.ConvertButton.setGeometry(QtCore.QRect(160, 200, 101, 41))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("Lucida Grande")) font.setFamily("Lucida Grande")
font.setPointSize(11) font.setPointSize(11)
font.setBold(True) font.setBold(True)
font.setWeight(75) font.setWeight(75)
self.ConvertButton.setFont(font) self.ConvertButton.setFont(font)
self.ConvertButton.setFocusPolicy(QtCore.Qt.NoFocus) self.ConvertButton.setFocusPolicy(QtCore.Qt.NoFocus)
icon1 = QtGui.QIcon() 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.setIcon(icon1)
self.ConvertButton.setObjectName(_fromUtf8("ConvertButton")) self.ConvertButton.setObjectName("ConvertButton")
self.DirectoryButton = QtGui.QPushButton(self.Form) self.DirectoryButton = QtWidgets.QPushButton(self.Form)
self.DirectoryButton.setGeometry(QtCore.QRect(5, 160, 156, 41)) self.DirectoryButton.setGeometry(QtCore.QRect(5, 160, 156, 41))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("Lucida Grande")) font.setFamily("Lucida Grande")
font.setPointSize(11) font.setPointSize(11)
self.DirectoryButton.setFont(font) self.DirectoryButton.setFont(font)
self.DirectoryButton.setFocusPolicy(QtCore.Qt.NoFocus) self.DirectoryButton.setFocusPolicy(QtCore.Qt.NoFocus)
icon2 = QtGui.QIcon() 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.setIcon(icon2)
self.DirectoryButton.setObjectName(_fromUtf8("DirectoryButton")) self.DirectoryButton.setObjectName("DirectoryButton")
self.FileButton = QtGui.QPushButton(self.Form) self.FileButton = QtWidgets.QPushButton(self.Form)
self.FileButton.setGeometry(QtCore.QRect(260, 160, 157, 41)) self.FileButton.setGeometry(QtCore.QRect(260, 160, 157, 41))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("Lucida Grande")) font.setFamily("Lucida Grande")
font.setPointSize(11) font.setPointSize(11)
self.FileButton.setFont(font) self.FileButton.setFont(font)
self.FileButton.setFocusPolicy(QtCore.Qt.NoFocus) self.FileButton.setFocusPolicy(QtCore.Qt.NoFocus)
icon3 = QtGui.QIcon() 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.setIcon(icon3)
self.FileButton.setObjectName(_fromUtf8("FileButton")) self.FileButton.setObjectName("FileButton")
self.ClearButton = QtGui.QPushButton(self.Form) self.ClearButton = QtWidgets.QPushButton(self.Form)
self.ClearButton.setGeometry(QtCore.QRect(160, 160, 101, 41)) self.ClearButton.setGeometry(QtCore.QRect(160, 160, 101, 41))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("Lucida Grande")) font.setFamily("Lucida Grande")
font.setPointSize(11) font.setPointSize(11)
self.ClearButton.setFont(font) self.ClearButton.setFont(font)
self.ClearButton.setFocusPolicy(QtCore.Qt.NoFocus) self.ClearButton.setFocusPolicy(QtCore.Qt.NoFocus)
icon4 = QtGui.QIcon() 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.setIcon(icon4)
self.ClearButton.setObjectName(_fromUtf8("ClearButton")) self.ClearButton.setObjectName("ClearButton")
self.OptionsBasic = QtGui.QFrame(self.Form) self.OptionsBasic = QtWidgets.QFrame(self.Form)
self.OptionsBasic.setGeometry(QtCore.QRect(5, 233, 421, 41)) self.OptionsBasic.setGeometry(QtCore.QRect(5, 233, 421, 41))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("Lucida Grande")) font.setFamily("Lucida Grande")
font.setPointSize(12) font.setPointSize(12)
self.OptionsBasic.setFont(font) self.OptionsBasic.setFont(font)
self.OptionsBasic.setObjectName(_fromUtf8("OptionsBasic")) self.OptionsBasic.setObjectName("OptionsBasic")
self.MangaBox = QtGui.QCheckBox(self.OptionsBasic) self.MangaBox = QtWidgets.QCheckBox(self.OptionsBasic)
self.MangaBox.setGeometry(QtCore.QRect(9, 10, 130, 18)) self.MangaBox.setGeometry(QtCore.QRect(9, 10, 130, 18))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("Lucida Grande")) font.setFamily("Lucida Grande")
font.setPointSize(12) font.setPointSize(12)
self.MangaBox.setFont(font) self.MangaBox.setFont(font)
self.MangaBox.setFocusPolicy(QtCore.Qt.NoFocus) self.MangaBox.setFocusPolicy(QtCore.Qt.NoFocus)
self.MangaBox.setObjectName(_fromUtf8("MangaBox")) self.MangaBox.setObjectName("MangaBox")
self.QualityBox = QtGui.QCheckBox(self.OptionsBasic) self.QualityBox = QtWidgets.QCheckBox(self.OptionsBasic)
self.QualityBox.setGeometry(QtCore.QRect(282, 10, 135, 18)) self.QualityBox.setGeometry(QtCore.QRect(282, 10, 135, 18))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("Lucida Grande")) font.setFamily("Lucida Grande")
font.setPointSize(12) font.setPointSize(12)
self.QualityBox.setFont(font) self.QualityBox.setFont(font)
self.QualityBox.setFocusPolicy(QtCore.Qt.NoFocus) self.QualityBox.setFocusPolicy(QtCore.Qt.NoFocus)
self.QualityBox.setTristate(True) self.QualityBox.setTristate(True)
self.QualityBox.setObjectName(_fromUtf8("QualityBox")) self.QualityBox.setObjectName("QualityBox")
self.RotateBox = QtGui.QCheckBox(self.OptionsBasic) self.RotateBox = QtWidgets.QCheckBox(self.OptionsBasic)
self.RotateBox.setGeometry(QtCore.QRect(145, 10, 130, 18)) self.RotateBox.setGeometry(QtCore.QRect(145, 10, 130, 18))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("Lucida Grande")) font.setFamily("Lucida Grande")
font.setPointSize(12) font.setPointSize(12)
self.RotateBox.setFont(font) self.RotateBox.setFont(font)
self.RotateBox.setFocusPolicy(QtCore.Qt.NoFocus) self.RotateBox.setFocusPolicy(QtCore.Qt.NoFocus)
self.RotateBox.setObjectName(_fromUtf8("RotateBox")) self.RotateBox.setObjectName("RotateBox")
self.JobList = QtGui.QListWidget(self.Form) self.JobList = QtWidgets.QListWidget(self.Form)
self.JobList.setGeometry(QtCore.QRect(10, 50, 401, 101)) self.JobList.setGeometry(QtCore.QRect(10, 50, 401, 101))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("Lucida Grande")) font.setFamily("Lucida Grande")
font.setPointSize(11) font.setPointSize(11)
self.JobList.setFont(font) self.JobList.setFont(font)
self.JobList.setFocusPolicy(QtCore.Qt.NoFocus) self.JobList.setFocusPolicy(QtCore.Qt.NoFocus)
self.JobList.setStyleSheet(_fromUtf8("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.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.setProperty("showDropIndicator", False)
self.JobList.setSelectionMode(QtGui.QAbstractItemView.NoSelection) self.JobList.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
self.JobList.setVerticalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel) self.JobList.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
self.JobList.setHorizontalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel) self.JobList.setHorizontalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
self.JobList.setObjectName(_fromUtf8("JobList")) self.JobList.setObjectName("JobList")
self.BasicModeButton = QtGui.QPushButton(self.Form) self.BasicModeButton = QtWidgets.QPushButton(self.Form)
self.BasicModeButton.setGeometry(QtCore.QRect(5, 10, 210, 41)) self.BasicModeButton.setGeometry(QtCore.QRect(5, 10, 210, 41))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("Lucida Grande")) font.setFamily("Lucida Grande")
font.setPointSize(12) font.setPointSize(12)
font.setBold(False) font.setBold(False)
font.setWeight(50) font.setWeight(50)
self.BasicModeButton.setFont(font) self.BasicModeButton.setFont(font)
self.BasicModeButton.setFocusPolicy(QtCore.Qt.NoFocus) self.BasicModeButton.setFocusPolicy(QtCore.Qt.NoFocus)
self.BasicModeButton.setObjectName(_fromUtf8("BasicModeButton")) self.BasicModeButton.setObjectName("BasicModeButton")
self.AdvModeButton = QtGui.QPushButton(self.Form) self.AdvModeButton = QtWidgets.QPushButton(self.Form)
self.AdvModeButton.setGeometry(QtCore.QRect(207, 10, 210, 41)) self.AdvModeButton.setGeometry(QtCore.QRect(207, 10, 210, 41))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("Lucida Grande")) font.setFamily("Lucida Grande")
font.setPointSize(12) font.setPointSize(12)
font.setBold(False) font.setBold(False)
font.setWeight(50) font.setWeight(50)
self.AdvModeButton.setFont(font) self.AdvModeButton.setFont(font)
self.AdvModeButton.setFocusPolicy(QtCore.Qt.NoFocus) self.AdvModeButton.setFocusPolicy(QtCore.Qt.NoFocus)
self.AdvModeButton.setObjectName(_fromUtf8("AdvModeButton")) self.AdvModeButton.setObjectName("AdvModeButton")
self.OptionsAdvancedGamma = QtGui.QFrame(self.Form) self.OptionsAdvancedGamma = QtWidgets.QFrame(self.Form)
self.OptionsAdvancedGamma.setEnabled(True) self.OptionsAdvancedGamma.setEnabled(True)
self.OptionsAdvancedGamma.setGeometry(QtCore.QRect(5, 303, 401, 41)) self.OptionsAdvancedGamma.setGeometry(QtCore.QRect(5, 303, 401, 41))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("Lucida Grande")) font.setFamily("Lucida Grande")
font.setPointSize(9) font.setPointSize(9)
self.OptionsAdvancedGamma.setFont(font) self.OptionsAdvancedGamma.setFont(font)
self.OptionsAdvancedGamma.setObjectName(_fromUtf8("OptionsAdvancedGamma")) self.OptionsAdvancedGamma.setObjectName("OptionsAdvancedGamma")
self.GammaLabel = QtGui.QLabel(self.OptionsAdvancedGamma) self.GammaLabel = QtWidgets.QLabel(self.OptionsAdvancedGamma)
self.GammaLabel.setGeometry(QtCore.QRect(20, 0, 100, 40)) self.GammaLabel.setGeometry(QtCore.QRect(20, 0, 100, 40))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("Lucida Grande")) font.setFamily("Lucida Grande")
font.setPointSize(12) font.setPointSize(12)
font.setBold(False) font.setBold(False)
font.setWeight(50) font.setWeight(50)
self.GammaLabel.setFont(font) self.GammaLabel.setFont(font)
self.GammaLabel.setObjectName(_fromUtf8("GammaLabel")) self.GammaLabel.setObjectName("GammaLabel")
self.GammaSlider = QtGui.QSlider(self.OptionsAdvancedGamma) self.GammaSlider = QtWidgets.QSlider(self.OptionsAdvancedGamma)
self.GammaSlider.setGeometry(QtCore.QRect(110, 10, 290, 22)) self.GammaSlider.setGeometry(QtCore.QRect(110, 10, 290, 22))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("Lucida Grande")) font.setFamily("Lucida Grande")
self.GammaSlider.setFont(font) self.GammaSlider.setFont(font)
self.GammaSlider.setFocusPolicy(QtCore.Qt.ClickFocus) self.GammaSlider.setFocusPolicy(QtCore.Qt.ClickFocus)
self.GammaSlider.setMaximum(500) self.GammaSlider.setMaximum(500)
self.GammaSlider.setSingleStep(5) self.GammaSlider.setSingleStep(5)
self.GammaSlider.setOrientation(QtCore.Qt.Horizontal) self.GammaSlider.setOrientation(QtCore.Qt.Horizontal)
self.GammaSlider.setObjectName(_fromUtf8("GammaSlider")) self.GammaSlider.setObjectName("GammaSlider")
self.ProgressBar = QtGui.QProgressBar(self.Form) self.ProgressBar = QtWidgets.QProgressBar(self.Form)
self.ProgressBar.setGeometry(QtCore.QRect(10, 10, 401, 35)) self.ProgressBar.setGeometry(QtCore.QRect(10, 10, 401, 29))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("Lucida Grande")) font.setFamily("Lucida Grande")
font.setPointSize(10) font.setPointSize(10)
font.setBold(True) font.setBold(True)
font.setWeight(75) font.setWeight(75)
self.ProgressBar.setFont(font) self.ProgressBar.setFont(font)
self.ProgressBar.setAutoFillBackground(True)
self.ProgressBar.setProperty("value", 0) self.ProgressBar.setProperty("value", 0)
self.ProgressBar.setAlignment(QtCore.Qt.AlignJustify|QtCore.Qt.AlignVCenter) self.ProgressBar.setAlignment(QtCore.Qt.AlignJustify|QtCore.Qt.AlignVCenter)
self.ProgressBar.setFormat(_fromUtf8("")) self.ProgressBar.setFormat("")
self.ProgressBar.setObjectName(_fromUtf8("ProgressBar")) self.ProgressBar.setObjectName("ProgressBar")
self.OptionsExpert = QtGui.QFrame(self.Form) self.OptionsExpert = QtWidgets.QFrame(self.Form)
self.OptionsExpert.setGeometry(QtCore.QRect(5, 335, 421, 41)) self.OptionsExpert.setGeometry(QtCore.QRect(5, 335, 421, 41))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("Lucida Grande")) font.setFamily("Lucida Grande")
font.setPointSize(9) font.setPointSize(9)
self.OptionsExpert.setFont(font) self.OptionsExpert.setFont(font)
self.OptionsExpert.setObjectName(_fromUtf8("OptionsExpert")) self.OptionsExpert.setObjectName("OptionsExpert")
self.ColorBox = QtGui.QCheckBox(self.OptionsExpert) self.ColorBox = QtWidgets.QCheckBox(self.OptionsExpert)
self.ColorBox.setGeometry(QtCore.QRect(9, 11, 130, 18)) self.ColorBox.setGeometry(QtCore.QRect(9, 11, 130, 18))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("Lucida Grande")) font.setFamily("Lucida Grande")
font.setPointSize(12) font.setPointSize(12)
self.ColorBox.setFont(font) self.ColorBox.setFont(font)
self.ColorBox.setFocusPolicy(QtCore.Qt.NoFocus) self.ColorBox.setFocusPolicy(QtCore.Qt.NoFocus)
self.ColorBox.setObjectName(_fromUtf8("ColorBox")) self.ColorBox.setObjectName("ColorBox")
self.OptionsExpertInternal = QtGui.QFrame(self.OptionsExpert) self.OptionsExpertInternal = QtWidgets.QFrame(self.OptionsExpert)
self.OptionsExpertInternal.setGeometry(QtCore.QRect(95, 0, 315, 40)) self.OptionsExpertInternal.setGeometry(QtCore.QRect(95, 0, 315, 40))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("Lucida Grande")) font.setFamily("Lucida Grande")
self.OptionsExpertInternal.setFont(font) self.OptionsExpertInternal.setFont(font)
self.OptionsExpertInternal.setObjectName(_fromUtf8("OptionsExpertInternal")) self.OptionsExpertInternal.setObjectName("OptionsExpertInternal")
self.gridLayout_2 = QtGui.QGridLayout(self.OptionsExpertInternal) self.gridLayout_2 = QtWidgets.QGridLayout(self.OptionsExpertInternal)
self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2")) self.gridLayout_2.setObjectName("gridLayout_2")
self.wLabel = QtGui.QLabel(self.OptionsExpertInternal) self.wLabel = QtWidgets.QLabel(self.OptionsExpertInternal)
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("Lucida Grande")) font.setFamily("Lucida Grande")
font.setPointSize(12) font.setPointSize(12)
font.setBold(False) font.setBold(False)
font.setWeight(50) font.setWeight(50)
self.wLabel.setFont(font) self.wLabel.setFont(font)
self.wLabel.setObjectName(_fromUtf8("wLabel")) self.wLabel.setObjectName("wLabel")
self.gridLayout_2.addWidget(self.wLabel, 0, 0, 1, 1) self.gridLayout_2.addWidget(self.wLabel, 0, 0, 1, 1)
self.customWidth = QtGui.QLineEdit(self.OptionsExpertInternal) self.customWidth = QtWidgets.QLineEdit(self.OptionsExpertInternal)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.customWidth.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(self.customWidth.sizePolicy().hasHeightForWidth())
self.customWidth.setSizePolicy(sizePolicy) self.customWidth.setSizePolicy(sizePolicy)
self.customWidth.setMaximumSize(QtCore.QSize(45, 16777215)) self.customWidth.setMaximumSize(QtCore.QSize(45, 16777215))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("Lucida Grande")) font.setFamily("Lucida Grande")
font.setPointSize(12) font.setPointSize(12)
self.customWidth.setFont(font) self.customWidth.setFont(font)
self.customWidth.setFocusPolicy(QtCore.Qt.ClickFocus) self.customWidth.setFocusPolicy(QtCore.Qt.ClickFocus)
self.customWidth.setAcceptDrops(False) self.customWidth.setAcceptDrops(False)
self.customWidth.setMaxLength(4) self.customWidth.setMaxLength(4)
self.customWidth.setObjectName(_fromUtf8("customWidth")) self.customWidth.setObjectName("customWidth")
self.gridLayout_2.addWidget(self.customWidth, 0, 1, 1, 1) 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 = QtGui.QFont()
font.setFamily(_fromUtf8("Lucida Grande")) font.setFamily("Lucida Grande")
font.setPointSize(12) font.setPointSize(12)
font.setBold(False) font.setBold(False)
font.setWeight(50) font.setWeight(50)
self.hLabel.setFont(font) self.hLabel.setFont(font)
self.hLabel.setObjectName(_fromUtf8("hLabel")) self.hLabel.setObjectName("hLabel")
self.gridLayout_2.addWidget(self.hLabel, 0, 2, 1, 1) self.gridLayout_2.addWidget(self.hLabel, 0, 2, 1, 1)
self.customHeight = QtGui.QLineEdit(self.OptionsExpertInternal) self.customHeight = QtWidgets.QLineEdit(self.OptionsExpertInternal)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.customHeight.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(self.customHeight.sizePolicy().hasHeightForWidth())
self.customHeight.setSizePolicy(sizePolicy) self.customHeight.setSizePolicy(sizePolicy)
self.customHeight.setMaximumSize(QtCore.QSize(45, 16777215)) self.customHeight.setMaximumSize(QtCore.QSize(45, 16777215))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("Lucida Grande")) font.setFamily("Lucida Grande")
font.setPointSize(12) font.setPointSize(12)
self.customHeight.setFont(font) self.customHeight.setFont(font)
self.customHeight.setFocusPolicy(QtCore.Qt.ClickFocus) self.customHeight.setFocusPolicy(QtCore.Qt.ClickFocus)
self.customHeight.setAcceptDrops(False) self.customHeight.setAcceptDrops(False)
self.customHeight.setMaxLength(4) self.customHeight.setMaxLength(4)
self.customHeight.setObjectName(_fromUtf8("customHeight")) self.customHeight.setObjectName("customHeight")
self.gridLayout_2.addWidget(self.customHeight, 0, 3, 1, 1) self.gridLayout_2.addWidget(self.customHeight, 0, 3, 1, 1)
KCC.setCentralWidget(self.Form) KCC.setCentralWidget(self.Form)
self.statusBar = QtGui.QStatusBar(KCC) self.statusBar = QtWidgets.QStatusBar(KCC)
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(_fromUtf8("Aharoni")) font.setFamily("Aharoni")
font.setPointSize(8) font.setPointSize(8)
self.statusBar.setFont(font) self.statusBar.setFont(font)
self.statusBar.setSizeGripEnabled(False) self.statusBar.setSizeGripEnabled(False)
self.statusBar.setObjectName(_fromUtf8("statusBar")) self.statusBar.setObjectName("statusBar")
KCC.setStatusBar(self.statusBar) KCC.setStatusBar(self.statusBar)
self.ActionBasic = QtGui.QAction(KCC) self.ActionBasic = QtWidgets.QAction(KCC)
self.ActionBasic.setCheckable(True) self.ActionBasic.setCheckable(True)
self.ActionBasic.setChecked(False) self.ActionBasic.setChecked(False)
font = QtGui.QFont() font = QtGui.QFont()
font.setPointSize(9) font.setPointSize(9)
self.ActionBasic.setFont(font) self.ActionBasic.setFont(font)
self.ActionBasic.setObjectName(_fromUtf8("ActionBasic")) self.ActionBasic.setObjectName("ActionBasic")
self.ActionAdvanced = QtGui.QAction(KCC) self.ActionAdvanced = QtWidgets.QAction(KCC)
self.ActionAdvanced.setCheckable(True) self.ActionAdvanced.setCheckable(True)
self.ActionAdvanced.setObjectName(_fromUtf8("ActionAdvanced")) self.ActionAdvanced.setObjectName("ActionAdvanced")
self.retranslateUi(KCC) self.retranslateUi(KCC)
QtCore.QMetaObject.connectSlotsByName(KCC) QtCore.QMetaObject.connectSlotsByName(KCC)
@@ -365,45 +350,47 @@ class Ui_KCC(object):
KCC.setTabOrder(self.ConvertButton, self.ClearButton) KCC.setTabOrder(self.ConvertButton, self.ClearButton)
def retranslateUi(self, KCC): def retranslateUi(self, KCC):
KCC.setWindowTitle(_translate("KCC", "Kindle Comic Converter", None)) _translate = QtCore.QCoreApplication.translate
self.ProcessingBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-size:12pt;\">Disable image optimizations.</span></p></body></html>", None)) KCC.setWindowTitle(_translate("KCC", "Kindle Comic Converter"))
self.ProcessingBox.setText(_translate("KCC", "No optimisation", None)) self.ProcessingBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Disable image optimizations.<br/>Input images must be already resized.</p></body></html>"))
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.ProcessingBox.setText(_translate("KCC", "No optimisation"))
self.UpscaleBox.setText(_translate("KCC", "Stretch/Upscale", 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>"))
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.UpscaleBox.setText(_translate("KCC", "Stretch/Upscale"))
self.WebtoonBox.setText(_translate("KCC", "Webtoon mode", None)) self.WebtoonBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>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>"))
self.NoDitheringBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-size:12pt;\">Create PNG files instead JPEG.<br/>Quality increase is not noticeable on most of devices.<br/>Output files </span><span style=\" font-size:12pt; font-weight:600;\">might</span><span style=\" font-size:12pt;\"> be smaller.<br/></span><span style=\" font-size:12pt; font-weight:600;\">MOBI conversion will be much slower.</span></p></body></html>", None)) self.WebtoonBox.setText(_translate("KCC", "Webtoon mode"))
self.NoDitheringBox.setText(_translate("KCC", "PNG output", None)) 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.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.NoDitheringBox.setText(_translate("KCC", "PNG output"))
self.BorderBox.setText(_translate("KCC", "W/B margins", 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>"))
self.NoRotateBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-size:12pt;\">Disable splitting and rotation.</span></p></body></html>", None)) self.BorderBox.setText(_translate("KCC", "W/B margins"))
self.NoRotateBox.setText(_translate("KCC", "No split/rotate", None)) self.NoRotateBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Disable splitting and rotation.</p></body></html>"))
self.DeviceBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-size:12pt;\">Target device.</span></p></body></html>", None)) self.NoRotateBox.setText(_translate("KCC", "No split/rotate"))
self.FormatBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-size:12pt;\">Output format.</span></p></body></html>", None)) self.DeviceBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Target device.</p></body></html>"))
self.ConvertButton.setText(_translate("KCC", "Convert", None)) self.FormatBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Output format.</p></body></html>"))
self.DirectoryButton.setText(_translate("KCC", "Add directory", None)) self.ConvertButton.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Shift+Click to select the output directory.</p></body></html>"))
self.FileButton.setText(_translate("KCC", "Add file", None)) self.ConvertButton.setText(_translate("KCC", "Convert"))
self.ClearButton.setText(_translate("KCC", "Clear list", None)) self.DirectoryButton.setText(_translate("KCC", "Add directory"))
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.FileButton.setText(_translate("KCC", "Add file"))
self.MangaBox.setText(_translate("KCC", "Manga mode", None)) self.ClearButton.setText(_translate("KCC", "Clear list"))
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.<br/>Smaller images might be forcefully upscaled in this mode.</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.MangaBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Enable right-to-left reading.</p></body></html>"))
self.QualityBox.setText(_translate("KCC", "High/Ultra quality", None)) self.MangaBox.setText(_translate("KCC", "Manga mode"))
self.RotateBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-size:12pt;\">Disable splitting of two-page spreads.<br/>They will be rotated instead.</span></p></body></html>", None)) self.QualityBox.setToolTip(_translate("KCC", "<html><head/><body><p><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.<br/></span>- Maximum quality when zoom is not enabled.<br/>- Poor quality when zoom is enabled.<br/>- Lowest file size.</p><p><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 a little blurry.<br/></span>- High quality when zoom is not enabled.<br/>- Maximum quality when zoom is enabled.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - Ultra quality mode<br/></span><span style=\" font-style:italic;\">Maximum possible quality.<br/></span>- Maximum quality when zoom is not enabled.<br/>- Maximum quality when zoom is enabled.<br/>- Very high file size.</p></body></html>"))
self.RotateBox.setText(_translate("KCC", "Horizontal mode", None)) self.QualityBox.setText(_translate("KCC", "High/Ultra quality"))
self.BasicModeButton.setText(_translate("KCC", "Basic", None)) 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.AdvModeButton.setText(_translate("KCC", "Advanced", None)) self.RotateBox.setText(_translate("KCC", "Horizontal mode"))
self.GammaLabel.setText(_translate("KCC", "Gamma: Auto", None)) self.BasicModeButton.setText(_translate("KCC", "Basic"))
self.ColorBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-size:12pt;\">Don\'t convert images to grayscale.</span></p></body></html>", None)) self.AdvModeButton.setText(_translate("KCC", "Advanced"))
self.ColorBox.setText(_translate("KCC", "Color mode", None)) self.GammaLabel.setText(_translate("KCC", "Gamma: Auto"))
self.wLabel.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-size:12pt;\">Resolution of target device.</span></p></body></html>", None)) self.ColorBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Don\'t convert images to grayscale.</p></body></html>"))
self.wLabel.setText(_translate("KCC", "Custom width: ", None)) self.ColorBox.setText(_translate("KCC", "Color mode"))
self.customWidth.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-size:12pt;\">Resolution of target device.</span></p></body></html>", None)) self.wLabel.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Resolution of target device.</p></body></html>"))
self.customWidth.setInputMask(_translate("KCC", "0000; ", None)) self.wLabel.setText(_translate("KCC", "Custom width: "))
self.hLabel.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-size:12pt;\">Resolution of target device.</span></p></body></html>", None)) self.customWidth.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: ", None)) self.customWidth.setInputMask(_translate("KCC", "0000"))
self.customHeight.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-size:12pt;\">Resolution of target device.</span></p></body></html>", None)) self.hLabel.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Resolution of target device.</p></body></html>"))
self.customHeight.setInputMask(_translate("KCC", "0000; ", None)) self.hLabel.setText(_translate("KCC", "Custom height: "))
self.ActionBasic.setText(_translate("KCC", "Basic", None)) self.customHeight.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Resolution of target device.</p></body></html>"))
self.ActionAdvanced.setText(_translate("KCC", "Advanced", None)) self.customHeight.setInputMask(_translate("KCC", "0000"))
self.ActionBasic.setText(_translate("KCC", "Basic"))
self.ActionAdvanced.setText(_translate("KCC", "Advanced"))
import KCC_rc from . import KCC_rc

View File

@@ -1,4 +1,4 @@
__version__ = '3.7.2' __version__ = '4.0.2'
__license__ = 'ISC' __license__ = 'ISC'
__copyright__ = '2012-2013, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>' __copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'

View File

@@ -1,5 +1,5 @@
# Copyright (c) 2012-2013 Ciro Mattia Gonano <ciromattia@gmail.com> # Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
# Copyright (c) 2013 Pawel Jastrzebski <pawelj@vulturis.eu> # Copyright (c) 2013-2014 Pawel Jastrzebski <pawelj@vulturis.eu>
# #
# Permission to use, copy, modify, and/or distribute this software for # Permission to use, copy, modify, and/or distribute this software for
# any purpose with or without fee is hereby granted, provided that the # any purpose with or without fee is hereby granted, provided that the
@@ -15,35 +15,24 @@
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE. # PERFORMANCE OF THIS SOFTWARE.
# #
__license__ = 'ISC' __license__ = 'ISC'
__copyright__ = '2012-2013, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>' __copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
import sys
import os import os
import zipfile from zipfile import is_zipfile, ZipFile
import rarfile
import locale
from sys import platform
from subprocess import STDOUT, PIPE from subprocess import STDOUT, PIPE
try: from psutil import Popen
# noinspection PyUnresolvedReferences from shutil import move, copy
from psutil import Popen from . import rarfile
except ImportError:
print "ERROR: Psutil is not installed!"
if platform.startswith('linux'):
import Tkinter
import tkMessageBox
importRoot = Tkinter.Tk()
importRoot.withdraw()
tkMessageBox.showerror("KCC - Error", "Psutil is not installed!")
exit(1)
from shutil import move
class CBxArchive: class CBxArchive:
def __init__(self, origFileName): def __init__(self, origFileName):
self.origFileName = origFileName self.origFileName = origFileName
if zipfile.is_zipfile(origFileName): if is_zipfile(origFileName):
self.compressor = 'zip' self.compressor = 'zip'
elif rarfile.is_rarfile(origFileName): elif rarfile.is_rarfile(origFileName):
self.compressor = 'rar' self.compressor = 'rar'
@@ -56,7 +45,7 @@ class CBxArchive:
return self.compressor is not None return self.compressor is not None
def extractCBZ(self, targetdir): def extractCBZ(self, targetdir):
cbzFile = zipfile.ZipFile(self.origFileName) cbzFile = ZipFile(self.origFileName)
filelist = [] filelist = []
for f in cbzFile.namelist(): for f in cbzFile.namelist():
if f.startswith('__MACOSX') or f.endswith('.DS_Store') or f.endswith('thumbs.db'): if f.startswith('__MACOSX') or f.endswith('.DS_Store') or f.endswith('thumbs.db'):
@@ -64,14 +53,14 @@ class CBxArchive:
elif f.endswith('/'): elif f.endswith('/'):
try: try:
os.makedirs(os.path.join(targetdir, f)) os.makedirs(os.path.join(targetdir, f))
except StandardError: except Exception:
pass # the dir exists so we are going to extract the images only. pass # the dir exists so we are going to extract the images only.
else: else:
filelist.append(f) filelist.append(f)
cbzFile.extractall(targetdir, filelist) cbzFile.extractall(targetdir, filelist)
def extractCBR(self, targetdir): def extractCBR(self, targetdir):
cbrFile = rarfile.RarFile(self.origFileName.encode(locale.getpreferredencoding())) cbrFile = rarfile.RarFile(self.origFileName)
filelist = [] filelist = []
for f in cbrFile.namelist(): for f in cbrFile.namelist():
if f.startswith('__MACOSX') or f.endswith('.DS_Store') or f.endswith('thumbs.db'): if f.startswith('__MACOSX') or f.endswith('.DS_Store') or f.endswith('thumbs.db'):
@@ -79,25 +68,29 @@ class CBxArchive:
elif f.endswith('/'): elif f.endswith('/'):
try: try:
os.makedirs(os.path.join(targetdir, f)) os.makedirs(os.path.join(targetdir, f))
except StandardError: except Exception:
pass # the dir exists so we are going to extract the images only. pass # the dir exists so we are going to extract the images only.
else: else:
filelist.append(f.encode(locale.getpreferredencoding())) filelist.append(f)
cbrFile.extractall(targetdir, filelist) cbrFile.extractall(targetdir, filelist)
def extractCB7(self, targetdir): def extractCB7(self, targetdir):
output = Popen('7za x "' + self.origFileName.encode(locale.getpreferredencoding()) + # Workaround for some wide UTF-8 + Popen abnormalities
'" -xr!__MACOSX -xr!.DS_Store -xr!thumbs.db -o"' + targetdir + '"', if sys.platform.startswith('darwin'):
stdout=PIPE, stderr=STDOUT, shell=True) 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 extracted = False
for line in output.stdout: for line in output.stdout:
if "Everything is Ok" in line: if b"Everything is Ok" in line:
extracted = True extracted = True
if sys.platform.startswith('darwin'):
os.remove(self.origFileName)
if not extracted: if not extracted:
raise OSError raise OSError
def extract(self, targetdir): def extract(self, targetdir):
print "\n" + targetdir + "\n"
if self.compressor == 'rar': if self.compressor == 'rar':
self.extractCBR(targetdir) self.extractCBR(targetdir)
elif self.compressor == 'zip': elif self.compressor == 'zip':
@@ -109,6 +102,10 @@ class CBxArchive:
adir.remove('ComicInfo.xml') adir.remove('ComicInfo.xml')
if len(adir) == 1 and os.path.isdir(os.path.join(targetdir, adir[0])): if len(adir) == 1 and os.path.isdir(os.path.join(targetdir, adir[0])):
for f in os.listdir(os.path.join(targetdir, adir[0])): for f in os.listdir(os.path.join(targetdir, adir[0])):
# 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)):
os.replace(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) move(os.path.join(targetdir, adir[0], f), targetdir)
os.rmdir(os.path.join(targetdir, adir[0])) os.rmdir(os.path.join(targetdir, adir[0]))
return targetdir return targetdir

View File

@@ -1,8 +1,7 @@
#!/usr/bin/env python2
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
# Copyright (c) 2012-2013 Ciro Mattia Gonano <ciromattia@gmail.com> # Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
# Copyright (c) 2013 Pawel Jastrzebski <pawelj@vulturis.eu> # Copyright (c) 2013-2014 Pawel Jastrzebski <pawelj@vulturis.eu>
# #
# Permission to use, copy, modify, and/or distribute this software for # Permission to use, copy, modify, and/or distribute this software for
# any purpose with or without fee is hereby granted, provided that the # any purpose with or without fee is hereby granted, provided that the
@@ -18,71 +17,53 @@
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE. # PERFORMANCE OF THIS SOFTWARE.
# #
__version__ = '3.7.2'
__version__ = '4.0.2'
__license__ = 'ISC' __license__ = 'ISC'
__copyright__ = '2012-2013, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>' __copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
import os import os
import sys import sys
import re from re import split, sub
import stat from stat import S_IWRITE, S_IREAD, S_IEXEC
import string from zipfile import ZipFile, ZIP_STORED, ZIP_DEFLATED
import unicodedata
import zipfile
from tempfile import mkdtemp from tempfile import mkdtemp
from shutil import move, copyfile, copytree, rmtree from shutil import move, copyfile, copytree, rmtree
from optparse import OptionParser, OptionGroup from optparse import OptionParser, OptionGroup
from multiprocessing import Pool, freeze_support from multiprocessing import Pool
from xml.dom.minidom import parse from xml.dom.minidom import parse
from uuid import uuid4 from uuid import uuid4
from slugify import slugify as slugifyExt
from PIL import Image
try: try:
# noinspection PyUnresolvedReferences from PyQt5 import QtCore
from PIL import Image
if tuple(map(int, ('2.3.0'.split(".")))) > tuple(map(int, (Image.PILLOW_VERSION.split(".")))):
print "ERROR: Pillow 2.3.0 or newer is required!"
if sys.platform.startswith('linux'):
import Tkinter
import tkMessageBox
importRoot = Tkinter.Tk()
importRoot.withdraw()
tkMessageBox.showerror("KCC - Error", "Pillow 2.3.0 or newer is required!")
exit(1)
except ImportError:
print "ERROR: Pillow is not installed!"
if sys.platform.startswith('linux'):
import Tkinter
import tkMessageBox
importRoot = Tkinter.Tk()
importRoot.withdraw()
tkMessageBox.showerror("KCC - Error", "Pillow 2.3.0 or newer is required!")
exit(1)
try:
from PyQt4 import QtCore
except ImportError: except ImportError:
QtCore = None QtCore = None
import comic2panel from .shared import md5Checksum, getImageFileName, walkLevel
import image from . import comic2panel
import cbxarchive from . import image
import pdfjpgextract from . import cbxarchive
from . import pdfjpgextract
def buildHTML(path, imgfile): def buildHTML(path, imgfile, imgfilepath):
imgfilepath = md5Checksum(imgfilepath)
filename = getImageFileName(imgfile) filename = getImageFileName(imgfile)
if filename is not None: if filename is not None:
if "_kccrot" in str(filename): if "Rotated" in theGreatIndex[imgfilepath]:
rotatedPage = True rotatedPage = True
else: else:
rotatedPage = False rotatedPage = False
if "_kccnpv" in str(filename): if "NoPanelView" in theGreatIndex[imgfilepath]:
noPV = True noPV = True
else: else:
noPV = False noPV = False
if "_kccnh" in str(filename): if "NoHorizontalPanelView" in theGreatIndex[imgfilepath]:
noHorizontalPV = True noHorizontalPV = True
else: else:
noHorizontalPV = False noHorizontalPV = False
if "_kccnv" in str(filename): if "NoVerticalPanelView" in theGreatIndex[imgfilepath]:
noVerticalPV = True noVerticalPV = True
else: else:
noVerticalPV = False noVerticalPV = False
@@ -100,7 +81,7 @@ def buildHTML(path, imgfile):
if not os.path.exists(htmlpath): if not os.path.exists(htmlpath):
os.makedirs(htmlpath) os.makedirs(htmlpath)
htmlfile = os.path.join(htmlpath, filename[0] + '.html') htmlfile = os.path.join(htmlpath, filename[0] + '.html')
f = open(htmlfile, "w") f = open(htmlfile, "w", encoding='UTF-8')
f.writelines(["<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" ", f.writelines(["<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" ",
"\"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n", "\"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n",
"<html xmlns=\"http://www.w3.org/1999/xhtml\">\n", "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n",
@@ -154,40 +135,12 @@ def buildHTML(path, imgfile):
"'{\"targetId\":\"" + boxes[i] + "-Panel-Parent\", \"ordinal\":" + str(order[i]), "'{\"targetId\":\"" + boxes[i] + "-Panel-Parent\", \"ordinal\":" + str(order[i]),
"}'></a></div>\n"]) "}'></a></div>\n"])
if options.quality == 2: if options.quality == 2:
imgfilepv = string.split(imgfile, ".") imgfilepv = str.split(imgfile, ".")
imgfilepv[0] = imgfilepv[0].split("_kccxl")[0].replace("_kccnh", "").replace("_kccnv", "") imgfilepv[0] += "-hq"
imgfilepv[0] += "_kcchq" imgfilepv = ".".join(imgfilepv)
imgfilepv = string.join(imgfilepv, ".")
else: else:
imgfilepv = imgfile imgfilepv = imgfile
if "_kccxl" in filename[0]: xl, yu, xr, yd = checkMargins(imgfilepath)
borders = filename[0].split('_kccxl')[1]
borders = re.findall('[0-9]{1,6}', borders)
xl = borders[0].lstrip("0")
yu = borders[1].lstrip("0")
xr = borders[2].lstrip("0")
yd = borders[3].lstrip("0")
if xl != "":
xl = "-" + str(float(xl)/100) + "%"
else:
xl = "0%"
if xr != "":
xr = "-" + str(float(xr)/100) + "%"
else:
xr = "0%"
if yu != "":
yu = "-" + str(float(yu)/100) + "%"
else:
yu = "0%"
if yd != "":
yd = "-" + str(float(yd)/100) + "%"
else:
yd = "0%"
else:
xl = "0%"
yu = "0%"
xr = "0%"
yd = "0%"
boxStyles = {"BoxTL": "left:" + xl + ";top:" + yu + ";", boxStyles = {"BoxTL": "left:" + xl + ";top:" + yu + ";",
"BoxTR": "right:" + xr + ";top:" + yu + ";", "BoxTR": "right:" + xr + ";top:" + yu + ";",
"BoxBL": "left:" + xl + ";bottom:" + yd + ";", "BoxBL": "left:" + xl + ";bottom:" + yd + ";",
@@ -209,11 +162,38 @@ def buildHTML(path, imgfile):
return path, imgfile return path, imgfile
def buildNCX(dstdir, title, chapters): def checkMargins(path):
for flag in theGreatIndex[path]:
if "Margins-" in flag:
flag = flag.split('-')
xl = flag[1]
yu = flag[2]
xr = flag[3]
yd = flag[4]
if xl != "0":
xl = "-" + str(float(xl)/100) + "%"
else:
xl = "0%"
if xr != "0":
xr = "-" + str(float(xr)/100) + "%"
else:
xr = "0%"
if yu != "0":
yu = "-" + str(float(yu)/100) + "%"
else:
yu = "0%"
if yd != "0":
yd = "-" + str(float(yd)/100) + "%"
else:
yd = "0%"
return xl, yu, xr, yd
return '0%', '0%', '0%', '0%'
def buildNCX(dstdir, title, chapters, chapterNames):
options.uuid = str(uuid4()) options.uuid = str(uuid4())
options.uuid = options.uuid.encode('utf-8')
ncxfile = os.path.join(dstdir, 'OEBPS', 'toc.ncx') ncxfile = os.path.join(dstdir, 'OEBPS', 'toc.ncx')
f = open(ncxfile, "w") f = open(ncxfile, "w", encoding='UTF-8')
f.writelines(["<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", f.writelines(["<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",
"<!DOCTYPE ncx PUBLIC \"-//NISO//DTD ncx 2005-1//EN\" ", "<!DOCTYPE ncx PUBLIC \"-//NISO//DTD ncx 2005-1//EN\" ",
"\"http://www.daisy.org/z3986/2005/ncx-2005-1.dtd\">\n", "\"http://www.daisy.org/z3986/2005/ncx-2005-1.dtd\">\n",
@@ -225,16 +205,16 @@ def buildNCX(dstdir, title, chapters):
"<meta name=\"dtb:maxPageNumber\" content=\"0\"/>\n", "<meta name=\"dtb:maxPageNumber\" content=\"0\"/>\n",
"<meta name=\"generated\" content=\"true\"/>\n", "<meta name=\"generated\" content=\"true\"/>\n",
"</head>\n", "</head>\n",
"<docTitle><text>", title.encode('utf-8'), "</text></docTitle>\n", "<docTitle><text>", title, "</text></docTitle>\n",
"<navMap>" "<navMap>"
]) ])
for chapter in chapters: for chapter in chapters:
folder = chapter[0].replace(os.path.join(dstdir, 'OEBPS'), '').lstrip('/').lstrip('\\\\') folder = chapter[0].replace(os.path.join(dstdir, 'OEBPS'), '').lstrip('/').lstrip('\\\\')
if os.path.basename(folder) != "Text": if os.path.basename(folder) != "Text":
title = os.path.basename(folder) title = chapterNames[os.path.basename(folder)]
filename = getImageFileName(os.path.join(folder, chapter[1])) filename = getImageFileName(os.path.join(folder, chapter[1]))
f.write("<navPoint id=\"" + folder.replace('/', '_').replace('\\', '_') + "\"><navLabel><text>" f.write("<navPoint id=\"" + folder.replace('/', '_').replace('\\', '_') + "\"><navLabel><text>"
+ title.encode('utf-8') + "</text></navLabel><content src=\"" + filename[0].replace("\\", "/") + title + "</text></navLabel><content src=\"" + filename[0].replace("\\", "/")
+ ".html\"/></navPoint>\n") + ".html\"/></navPoint>\n")
f.write("</navMap>\n</ncx>") f.write("</navMap>\n</ncx>")
f.close() f.close()
@@ -249,17 +229,17 @@ def buildOPF(dstdir, title, filelist, cover=None):
writingmode = "horizontal-rl" writingmode = "horizontal-rl"
else: else:
writingmode = "horizontal-lr" writingmode = "horizontal-lr"
f = open(opffile, "w") f = open(opffile, "w", encoding='UTF-8')
f.writelines(["<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", f.writelines(["<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",
"<package version=\"2.0\" unique-identifier=\"BookID\" ", "<package version=\"2.0\" unique-identifier=\"BookID\" ",
"xmlns=\"http://www.idpf.org/2007/opf\">\n", "xmlns=\"http://www.idpf.org/2007/opf\">\n",
"<metadata xmlns:opf=\"http://www.idpf.org/2007/opf\" ", "<metadata xmlns:opf=\"http://www.idpf.org/2007/opf\" ",
"xmlns:dc=\"http://purl.org/dc/elements/1.1/\">\n", "xmlns:dc=\"http://purl.org/dc/elements/1.1/\">\n",
"<dc:title>", title.encode('utf-8'), "</dc:title>\n", "<dc:title>", title, "</dc:title>\n",
"<dc:language>en-US</dc:language>\n", "<dc:language>en-US</dc:language>\n",
"<dc:identifier id=\"BookID\" opf:scheme=\"UUID\">", options.uuid, "</dc:identifier>\n"]) "<dc:identifier id=\"BookID\" opf:scheme=\"UUID\">", options.uuid, "</dc:identifier>\n"])
for author in options.authors: for author in options.authors:
f.writelines(["<dc:creator>", author.encode('utf-8'), "</dc:creator>\n"]) f.writelines(["<dc:creator>", author, "</dc:creator>\n"])
f.writelines(["<meta name=\"generator\" content=\"KindleComicConverter-" + __version__ + "\"/>\n", f.writelines(["<meta name=\"generator\" content=\"KindleComicConverter-" + __version__ + "\"/>\n",
"<meta name=\"RegionMagnification\" content=\"true\"/>\n", "<meta name=\"RegionMagnification\" content=\"true\"/>\n",
"<meta name=\"region-mag\" content=\"true\"/>\n", "<meta name=\"region-mag\" content=\"true\"/>\n",
@@ -290,14 +270,14 @@ def buildOPF(dstdir, title, filelist, cover=None):
filename = getImageFileName(path[1]) filename = getImageFileName(path[1])
uniqueid = os.path.join(folder, filename[0]).replace('/', '_').replace('\\', '_') uniqueid = os.path.join(folder, filename[0]).replace('/', '_').replace('\\', '_')
reflist.append(uniqueid) reflist.append(uniqueid)
f.write("<item id=\"page_" + uniqueid + "\" href=\"" f.write("<item id=\"page_" + str(uniqueid) + "\" href=\""
+ folder.replace('Images', 'Text') + "/" + filename[0] + folder.replace('Images', 'Text') + "/" + filename[0]
+ ".html\" media-type=\"application/xhtml+xml\"/>\n") + ".html\" media-type=\"application/xhtml+xml\"/>\n")
if '.png' == filename[1]: if '.png' == filename[1]:
mt = 'image/png' mt = 'image/png'
else: else:
mt = 'image/jpeg' mt = 'image/jpeg'
f.write("<item id=\"img_" + uniqueid + "\" href=\"" + folder + "/" + path[1] + "\" media-type=\"" f.write("<item id=\"img_" + str(uniqueid) + "\" href=\"" + folder + "/" + path[1] + "\" media-type=\""
+ mt + "\"/>\n") + mt + "\"/>\n")
f.write("<item id=\"css\" href=\"Text/style.css\" media-type=\"text/css\"/>\n") f.write("<item id=\"css\" href=\"Text/style.css\" media-type=\"text/css\"/>\n")
f.write("</manifest>\n<spine toc=\"ncx\">\n") f.write("</manifest>\n<spine toc=\"ncx\">\n")
@@ -306,7 +286,7 @@ def buildOPF(dstdir, title, filelist, cover=None):
f.write("</spine>\n<guide>\n</guide>\n</package>\n") f.write("</spine>\n<guide>\n</guide>\n</package>\n")
f.close() f.close()
os.mkdir(os.path.join(dstdir, 'META-INF')) os.mkdir(os.path.join(dstdir, 'META-INF'))
f = open(os.path.join(dstdir, 'META-INF', 'container.xml'), 'w') f = open(os.path.join(dstdir, 'META-INF', 'container.xml'), 'w', encoding='UTF-8')
f.writelines(["<?xml version=\"1.0\"?>\n", f.writelines(["<?xml version=\"1.0\"?>\n",
"<container version=\"1.0\" xmlns=\"urn:oasis:names:tc:opendocument:xmlns:container\">\n", "<container version=\"1.0\" xmlns=\"urn:oasis:names:tc:opendocument:xmlns:container\">\n",
"<rootfiles>\n", "<rootfiles>\n",
@@ -317,20 +297,6 @@ def buildOPF(dstdir, title, filelist, cover=None):
return return
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 applyImgOptimization(img, opt, hqImage=None): def applyImgOptimization(img, opt, hqImage=None):
if not img.fill: if not img.fill:
img.getImageFill(opt.webtoon) img.getImageFill(opt.webtoon)
@@ -354,10 +320,12 @@ def applyImgOptimization(img, opt, hqImage=None):
def dirImgProcess(path): def dirImgProcess(path):
global workerPool, workerOutput global workerPool, workerOutput, theGreatIndex, theGreatWipe
workerPool = Pool() workerPool = Pool()
workerOutput = [] workerOutput = []
work = [] work = []
theGreatIndex = {}
theGreatWipe = []
pagenumber = 0 pagenumber = 0
for (dirpath, dirnames, filenames) in os.walk(path): for (dirpath, dirnames, filenames) in os.walk(path):
for afile in filenames: for afile in filenames:
@@ -365,7 +333,7 @@ def dirImgProcess(path):
pagenumber += 1 pagenumber += 1
work.append([afile, dirpath, options]) work.append([afile, dirpath, options])
if GUI: if GUI:
GUI.emit(QtCore.SIGNAL("progressBarTick"), pagenumber) GUI.progressBarTick.emit(str(pagenumber))
if len(work) > 0: if len(work) > 0:
for i in work: for i in work:
workerPool.apply_async(func=fileImgProcess, args=(i, ), callback=fileImgProcess_tick) workerPool.apply_async(func=fileImgProcess, args=(i, ), callback=fileImgProcess_tick)
@@ -377,17 +345,27 @@ def dirImgProcess(path):
if len(workerOutput) > 0: if len(workerOutput) > 0:
rmtree(os.path.join(path, '..', '..'), True) rmtree(os.path.join(path, '..', '..'), True)
raise RuntimeError("One of workers crashed. Cause: " + workerOutput[0]) raise RuntimeError("One of workers crashed. Cause: " + workerOutput[0])
for file in theGreatWipe:
if os.path.isfile(file):
os.remove(file)
else: else:
rmtree(os.path.join(path, '..', '..'), True) rmtree(os.path.join(path, '..', '..'), True)
raise UserWarning("Source directory is empty.") raise UserWarning("Source directory is empty.")
def fileImgProcess_tick(output): def fileImgProcess_tick(output):
if output: if isinstance(output, str):
workerOutput.append(output) workerOutput.append(output)
workerPool.terminate() workerPool.terminate()
else:
for page in output:
if page is not None:
if isinstance(page, str):
theGreatWipe.append(page)
else:
theGreatIndex[page[0]] = page[1]
if GUI: if GUI:
GUI.emit(QtCore.SIGNAL("progressBarTick")) GUI.progressBarTick.emit('tick')
if not GUI.conversionAlive: if not GUI.conversionAlive:
workerPool.terminate() workerPool.terminate()
@@ -397,56 +375,61 @@ def fileImgProcess(work):
afile = work[0] afile = work[0]
dirpath = work[1] dirpath = work[1]
opt = work[2] opt = work[2]
if opt.verbose: output = []
print "Optimizing " + afile + " for " + opt.profile
else:
print ".",
img = image.ComicPage(os.path.join(dirpath, afile), opt.profileData) img = image.ComicPage(os.path.join(dirpath, afile), opt.profileData)
if opt.quality == 2: if opt.quality == 2:
wipe = False wipe = False
else: else:
wipe = True wipe = True
if opt.nosplitrotate: if opt.nosplitrotate:
split = None splitter = None
else: else:
split = img.splitPage(dirpath, opt.righttoleft, opt.rotate) splitter = img.splitPage(dirpath, opt.righttoleft, opt.rotate)
if split is not None: if splitter is not None:
if opt.verbose: img0 = image.ComicPage(splitter[0], opt.profileData)
print "Splitted " + afile
img0 = image.ComicPage(split[0], opt.profileData)
applyImgOptimization(img0, opt) applyImgOptimization(img0, opt)
img0.saveToDir(dirpath, opt.forcepng, opt.forcecolor, wipe) output.append(img0.saveToDir(dirpath, opt.forcepng, opt.forcecolor))
img1 = image.ComicPage(split[1], opt.profileData) img1 = image.ComicPage(splitter[1], opt.profileData)
applyImgOptimization(img1, opt) applyImgOptimization(img1, opt)
img1.saveToDir(dirpath, opt.forcepng, opt.forcecolor, wipe) output.append(img1.saveToDir(dirpath, opt.forcepng, opt.forcecolor))
if wipe:
output.append(img0.origFileName)
output.append(img1.origFileName)
if opt.quality == 2: if opt.quality == 2:
img0b = image.ComicPage(split[0], opt.profileData, img0.fill) img0b = image.ComicPage(splitter[0], opt.profileData, img0.fill)
applyImgOptimization(img0b, opt, img0) applyImgOptimization(img0b, opt, img0)
img0b.saveToDir(dirpath, opt.forcepng, opt.forcecolor, True) output.append(img0b.saveToDir(dirpath, opt.forcepng, opt.forcecolor))
img1b = image.ComicPage(split[1], opt.profileData, img1.fill) img1b = image.ComicPage(splitter[1], opt.profileData, img1.fill)
applyImgOptimization(img1b, opt, img1) applyImgOptimization(img1b, opt, img1)
img1b.saveToDir(dirpath, opt.forcepng, opt.forcecolor, True) output.append(img1b.saveToDir(dirpath, opt.forcepng, opt.forcecolor))
output.append(img0.origFileName)
output.append(img1.origFileName)
output.append(img.origFileName)
else: else:
applyImgOptimization(img, opt) applyImgOptimization(img, opt)
img.saveToDir(dirpath, opt.forcepng, opt.forcecolor, wipe) output.append(img.saveToDir(dirpath, opt.forcepng, opt.forcecolor))
if wipe:
output.append(img.origFileName)
if opt.quality == 2: if opt.quality == 2:
img2 = image.ComicPage(os.path.join(dirpath, afile), opt.profileData, img.fill) img2 = image.ComicPage(os.path.join(dirpath, afile), opt.profileData, img.fill)
if img.rotated: if img.rotated:
img2.image = img2.image.rotate(90) img2.image = img2.image.rotate(90)
img2.rotated = True img2.rotated = True
applyImgOptimization(img2, opt, img) applyImgOptimization(img2, opt, img)
img2.saveToDir(dirpath, opt.forcepng, opt.forcecolor, True) output.append(img2.saveToDir(dirpath, opt.forcepng, opt.forcecolor))
except StandardError: output.append(img.origFileName)
return output
except Exception:
return str(sys.exc_info()[1]) return str(sys.exc_info()[1])
def genEpubStruct(path): def genEpubStruct(path, chapterNames):
filelist = [] filelist = []
chapterlist = [] chapterlist = []
cover = None cover = None
_, deviceres, _, _, panelviewsize = options.profileData _, deviceres, _, _, panelviewsize = options.profileData
os.mkdir(os.path.join(path, 'OEBPS', 'Text')) os.mkdir(os.path.join(path, 'OEBPS', 'Text'))
f = open(os.path.join(path, 'OEBPS', 'Text', 'style.css'), 'w') f = open(os.path.join(path, 'OEBPS', 'Text', 'style.css'), 'w', encoding='UTF-8')
# DON'T COMPRESS CSS. KINDLE WILL FAIL TO PARSE IT. # DON'T COMPRESS CSS. KINDLE WILL FAIL TO PARSE IT.
# Generic Panel View support + Margins fix for Non-Kindle devices. # Generic Panel View support + Margins fix for Non-Kindle devices.
f.writelines(["@page {\n", f.writelines(["@page {\n",
@@ -560,8 +543,8 @@ def genEpubStruct(path):
chapter = False chapter = False
for afile in filenames: for afile in filenames:
filename = getImageFileName(afile) filename = getImageFileName(afile)
if filename is not None and not "_kcchq" in filename[0]: if filename is not None and not '-kcc-hq' in filename[0]:
filelist.append(buildHTML(dirpath, afile)) filelist.append(buildHTML(dirpath, afile, os.path.join(dirpath, afile)))
if not chapter: if not chapter:
chapterlist.append((dirpath.replace('Images', 'Text'), filelist[-1][1])) chapterlist.append((dirpath.replace('Images', 'Text'), filelist[-1][1]))
chapter = True chapter = True
@@ -569,10 +552,10 @@ def genEpubStruct(path):
cover = os.path.join(os.path.join(path, 'OEBPS', 'Images'), cover = os.path.join(os.path.join(path, 'OEBPS', 'Images'),
'cover' + getImageFileName(filelist[-1][1])[1]) 'cover' + getImageFileName(filelist[-1][1])[1])
copyfile(os.path.join(filelist[-1][0], filelist[-1][1]), cover) copyfile(os.path.join(filelist[-1][0], filelist[-1][1]), cover)
buildNCX(path, options.title, chapterlist) buildNCX(path, options.title, chapterlist, chapterNames)
# Ensure we're sorting files alphabetically # Ensure we're sorting files alphabetically
convert = lambda text: int(text) if text.isdigit() else text convert = lambda text: int(text) if text.isdigit() else text
alphanum_key = lambda key: [convert(c) for c in re.split('([0-9]+)', key)] alphanum_key = lambda key: [convert(c) for c in split('([0-9]+)', key)]
filelist.sort(key=lambda name: (alphanum_key(name[0].lower()), alphanum_key(name[1].lower()))) filelist.sort(key=lambda name: (alphanum_key(name[0].lower()), alphanum_key(name[1].lower())))
buildOPF(path, options.title, filelist, cover) buildOPF(path, options.title, filelist, cover)
@@ -607,8 +590,7 @@ def getWorkFolder(afile):
path = cbx.extract(workdir) path = cbx.extract(workdir)
except OSError: except OSError:
rmtree(workdir, True) rmtree(workdir, True)
print 'UnRAR/7za not found or file failed to extract!' raise UserWarning("Failed to extract file.")
sys.exit(21)
else: else:
rmtree(workdir, True) rmtree(workdir, True)
raise TypeError raise TypeError
@@ -634,7 +616,7 @@ def checkComicInfo(path, originalPath):
if os.path.exists(xmlPath): if os.path.exists(xmlPath):
try: try:
xml = parse(xmlPath) xml = parse(xmlPath)
except StandardError: except Exception:
os.remove(xmlPath) os.remove(xmlPath)
return return
options.authors = [] options.authors = []
@@ -647,19 +629,19 @@ def checkComicInfo(path, originalPath):
titleSuffix += ' #' + xml.getElementsByTagName('Number')[0].firstChild.nodeValue titleSuffix += ' #' + xml.getElementsByTagName('Number')[0].firstChild.nodeValue
options.title += titleSuffix options.title += titleSuffix
if len(xml.getElementsByTagName('Writer')) != 0: if len(xml.getElementsByTagName('Writer')) != 0:
authorsTemp = string.split(xml.getElementsByTagName('Writer')[0].firstChild.nodeValue, ', ') authorsTemp = str.split(xml.getElementsByTagName('Writer')[0].firstChild.nodeValue, ', ')
for author in authorsTemp: for author in authorsTemp:
options.authors.append(author) options.authors.append(author)
if len(xml.getElementsByTagName('Penciller')) != 0: if len(xml.getElementsByTagName('Penciller')) != 0:
authorsTemp = string.split(xml.getElementsByTagName('Penciller')[0].firstChild.nodeValue, ', ') authorsTemp = str.split(xml.getElementsByTagName('Penciller')[0].firstChild.nodeValue, ', ')
for author in authorsTemp: for author in authorsTemp:
options.authors.append(author) options.authors.append(author)
if len(xml.getElementsByTagName('Inker')) != 0: if len(xml.getElementsByTagName('Inker')) != 0:
authorsTemp = string.split(xml.getElementsByTagName('Inker')[0].firstChild.nodeValue, ', ') authorsTemp = str.split(xml.getElementsByTagName('Inker')[0].firstChild.nodeValue, ', ')
for author in authorsTemp: for author in authorsTemp:
options.authors.append(author) options.authors.append(author)
if len(xml.getElementsByTagName('Colorist')) != 0: if len(xml.getElementsByTagName('Colorist')) != 0:
authorsTemp = string.split(xml.getElementsByTagName('Colorist')[0].firstChild.nodeValue, ', ') authorsTemp = str.split(xml.getElementsByTagName('Colorist')[0].firstChild.nodeValue, ', ')
for author in authorsTemp: for author in authorsTemp:
options.authors.append(author) options.authors.append(author)
if len(options.authors) > 0: if len(options.authors) > 0:
@@ -671,20 +653,13 @@ def checkComicInfo(path, originalPath):
def slugify(value): def slugify(value):
# Normalizes string, converts to lowercase, removes non-alpha characters and converts spaces to hyphens. value = slugifyExt(value)
if isinstance(value, str): value = sub(r'0*([0-9]{4,})', r'\1', sub(r'([0-9]+)', r'0000\1', value))
#noinspection PyArgumentList
value = unicodedata.normalize('NFKD', unicode(value, 'latin1')).encode('ascii', 'ignore')
elif isinstance(value, unicode):
value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore')
value = re.sub('[^\w\s\.-]', '', value).strip().lower()
value = re.sub('[-\.\s]+', '-', value)
value = re.sub(r'([0-9]+)', r'00000\1', value)
value = re.sub(r'0*([0-9]{6,})', r'\1', value)
return value return value
def sanitizeTree(filetree): def sanitizeTree(filetree):
chapterNames = {}
for root, dirs, files in os.walk(filetree, False): for root, dirs, files in os.walk(filetree, False):
for name in files: for name in files:
if name.startswith('.') or name.lower() == 'thumbs.db': if name.startswith('.') or name.lower() == 'thumbs.db':
@@ -695,23 +670,32 @@ def sanitizeTree(filetree):
while os.path.exists(os.path.join(root, slugified + splitname[1])) and splitname[0].upper()\ while os.path.exists(os.path.join(root, slugified + splitname[1])) and splitname[0].upper()\
!= slugified.upper(): != slugified.upper():
slugified += "A" slugified += "A"
os.rename(os.path.join(root, name), os.path.join(root, slugified + splitname[1])) newKey = os.path.join(root, slugified + splitname[1])
key = os.path.join(root, name)
if key != newKey:
os.replace(key, newKey)
for name in dirs: for name in dirs:
if name.startswith('.'): if name.startswith('.'):
os.remove(os.path.join(root, name)) os.remove(os.path.join(root, name))
else: else:
tmpName = name
slugified = slugify(name) slugified = slugify(name)
while os.path.exists(os.path.join(root, slugified)) and name.upper() != slugified.upper(): while os.path.exists(os.path.join(root, slugified)) and name.upper() != slugified.upper():
slugified += "A" slugified += "A"
os.rename(os.path.join(root, name), os.path.join(root, slugified)) chapterNames[slugified] = tmpName
newKey = os.path.join(root, slugified)
key = os.path.join(root, name)
if key != newKey:
os.replace(key, newKey)
return chapterNames
def sanitizeTreeBeforeConversion(filetree): def sanitizeTreeBeforeConversion(filetree):
for root, dirs, files in os.walk(filetree, False): for root, dirs, files in os.walk(filetree, False):
for name in files: for name in files:
os.chmod(os.path.join(root, name), stat.S_IWRITE | stat.S_IREAD) os.chmod(os.path.join(root, name), S_IWRITE | S_IREAD)
for name in dirs: for name in dirs:
os.chmod(os.path.join(root, name), stat.S_IWRITE | stat.S_IREAD | stat.S_IEXEC) os.chmod(os.path.join(root, name), S_IWRITE | S_IREAD | S_IEXEC)
def getDirectorySize(start_path='.'): def getDirectorySize(start_path='.'):
@@ -730,17 +714,6 @@ def createNewTome():
return tomePath, tomePathRoot return tomePath, tomePathRoot
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 os.walk(some_dir):
yield root, dirs, files
num_sep_this = root.count(os.path.sep)
if num_sep + level <= num_sep_this:
del dirs[:]
def splitDirectory(path, mode): def splitDirectory(path, mode):
output = [] output = []
currentSize = 0 currentSize = 0
@@ -814,13 +787,13 @@ def preSplitDirectory(path):
mode = 0 mode = 0
else: else:
if filesNumber > 0: if filesNumber > 0:
print '\nWARNING: Automatic output splitting failed.' print('\nWARNING: Automatic output splitting failed.')
if GUI: if GUI:
GUI.emit(QtCore.SIGNAL("addMessage"), 'Automatic output splitting failed. <a href=' GUI.addMessage.emit('Automatic output splitting failed. <a href='
'"https://github.com/ciromattia/kcc/wiki' '"https://github.com/ciromattia/kcc/wiki'
'/Automatic-output-splitting">' '/Automatic-output-splitting">'
'More details.</a>', 'warning') 'More details.</a>', 'warning', False)
GUI.emit(QtCore.SIGNAL("addMessage"), '') GUI.addMessage.emit('', '', False)
return [path] return [path]
detectedSubSubdirectories = False detectedSubSubdirectories = False
detectedFilesInSubdirectories = False detectedFilesInSubdirectories = False
@@ -829,13 +802,13 @@ def preSplitDirectory(path):
if len(dirs) != 0: if len(dirs) != 0:
detectedSubSubdirectories = True detectedSubSubdirectories = True
elif len(dirs) == 0 and detectedSubSubdirectories: elif len(dirs) == 0 and detectedSubSubdirectories:
print '\nWARNING: Automatic output splitting failed.' print('\nWARNING: Automatic output splitting failed.')
if GUI: if GUI:
GUI.emit(QtCore.SIGNAL("addMessage"), 'Automatic output splitting failed. <a href=' GUI.addMessage.emit('Automatic output splitting failed. <a href='
'"https://github.com/ciromattia/kcc/wiki' '"https://github.com/ciromattia/kcc/wiki'
'/Automatic-output-splitting">' '/Automatic-output-splitting">'
'More details.</a>', 'warning') 'More details.</a>', 'warning', False)
GUI.emit(QtCore.SIGNAL("addMessage"), '') GUI.addMessage.emit('', '', False)
return [path] return [path]
if len(files) != 0: if len(files) != 0:
detectedFilesInSubdirectories = True detectedFilesInSubdirectories = True
@@ -846,18 +819,18 @@ def preSplitDirectory(path):
# One level of subdirectories # One level of subdirectories
mode = 1 mode = 1
if detectedFilesInSubdirectories and detectedSubSubdirectories: if detectedFilesInSubdirectories and detectedSubSubdirectories:
print '\nWARNING: Automatic output splitting failed.' print('\nWARNING: Automatic output splitting failed.')
if GUI: if GUI:
GUI.emit(QtCore.SIGNAL("addMessage"), 'Automatic output splitting failed. <a href=' GUI.addMessage.emit('Automatic output splitting failed. <a href='
'"https://github.com/ciromattia/kcc/wiki' '"https://github.com/ciromattia/kcc/wiki'
'/Automatic-output-splitting">' '/Automatic-output-splitting">'
'More details.</a>', 'warning') 'More details.</a>', 'warning', False)
GUI.emit(QtCore.SIGNAL("addMessage"), '') GUI.addMessage.emit('', '', False)
return [path] return [path]
# Split directories # Split directories
split = splitDirectory(os.path.join(path, 'OEBPS', 'Images'), mode) splitter = splitDirectory(os.path.join(path, 'OEBPS', 'Images'), mode)
path = [path] path = [path]
for tome in split: for tome in splitter:
path.append(tome) path.append(tome)
return path return path
else: else:
@@ -879,16 +852,16 @@ def detectCorruption(tmpPath, orgPath):
img.verify() img.verify()
img = Image.open(path) img = Image.open(path)
img.load() img.load()
except: except Exception:
rmtree(os.path.join(tmpPath, '..', '..'), True) rmtree(os.path.join(tmpPath, '..', '..'), True)
raise RuntimeError('Image file %s is corrupted.' % pathOrg) raise RuntimeError('Image file %s is corrupted.' % pathOrg)
def makeZIP(zipFilename, baseDir, isEPUB=False): def makeZIP(zipFilename, baseDir, isEPUB=False):
zipFilename = os.path.abspath(zipFilename) + '.zip' zipFilename = os.path.abspath(zipFilename) + '.zip'
zipOutput = zipfile.ZipFile(zipFilename, 'w', zipfile.ZIP_DEFLATED) zipOutput = ZipFile(zipFilename, 'w', ZIP_DEFLATED)
if isEPUB: if isEPUB:
zipOutput.writestr('mimetype', 'application/epub+zip', zipfile.ZIP_STORED) zipOutput.writestr('mimetype', 'application/epub+zip', ZIP_STORED)
for dirpath, dirnames, filenames in os.walk(baseDir): for dirpath, dirnames, filenames in os.walk(baseDir):
for name in filenames: for name in filenames:
path = os.path.normpath(os.path.join(dirpath, name)) path = os.path.normpath(os.path.join(dirpath, name))
@@ -900,18 +873,17 @@ def makeZIP(zipFilename, baseDir, isEPUB=False):
def Copyright(): def Copyright():
print ('comic2ebook v%(__version__)s. ' print(('comic2ebook v%(__version__)s. Written by Ciro Mattia Gonano and Pawel Jastrzebski.' % globals()))
'Written 2013 by Ciro Mattia Gonano and Pawel Jastrzebski.' % globals())
def Usage(): def Usage():
print "Generates EPUB/CBZ comic ebook from a bunch of images." print("Generates EPUB/CBZ comic ebook from a bunch of images.")
parser.print_help() parser.print_help()
def main(argv=None, qtGUI=None): def main(argv=None, qtGUI=None):
global parser, options, GUI global parser, options, GUI
parser = OptionParser(usage="Usage: %prog [options] comic_file|comic_folder", add_help_option=False) parser = OptionParser(usage="Usage: kcc-c2e [options] comic_file|comic_folder", add_help_option=False)
mainOptions = OptionGroup(parser, "MAIN") mainOptions = OptionGroup(parser, "MAIN")
processingOptions = OptionGroup(parser, "PROCESSING") processingOptions = OptionGroup(parser, "PROCESSING")
outputOptions = OptionGroup(parser, "OUTPUT SETTINGS") outputOptions = OptionGroup(parser, "OUTPUT SETTINGS")
@@ -960,8 +932,6 @@ def main(argv=None, qtGUI=None):
help="Replace screen width provided by device profile") help="Replace screen width provided by device profile")
customProfileOptions.add_option("--customheight", type="int", dest="customheight", default=0, customProfileOptions.add_option("--customheight", type="int", dest="customheight", default=0,
help="Replace screen height provided by device profile") help="Replace screen height provided by device profile")
otherOptions.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False,
help="Verbose output")
otherOptions.add_option("-h", "--help", action="help", otherOptions.add_option("-h", "--help", action="help",
help="Show this help message and exit") help="Show this help message and exit")
parser.add_option_group(mainOptions) parser.add_option_group(mainOptions)
@@ -973,28 +943,29 @@ def main(argv=None, qtGUI=None):
checkOptions() checkOptions()
if qtGUI: if qtGUI:
GUI = qtGUI GUI = qtGUI
GUI.emit(QtCore.SIGNAL("progressBarTick"), 1) GUI.progressBarTick.emit('1')
else: else:
GUI = None GUI = None
if len(args) != 1: if len(args) != 1:
parser.print_help() parser.print_help()
return return
path = getWorkFolder(args[0]) path = getWorkFolder(args[0])
detectCorruption(path + "/OEBPS/Images/", args[0]) print("\nChecking images...")
checkComicInfo(path + "/OEBPS/Images/", args[0]) detectCorruption(os.path.join(path, "OEBPS", "Images"), args[0])
checkComicInfo(os.path.join(path, "OEBPS", "Images"), args[0])
if options.webtoon: if options.webtoon:
if options.customheight > 0: if options.customheight > 0:
comic2panel.main(['-y ' + str(options.customheight), '-i', '-m', path], qtGUI) comic2panel.main(['-y ' + str(options.customheight), '-i', '-m', path], qtGUI)
else: else:
comic2panel.main(['-y ' + str(image.ProfileData.Profiles[options.profile][1][1]), '-i', '-m', path], qtGUI) comic2panel.main(['-y ' + str(image.ProfileData.Profiles[options.profile][1][1]), '-i', '-m', path], qtGUI)
if options.imgproc: if options.imgproc:
print "\nProcessing images..." print("\nProcessing images...")
if GUI: if GUI:
GUI.emit(QtCore.SIGNAL("progressBarTick"), 'status', 'Processing images') GUI.progressBarTick.emit('Processing images')
dirImgProcess(path + "/OEBPS/Images/") dirImgProcess(os.path.join(path, "OEBPS", "Images"))
if GUI: if GUI:
GUI.emit(QtCore.SIGNAL("progressBarTick"), 1) GUI.progressBarTick.emit('1')
sanitizeTree(os.path.join(path, 'OEBPS', 'Images')) chapterNames = sanitizeTree(os.path.join(path, 'OEBPS', 'Images'))
if options.batchsplit: if options.batchsplit:
tomes = preSplitDirectory(path) tomes = preSplitDirectory(path)
else: else:
@@ -1003,11 +974,11 @@ def main(argv=None, qtGUI=None):
tomeNumber = 0 tomeNumber = 0
if GUI: if GUI:
if options.cbzoutput: if options.cbzoutput:
GUI.emit(QtCore.SIGNAL("progressBarTick"), 'status', 'Compressing CBZ files') GUI.progressBarTick.emit('Compressing CBZ files')
else: else:
GUI.emit(QtCore.SIGNAL("progressBarTick"), 'status', 'Compressing EPUB files') GUI.progressBarTick.emit('Compressing EPUB files')
GUI.emit(QtCore.SIGNAL("progressBarTick"), len(tomes) + 1) GUI.progressBarTick.emit(str(len(tomes) + 1))
GUI.emit(QtCore.SIGNAL("progressBarTick")) GUI.progressBarTick.emit('tick')
options.baseTitle = options.title options.baseTitle = options.title
for tome in tomes: for tome in tomes:
if len(tomes) > 1: if len(tomes) > 1:
@@ -1015,15 +986,15 @@ def main(argv=None, qtGUI=None):
options.title = options.baseTitle + ' [' + str(tomeNumber) + '/' + str(len(tomes)) + ']' options.title = options.baseTitle + ' [' + str(tomeNumber) + '/' + str(len(tomes)) + ']'
if options.cbzoutput: if options.cbzoutput:
# if CBZ output wanted, compress all images and return filepath # if CBZ output wanted, compress all images and return filepath
print "\nCreating CBZ file..." print("\nCreating CBZ file...")
if len(tomes) > 1: if len(tomes) > 1:
filepath.append(getOutputFilename(args[0], options.output, '.cbz', ' ' + str(tomeNumber))) filepath.append(getOutputFilename(args[0], options.output, '.cbz', ' ' + str(tomeNumber)))
else: else:
filepath.append(getOutputFilename(args[0], options.output, '.cbz', '')) filepath.append(getOutputFilename(args[0], options.output, '.cbz', ''))
makeZIP(tome + '_comic', tome + '/OEBPS/Images') makeZIP(tome + '_comic', os.path.join(tome, "OEBPS", "Images"))
else: else:
print "\nCreating EPUB structure..." print("\nCreating EPUB structure...")
genEpubStruct(tome) genEpubStruct(tome, chapterNames)
# actually zip the ePub # actually zip the ePub
if len(tomes) > 1: if len(tomes) > 1:
filepath.append(getOutputFilename(args[0], options.output, '.epub', ' ' + str(tomeNumber))) filepath.append(getOutputFilename(args[0], options.output, '.epub', ' ' + str(tomeNumber)))
@@ -1033,7 +1004,7 @@ def main(argv=None, qtGUI=None):
move(tome + '_comic.zip', filepath[-1]) move(tome + '_comic.zip', filepath[-1])
rmtree(tome, True) rmtree(tome, True)
if GUI: if GUI:
GUI.emit(QtCore.SIGNAL("progressBarTick")) GUI.progressBarTick.emit('tick')
return filepath return filepath
@@ -1044,9 +1015,10 @@ def getOutputFilename(srcpath, wantedname, ext, tomeNumber):
if wantedname.endswith(ext): if wantedname.endswith(ext):
filename = os.path.abspath(wantedname) filename = os.path.abspath(wantedname)
elif os.path.isdir(srcpath): elif os.path.isdir(srcpath):
filename = os.path.abspath(options.output) + "/" + os.path.basename(srcpath) + ext filename = os.path.join(os.path.abspath(options.output), os.path.basename(srcpath) + ext)
else: else:
filename = os.path.abspath(options.output) + "/" + os.path.basename(os.path.splitext(srcpath)[0]) + ext filename = os.path.join(os.path.abspath(options.output),
os.path.basename(os.path.splitext(srcpath)[0]) + ext)
elif os.path.isdir(srcpath): elif os.path.isdir(srcpath):
filename = srcpath + tomeNumber + ext filename = srcpath + tomeNumber + ext
else: else:
@@ -1094,7 +1066,7 @@ def checkOptions():
options.quality = 1 options.quality = 1
# Kindle for Android profile require target resolution. # Kindle for Android profile require target resolution.
if options.profile == 'KFA' and (options.customwidth == 0 or options.customheight == 0): if options.profile == 'KFA' and (options.customwidth == 0 or options.customheight == 0):
print "ERROR: Kindle for Android profile require --customwidth and --customheight options!" print("ERROR: Kindle for Android profile require --customwidth and --customheight options!")
sys.exit(1) sys.exit(1)
# CBZ files on Kindle DX/DXG support higher resolution # CBZ files on Kindle DX/DXG support higher resolution
if options.profile == 'KDX' and options.cbzoutput: if options.profile == 'KDX' and options.cbzoutput:
@@ -1111,11 +1083,4 @@ def checkOptions():
(int(X*1.5), int(Y*1.5))) (int(X*1.5), int(Y*1.5)))
image.ProfileData.Profiles["Custom"] = newProfile image.ProfileData.Profiles["Custom"] = newProfile
options.profile = "Custom" options.profile = "Custom"
options.profileData = image.ProfileData.Profiles[options.profile] options.profileData = image.ProfileData.Profiles[options.profile]
if __name__ == "__main__":
freeze_support()
Copyright()
main(sys.argv[1:])
sys.exit(0)

View File

@@ -1,8 +1,7 @@
#!/usr/bin/env python2
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
# Copyright (c) 2012-2013 Ciro Mattia Gonano <ciromattia@gmail.com> # Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
# Copyright (c) 2013 Pawel Jastrzebski <pawelj@vulturis.eu> # Copyright (c) 2013-2014 Pawel Jastrzebski <pawelj@vulturis.eu>
# #
# Permission to use, copy, modify, and/or distribute this software for # Permission to use, copy, modify, and/or distribute this software for
# any purpose with or without fee is hereby granted, provided that the # any purpose with or without fee is hereby granted, provided that the
@@ -18,74 +17,31 @@
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE. # PERFORMANCE OF THIS SOFTWARE.
# #
__version__ = '3.7.2'
__version__ = '4.0.2'
__license__ = 'ISC' __license__ = 'ISC'
__copyright__ = '2012-2013, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>' __copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
import os import os
import sys import sys
from shutil import rmtree, copytree, move from shutil import rmtree, copytree, move
from optparse import OptionParser, OptionGroup from optparse import OptionParser, OptionGroup
from multiprocessing import Pool, freeze_support from multiprocessing import Pool
from PIL import Image, ImageStat
from .shared import getImageFileName, walkLevel
try: try:
# noinspection PyUnresolvedReferences from PyQt5 import QtCore
from PIL import Image, ImageStat
if tuple(map(int, ('2.3.0'.split(".")))) > tuple(map(int, (Image.PILLOW_VERSION.split(".")))):
print "ERROR: Pillow 2.3.0 or newer is required!"
if sys.platform.startswith('linux'):
import Tkinter
import tkMessageBox
importRoot = Tkinter.Tk()
importRoot.withdraw()
tkMessageBox.showerror("KCC - Error", "Pillow 2.3.0 or newer is required!")
exit(1)
except ImportError:
print "ERROR: Pillow is not installed!"
if sys.platform.startswith('linux'):
import Tkinter
import tkMessageBox
importRoot = Tkinter.Tk()
importRoot.withdraw()
tkMessageBox.showerror("KCC - Error", "Pillow 2.3.0 or newer is required!")
exit(1)
try:
from PyQt4 import QtCore
except ImportError: except ImportError:
QtCore = None 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 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 os.walk(some_dir):
yield root, dirs, files
num_sep_this = root.count(os.path.sep)
if num_sep + level <= num_sep_this:
del dirs[:]
def mergeDirectory_tick(output): def mergeDirectory_tick(output):
if output: if output:
mergeWorkerOutput.append(output) mergeWorkerOutput.append(output)
mergeWorkerPool.terminate() mergeWorkerPool.terminate()
if GUI: if GUI:
GUI.emit(QtCore.SIGNAL("progressBarTick")) GUI.progressBarTick.emit('tick')
if not GUI.conversionAlive: if not GUI.conversionAlive:
mergeWorkerPool.terminate() mergeWorkerPool.terminate()
@@ -96,36 +52,40 @@ def mergeDirectory(work):
images = [] images = []
imagesClear = [] imagesClear = []
sizes = [] sizes = []
h = 0
for root, dirs, files in walkLevel(directory, 0): for root, dirs, files in walkLevel(directory, 0):
for name in files: for name in files:
if getImageFileName(name) is not None: if getImageFileName(name) is not None:
images.append([Image.open(os.path.join(root, name)), os.path.join(root, name)]) 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: if len(images) > 0:
for i in images:
sizes.append(i[0].size[0])
mw = max(set(sizes), key=sizes.count) mw = max(set(sizes), key=sizes.count)
for i in images: for i in images:
if i[0].size[0] == mw: if i[1] == mw:
i[0] = i[0].convert('RGB') h += i[2]
imagesClear.append(i) imagesClear.append(i[0])
h = sum(i[0].size[1] for i in imagesClear) # Silently drop directories that contain too many images
if h > 262144:
return None
result = Image.new('RGB', (mw, h)) result = Image.new('RGB', (mw, h))
y = 0 y = 0
for i in imagesClear: for i in imagesClear:
result.paste(i[0], (0, y)) img = Image.open(i)
y += i[0].size[1] img = img.convert('RGB')
for i in imagesClear: result.paste(img, (0, y))
os.remove(i[1]) y += img.size[1]
savePath = os.path.split(imagesClear[0][1]) os.remove(i)
savePath = os.path.split(imagesClear[0])
result.save(os.path.join(savePath[0], os.path.splitext(savePath[1])[0] + '.png'), 'PNG') result.save(os.path.join(savePath[0], os.path.splitext(savePath[1])[0] + '.png'), 'PNG')
except StandardError: except Exception:
return str(sys.exc_info()[1]) return str(sys.exc_info()[1])
def sanitizePanelSize(panel, opt): def sanitizePanelSize(panel, opt):
newPanels = [] newPanels = []
if panel[2] > 8 * opt.height: if panel[2] > 8 * opt.height:
diff = (panel[2] / 8) diff = int(panel[2] / 8)
newPanels.append([panel[0], panel[1] - diff*7, diff]) 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*7, panel[1] - diff*6, diff])
newPanels.append([panel[1] - diff*6, panel[1] - diff*5, diff]) newPanels.append([panel[1] - diff*6, panel[1] - diff*5, diff])
@@ -135,14 +95,14 @@ def sanitizePanelSize(panel, opt):
newPanels.append([panel[1] - diff*2, panel[1] - diff, diff]) newPanels.append([panel[1] - diff*2, panel[1] - diff, diff])
newPanels.append([panel[1] - diff, panel[1], diff]) newPanels.append([panel[1] - diff, panel[1], diff])
elif panel[2] > 4 * opt.height: elif panel[2] > 4 * opt.height:
diff = (panel[2] / 4) diff = int(panel[2] / 4)
newPanels.append([panel[0], panel[1] - diff*3, diff]) 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*3, panel[1] - diff*2, diff])
newPanels.append([panel[1] - diff*2, panel[1] - diff, diff]) newPanels.append([panel[1] - diff*2, panel[1] - diff, diff])
newPanels.append([panel[1] - diff, panel[1], diff]) newPanels.append([panel[1] - diff, panel[1], diff])
elif panel[2] > 2 * opt.height: elif panel[2] > 2 * opt.height:
newPanels.append([panel[0], panel[1] - (panel[2] / 2), (panel[2] / 2)]) newPanels.append([panel[0], panel[1] - int(panel[2] / 2), int(panel[2] / 2)])
newPanels.append([panel[1] - (panel[2] / 2), panel[1], (panel[2] / 2)]) newPanels.append([panel[1] - int(panel[2] / 2), panel[1], int(panel[2] / 2)])
else: else:
newPanels = [panel] newPanels = [panel]
return newPanels return newPanels
@@ -153,7 +113,7 @@ def splitImage_tick(output):
splitWorkerOutput.append(output) splitWorkerOutput.append(output)
splitWorkerPool.terminate() splitWorkerPool.terminate()
if GUI: if GUI:
GUI.emit(QtCore.SIGNAL("progressBarTick")) GUI.progressBarTick.emit('tick')
if not GUI.conversionAlive: if not GUI.conversionAlive:
splitWorkerPool.terminate() splitWorkerPool.terminate()
@@ -167,7 +127,6 @@ def splitImage(work):
# Harcoded opttions # Harcoded opttions
threshold = 1.0 threshold = 1.0
delta = 15 delta = 15
print ".",
fileExpanded = os.path.splitext(name) fileExpanded = os.path.splitext(name)
filePath = os.path.join(path, name) filePath = os.path.join(path, name)
image = Image.open(filePath) image = Image.open(filePath)
@@ -244,18 +203,17 @@ def splitImage(work):
str(pageNumber) + '.png'), 'PNG') str(pageNumber) + '.png'), 'PNG')
pageNumber += 1 pageNumber += 1
os.remove(filePath) os.remove(filePath)
except StandardError: except Exception:
return str(sys.exc_info()[1]) return str(sys.exc_info()[1])
def Copyright(): def Copyright():
print ('comic2panel v%(__version__)s. ' print(('comic2panel v%(__version__)s. Written by Ciro Mattia Gonano and Pawel Jastrzebski.' % globals()))
'Written 2013 by Ciro Mattia Gonano and Pawel Jastrzebski.' % globals())
def main(argv=None, qtGUI=None): def main(argv=None, qtGUI=None):
global options, GUI, splitWorkerPool, splitWorkerOutput, mergeWorkerPool, mergeWorkerOutput global options, GUI, splitWorkerPool, splitWorkerOutput, mergeWorkerPool, mergeWorkerOutput
parser = OptionParser(usage="Usage: %prog [options] comic_folder", add_help_option=False) parser = OptionParser(usage="Usage: kcc-c2p [options] comic_folder", add_help_option=False)
mainOptions = OptionGroup(parser, "MANDATORY") mainOptions = OptionGroup(parser, "MANDATORY")
otherOptions = OptionGroup(parser, "OTHER") otherOptions = OptionGroup(parser, "OTHER")
mainOptions.add_option("-y", "--height", type="int", dest="height", default=0, mainOptions.add_option("-y", "--height", type="int", dest="height", default=0,
@@ -281,15 +239,15 @@ def main(argv=None, qtGUI=None):
if options.height > 0: if options.height > 0:
options.sourceDir = args[0] options.sourceDir = args[0]
options.targetDir = args[0] + "-Splitted" options.targetDir = args[0] + "-Splitted"
print "\nSplitting images..."
if os.path.isdir(options.sourceDir): if os.path.isdir(options.sourceDir):
rmtree(options.targetDir, True) rmtree(options.targetDir, True)
copytree(options.sourceDir, options.targetDir) copytree(options.sourceDir, options.targetDir)
work = [] work = []
pagenumber = 0 pagenumber = 1
splitWorkerOutput = [] splitWorkerOutput = []
splitWorkerPool = Pool() splitWorkerPool = Pool()
if options.merge: if options.merge:
print("\nMerging images...")
directoryNumer = 1 directoryNumer = 1
mergeWork = [] mergeWork = []
mergeWorkerOutput = [] mergeWorkerOutput = []
@@ -300,8 +258,8 @@ def main(argv=None, qtGUI=None):
directoryNumer += 1 directoryNumer += 1
mergeWork.append([os.path.join(root, directory)]) mergeWork.append([os.path.join(root, directory)])
if GUI: if GUI:
GUI.emit(QtCore.SIGNAL("progressBarTick"), 'status', 'Combining images') GUI.progressBarTick.emit('Combining images')
GUI.emit(QtCore.SIGNAL("progressBarTick"), directoryNumer) GUI.progressBarTick.emit(str(directoryNumer))
for i in mergeWork: for i in mergeWork:
mergeWorkerPool.apply_async(func=mergeDirectory, args=(i, ), callback=mergeDirectory_tick) mergeWorkerPool.apply_async(func=mergeDirectory, args=(i, ), callback=mergeDirectory_tick)
mergeWorkerPool.close() mergeWorkerPool.close()
@@ -312,6 +270,7 @@ def main(argv=None, qtGUI=None):
if len(mergeWorkerOutput) > 0: if len(mergeWorkerOutput) > 0:
rmtree(options.targetDir, True) rmtree(options.targetDir, True)
raise RuntimeError("One of workers crashed. Cause: " + mergeWorkerOutput[0]) raise RuntimeError("One of workers crashed. Cause: " + mergeWorkerOutput[0])
print("\nSplitting images...")
for root, dirs, files in os.walk(options.targetDir, False): for root, dirs, files in os.walk(options.targetDir, False):
for name in files: for name in files:
if getImageFileName(name) is not None: if getImageFileName(name) is not None:
@@ -320,9 +279,9 @@ def main(argv=None, qtGUI=None):
else: else:
os.remove(os.path.join(root, name)) os.remove(os.path.join(root, name))
if GUI: if GUI:
GUI.emit(QtCore.SIGNAL("progressBarTick"), 'status', 'Splitting images') GUI.progressBarTick.emit('Splitting images')
GUI.emit(QtCore.SIGNAL("progressBarTick"), pagenumber) GUI.progressBarTick.emit(str(pagenumber))
GUI.emit(QtCore.SIGNAL("progressBarTick")) GUI.progressBarTick.emit('tick')
if len(work) > 0: if len(work) > 0:
for i in work: for i in work:
splitWorkerPool.apply_async(func=splitImage, args=(i, ), callback=splitImage_tick) splitWorkerPool.apply_async(func=splitImage, args=(i, ), callback=splitImage_tick)
@@ -343,11 +302,4 @@ def main(argv=None, qtGUI=None):
else: else:
raise UserWarning("Provided path is not a directory.") raise UserWarning("Provided path is not a directory.")
else: else:
raise UserWarning("Target height is not set.") raise UserWarning("Target height is not set.")
if __name__ == "__main__":
freeze_support()
Copyright()
main(sys.argv[1:])
sys.exit(0)

View File

@@ -1,7 +1,7 @@
# Copyright (C) 2010 Alex Yatskov # Copyright (C) 2010 Alex Yatskov
# Copyright (C) 2011 Stanislav (proDOOMman) Kosolapov <prodoomman@gmail.com> # Copyright (C) 2011 Stanislav (proDOOMman) Kosolapov <prodoomman@gmail.com>
# Copyright (C) 2012-2013 Ciro Mattia Gonano <ciromattia@gmail.com> # Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
# Copyright (C) 2013 Pawel Jastrzebski <pawelj@vulturis.eu> # Copyright (c) 2013-2014 Pawel Jastrzebski <pawelj@vulturis.eu>
# #
# This program is free software: you can redistribute it and/or modify # 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 # it under the terms of the GNU General Public License as published by
@@ -17,32 +17,13 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
__license__ = 'ISC' __license__ = 'ISC'
__copyright__ = '2012-2013, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>' __copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
import os import os
from sys import platform from functools import reduce
try: from PIL import Image, ImageOps, ImageStat, ImageChops
# noinspection PyUnresolvedReferences from .shared import md5Checksum
from PIL import Image, ImageOps, ImageStat, ImageChops
if tuple(map(int, ('2.3.0'.split(".")))) > tuple(map(int, (Image.PILLOW_VERSION.split(".")))):
print "ERROR: Pillow 2.3.0 or newer is required!"
if platform.startswith('linux'):
import Tkinter
import tkMessageBox
importRoot = Tkinter.Tk()
importRoot.withdraw()
tkMessageBox.showerror("KCC - Error", "Pillow 2.3.0 or newer is required!")
exit(1)
except ImportError:
print "ERROR: Pillow is not installed!"
if platform.startswith('linux'):
import Tkinter
import tkMessageBox
importRoot = Tkinter.Tk()
importRoot.withdraw()
tkMessageBox.showerror("KCC - Error", "Pillow 2.3.0 or newer is required!")
exit(1)
class ProfileData: class ProfileData:
@@ -126,52 +107,57 @@ class ComicPage:
self.filename = os.path.basename(self.origFileName) self.filename = os.path.basename(self.origFileName)
self.image = Image.open(source) self.image = Image.open(source)
self.image = self.image.convert('RGB') self.image = self.image.convert('RGB')
self.color = self.isImageColor()
self.rotated = None self.rotated = None
self.border = None self.border = None
self.noHPV = None self.noHPV = None
self.noVPV = None self.noVPV = None
self.noPV = None self.noPV = None
self.purge = False self.purge = False
self.hq = False
if fill: if fill:
self.fill = fill self.fill = fill
else: else:
self.fill = None self.fill = None
def saveToDir(self, targetdir, forcepng, color, wipe): def saveToDir(self, targetdir, forcepng, color):
try: try:
suffix = ""
if not color and not forcepng:
self.image = self.image.convert('L')
if self.rotated:
suffix += "_kccrot"
if wipe:
os.remove(os.path.join(targetdir, self.filename))
else:
suffix += "_kcchq"
if self.noPV:
suffix += "_kccnpv"
else:
if self.noHPV:
suffix += "_kccnh"
if self.noVPV:
suffix += "_kccnv"
if self.border:
suffix += "_kccxl" + str(self.border[0]) + "_kccyu" + str(self.border[1]) + "_kccxr" +\
str(self.border[2]) + "_kccyd" + str(self.border[3])
if not self.purge: if not self.purge:
if forcepng: flags = []
self.image.save(os.path.join(targetdir, os.path.splitext(self.filename)[0] + suffix + ".png"), filename = os.path.join(targetdir, os.path.splitext(self.filename)[0]) + '-KCC'
"PNG", optimize=1) if not color and not forcepng:
self.image = self.image.convert('L')
if self.rotated:
flags.append('Rotated')
if self.hq:
flags.append('HighQuality')
filename += '-HQ'
if self.noPV:
flags.append('NoPanelView')
else: else:
self.image.save(os.path.join(targetdir, os.path.splitext(self.filename)[0] + suffix + ".jpg"), if self.noHPV:
"JPEG", optimize=1) 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 forcepng:
filename += ".png"
self.image.save(filename, "PNG", optimize=1)
else:
filename += ".jpg"
self.image.save(filename, "JPEG", optimize=1)
return [md5Checksum(filename), flags]
else:
return None
except IOError as e: except IOError as e:
raise RuntimeError('Cannot write image in directory %s: %s' % (targetdir, e)) raise RuntimeError('Cannot write image in directory %s: %s' % (targetdir, e))
def optimizeImage(self, gamma): def optimizeImage(self, gamma):
if gamma < 0.1: if gamma < 0.1:
gamma = self.gamma gamma = self.gamma
if self.gamma != 1.0 and self.isImageColor(self.image): if self.gamma != 1.0 and self.color:
gamma = 1.0 gamma = 1.0
if gamma == 1.0: if gamma == 1.0:
self.image = ImageOps.autocontrast(self.image) self.image = ImageOps.autocontrast(self.image)
@@ -179,7 +165,7 @@ class ComicPage:
self.image = ImageOps.autocontrast(Image.eval(self.image, lambda a: 255 * (a / 255.) ** gamma)) self.image = ImageOps.autocontrast(Image.eval(self.image, lambda a: 255 * (a / 255.) ** gamma))
def quantizeImage(self): def quantizeImage(self):
colors = len(self.palette) / 3 colors = len(self.palette) // 3
if colors < 256: if colors < 256:
self.palette += self.palette[:3] * (256 - colors) self.palette += self.palette[:3] * (256 - colors)
palImg = Image.new('P', (1, 1)) palImg = Image.new('P', (1, 1))
@@ -196,7 +182,7 @@ class ComicPage:
return int(round(float(x)/float(img.image.size[1]), 4) * 10000 * 1.5) return int(round(float(x)/float(img.image.size[1]), 4) * 10000 * 1.5)
def calculateBorder(self, sourceImage, isHQ=False): def calculateBorder(self, sourceImage, isHQ=False):
if isHQ and sourceImage.purge: if (isHQ and sourceImage.purge) or self.noPV:
self.border = [0, 0, 0, 0] self.border = [0, 0, 0, 0]
self.noPV = True self.noPV = True
return return
@@ -233,11 +219,21 @@ class ComicPage:
# Set target size # Set target size
if qualityMode == 0: if qualityMode == 0:
size = (self.size[0], self.size[1]) size = (self.size[0], self.size[1])
else: elif qualityMode == 1 and not stretch and not 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 qualityMode == 1:
# Forcing upscale to make sure that margins will be not too big
if not stretch:
upscale = True
size = (self.panelviewsize[0], self.panelviewsize[1])
elif qualityMode == 2 and not stretch and not upscale and self.image.size[0] <=\
self.size[0] and self.image.size[1] <= self.size[1]:
self.purge = True
return self.image
else:
self.hq = True
size = (self.panelviewsize[0], self.panelviewsize[1]) size = (self.panelviewsize[0], self.panelviewsize[1])
# If image is small and HQ mode is on we have to force upscaling. Otherwise non-zoomed image will be distorted
if self.image.size[0] <= size[0] and self.image.size[1] <= size[1] and qualityMode == 1 and not stretch:
upscale = True
# If stretching is on - Resize without other considerations # If stretching is on - Resize without other considerations
if stretch: if stretch:
if self.image.size[0] <= size[0] and self.image.size[1] <= size[1]: if self.image.size[0] <= size[0] and self.image.size[1] <= size[1]:
@@ -248,11 +244,11 @@ class ComicPage:
return self.image return self.image
# If image is smaller than target resolution and upscale is off - Just expand it by adding margins # 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 upscale: if self.image.size[0] <= size[0] and self.image.size[1] <= size[1] and not upscale:
borderw = (size[0] - self.image.size[0]) / 2 borderw = int((size[0] - self.image.size[0]) / 2)
borderh = (size[1] - self.image.size[1]) / 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 - So we drop HQ image # PV is disabled when source image is smaller than device screen and upscale is off
if qualityMode == 2 and self.image.size[0] <= self.size[0] and self.image.size[1] <= self.size[1]: if self.image.size[0] <= self.size[0] and self.image.size[1] <= self.size[1]:
self.purge = True self.noPV = True
self.image = ImageOps.expand(self.image, border=(borderw, borderh), fill=fill) 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 # 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]: if self.image.size[0] != size[0] or self.image.size[1] != size[1]:
@@ -262,10 +258,10 @@ class ComicPage:
ratioDev = float(size[0]) / float(size[1]) ratioDev = float(size[0]) / float(size[1])
if (float(self.image.size[0]) / float(self.image.size[1])) < ratioDev: if (float(self.image.size[0]) / float(self.image.size[1])) < ratioDev:
diff = int(self.image.size[1] * ratioDev) - self.image.size[0] 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: elif (float(self.image.size[0]) / float(self.image.size[1])) > ratioDev:
diff = int(self.image.size[0] / ratioDev) - self.image.size[1] 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]: if self.image.size[0] <= size[0] and self.image.size[1] <= size[1]:
method = Image.BICUBIC method = Image.BICUBIC
else: else:
@@ -286,15 +282,15 @@ class ComicPage:
self.rotated = False self.rotated = False
if width > height: if width > height:
# Source is landscape, so split by the width # Source is landscape, so split by the width
leftbox = (0, 0, width / 2, height) leftbox = (0, 0, int(width / 2), height)
rightbox = (width / 2, 0, width, height) rightbox = (int(width / 2), 0, width, height)
else: else:
# Source is portrait and target is landscape, so split by the height # Source is portrait and target is landscape, so split by the height
leftbox = (0, 0, width, height / 2) leftbox = (0, 0, width, int(height / 2))
rightbox = (0, height / 2, width, height) rightbox = (0, int(height / 2), width, height)
filename = os.path.splitext(self.filename) filename = os.path.splitext(self.filename)
fileone = targetdir + '/' + filename[0] + '_kcca' + filename[1] fileone = targetdir + '/' + filename[0] + '-A' + filename[1]
filetwo = targetdir + '/' + filename[0] + '_kccb' + filename[1] filetwo = targetdir + '/' + filename[0] + '-B' + filename[1]
try: try:
if righttoleft: if righttoleft:
pageone = self.image.crop(rightbox) pageone = self.image.crop(rightbox)
@@ -304,7 +300,6 @@ class ComicPage:
pagetwo = self.image.crop(rightbox) pagetwo = self.image.crop(rightbox)
pageone.save(fileone) pageone.save(fileone)
pagetwo.save(filetwo) pagetwo.save(filetwo)
os.remove(self.origFileName)
except IOError as e: except IOError as e:
raise RuntimeError('Cannot write image in directory %s: %s' % (targetdir, e)) raise RuntimeError('Cannot write image in directory %s: %s' % (targetdir, e))
return fileone, filetwo return fileone, filetwo
@@ -330,7 +325,7 @@ class ComicPage:
oldStat = ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg))).var[0] oldStat = ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg))).var[0]
diff += delta diff += delta
while ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg))).var[0] - oldStat > 0\ 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] oldStat = ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg))).var[0]
diff += delta diff += delta
diff -= delta diff -= delta
@@ -339,7 +334,7 @@ class ComicPage:
oldStat = ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, oldStat = ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg,
heightImg - pageNumberCut2))).var[0] heightImg - pageNumberCut2))).var[0]
while 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
diff -= delta diff -= delta
pageNumberCut3 = diff pageNumberCut3 = diff
@@ -428,25 +423,29 @@ class ComicPage:
# Search for horizontal solid lines # Search for horizontal solid lines
startY = 0 startY = 0
while startY < self.image.size[1]: while startY < self.image.size[1]:
checkSolid = self.getImageHistogram(self.image.crop((0, startY, self.image.size[0], startY+1))) if startY + 5 > self.image.size[1]:
startY = self.image.size[1] - 5
checkSolid = self.getImageHistogram(self.image.crop((0, startY, self.image.size[0], startY+5)))
if checkSolid: if checkSolid:
fill += checkSolid fill += checkSolid
startY += 1 startY += 5
else: else:
# Search for vertical solid lines # Search for vertical solid lines
startX = 0 startX = 0
while startX < self.image.size[0]: while startX < self.image.size[0]:
checkSolid = self.getImageHistogram(self.image.crop((startX, 0, startX+1, self.image.size[1]))) if startX + 5 > self.image.size[0]:
startX = self.image.size[0] - 5
checkSolid = self.getImageHistogram(self.image.crop((startX, 0, startX+5, self.image.size[1])))
if checkSolid: if checkSolid:
fill += checkSolid fill += checkSolid
startX += 1 startX += 5
if fill > 0: if fill > 0:
self.fill = 'black' self.fill = 'black'
else: else:
self.fill = 'white' self.fill = 'white'
def isImageColor(self, image): def isImageColor(self):
v = ImageStat.Stat(image).var v = ImageStat.Stat(self.image).var
isMonochromatic = reduce(lambda x, y: x and y < 0.005, v, True) isMonochromatic = reduce(lambda x, y: x and y < 0.005, v, True)
if isMonochromatic: if isMonochromatic:
# Monochromatic # Monochromatic

View File

@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
#
# Based on initial version of KindleUnpack. Copyright (C) 2009 Charles M. Hannum <root@ihack.net> # 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 # Improvements Copyright (C) 2009-2012 P. Durrant, K. Hendricks, S. Siebert, fandrieu, DiapDealer, nickredding
# Changes for KCC Copyright (C) 2013 Pawel Jastrzebski <pawelj@vulturis.eu> # Changes for KCC Copyright (C) 2013-2014 Pawel Jastrzebski <pawelj@vulturis.eu>
# #
# This program is free software: you can redistribute it and/or modify # 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 # it under the terms of the GNU General Public License as published by
@@ -98,10 +100,10 @@ def nullsection(datain, secno): # make it zero-length without deleting it
datalst.append(struct.pack('>L', ofs) + struct.pack('>L', flgval)) datalst.append(struct.pack('>L', ofs) + struct.pack('>L', flgval))
lpad = zerosecstart - (first_pdb_record + 8*nsec) lpad = zerosecstart - (first_pdb_record + 8*nsec)
if lpad > 0: if lpad > 0:
datalst.append('\0' * lpad) datalst.append(b'\0' * lpad)
datalst.append(datain[zerosecstart: secstart]) datalst.append(datain[zerosecstart: secstart])
datalst.append(datain[secend:]) datalst.append(datain[secend:])
dataout = "".join(datalst) dataout = b"".join(datalst)
return dataout return dataout
@@ -128,10 +130,10 @@ def deletesectionrange(datain, firstsec, lastsec): # delete a range of sections
datalst.append(struct.pack('>L', ofs) + struct.pack('>L', flgval)) datalst.append(struct.pack('>L', ofs) + struct.pack('>L', flgval))
lpad = newstart - (first_pdb_record + 8*(nsec - (lastsec - firstsec + 1))) lpad = newstart - (first_pdb_record + 8*(nsec - (lastsec - firstsec + 1)))
if lpad > 0: if lpad > 0:
datalst.append('\0' * lpad) datalst.append(b'\0' * lpad)
datalst.append(datain[zerosecstart:firstsecstart]) datalst.append(datain[zerosecstart:firstsecstart])
datalst.append(datain[lastsecend:]) datalst.append(datain[lastsecend:])
dataout = "".join(datalst) dataout = b"".join(datalst)
return dataout return dataout
@@ -158,11 +160,11 @@ def insertsection(datain, secno, secdata): # insert a new section
datalst.append(struct.pack('>L', ofs) + struct.pack('>L', flgval)) datalst.append(struct.pack('>L', ofs) + struct.pack('>L', flgval))
lpad = newstart - (first_pdb_record + 8*(nsec + 1)) lpad = newstart - (first_pdb_record + 8*(nsec + 1))
if lpad > 0: if lpad > 0:
datalst.append('\0' * lpad) datalst.append(b'\0' * lpad)
datalst.append(datain[zerosecstart:secstart]) datalst.append(datain[zerosecstart:secstart])
datalst.append(secdata) datalst.append(secdata)
datalst.append(datain[secstart:]) datalst.append(datain[secstart:])
dataout = "".join(datalst) dataout = b"".join(datalst)
return dataout return dataout
@@ -284,7 +286,7 @@ class mobi_split:
# datain_rec0 = del_exth(datain_rec0,534) # 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 # 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 # set the EXTH 129 KF8 Masthead / Cover Image string to the null string
datain_rec0 = write_exth(datain_rec0, 129, '') datain_rec0 = write_exth(datain_rec0, 129, b'')
# don't remove the EXTH 131 KF8 Unidentified Count, seems to be present in mobi6 files as well # 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... # Make sure we have an ASIN & cdeType set...
@@ -377,4 +379,4 @@ class mobi_split:
raise raise
def getResult(self): def getResult(self):
return self.result_file return self.result_file

View File

@@ -1,5 +1,5 @@
# Copyright (c) 2012-2013 Ciro Mattia Gonano <ciromattia@gmail.com> # Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
# Copyright (c) 2013 Pawel Jastrzebski <pawelj@vulturis.eu> # Copyright (c) 2013-2014 Pawel Jastrzebski <pawelj@vulturis.eu>
# #
# Based upon the code snippet by Ned Batchelder # Based upon the code snippet by Ned Batchelder
# (http://nedbatchelder.com/blog/200712/extracting_jpgs_from_pdfs.html) # (http://nedbatchelder.com/blog/200712/extracting_jpgs_from_pdfs.html)
@@ -20,7 +20,7 @@
# #
__license__ = 'ISC' __license__ = 'ISC'
__copyright__ = '2012-2013, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>' __copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
import os import os
@@ -39,38 +39,34 @@ class PdfJpgExtract:
return self.path return self.path
def extract(self): def extract(self):
pdf = file(self.origFileName, "rb").read() pdf = open(self.origFileName, "rb").read()
startmark = b"\xff\xd8"
startmark = "\xff\xd8"
startfix = 0 startfix = 0
endmark = "\xff\xd9" endmark = b"\xff\xd9"
endfix = 2 endfix = 2
i = 0 i = 0
njpg = 0 njpg = 0
os.makedirs(self.path) os.makedirs(self.path)
while True: while True:
istream = pdf.find("stream", i) istream = pdf.find(b"stream", i)
if istream < 0: if istream < 0:
break break
istart = pdf.find(startmark, istream, istream + 20) istart = pdf.find(startmark, istream, istream + 20)
if istart < 0: if istart < 0:
i = istream + 20 i = istream + 20
continue continue
iend = pdf.find("endstream", istart) iend = pdf.find(b"endstream", istart)
if iend < 0: if iend < 0:
raise Exception("Didn't find end of stream!") raise Exception("Didn't find end of stream!")
iend = pdf.find(endmark, iend - 20) iend = pdf.find(endmark, iend - 20)
if iend < 0: if iend < 0:
raise Exception("Didn't find end of JPG!") raise Exception("Didn't find end of JPG!")
istart += startfix istart += startfix
iend += endfix iend += endfix
jpg = pdf[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.write(jpg)
jpgfile.close() jpgfile.close()
njpg += 1 njpg += 1
i = iend i = iend
return self.path, njpg return self.path, njpg

View File

@@ -108,6 +108,8 @@ if sys.hexversion < 0x3000000:
# py2.6 has broken bytes() # py2.6 has broken bytes()
def bytes(s, enc): def bytes(s, enc):
return str(s) return str(s)
else:
unicode = str
# see if compat bytearray() is needed # see if compat bytearray() is needed
try: try:
@@ -188,10 +190,6 @@ NEED_COMMENTS = 1
#: whether to convert comments to unicode strings #: whether to convert comments to unicode strings
UNICODE_COMMENTS = 0 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 #: Convert RAR time tuple into datetime() object
USE_DATETIME = 0 USE_DATETIME = 0
@@ -340,9 +338,11 @@ class RarSignalExit(RarExecError):
"""Unrar exited with signal""" """Unrar exited with signal"""
def is_rarfile(fn): def is_rarfile(xfile):
'''Check quickly whether file is rar archive.''' '''Check quickly whether file is rar archive.'''
buf = open(fn, "rb").read(len(RAR_ID)) fd = XFile(xfile)
buf = fd.read(len(RAR_ID))
fd.close()
return buf == RAR_ID return buf == RAR_ID
@@ -453,11 +453,12 @@ class RarFile(object):
'''Parse RAR structure, provide access to files in archive. '''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. #: to get automatic decoding to unicode.
comment = None 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. """Open and parse a RAR archive.
Parameters: Parameters:
@@ -472,6 +473,9 @@ class RarFile(object):
debug callback, gets to see all archive entries. debug callback, gets to see all archive entries.
crc_check crc_check
set to False to disable CRC checks 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.rarfile = rarfile
self.comment = None self.comment = None
@@ -485,6 +489,13 @@ class RarFile(object):
self._crc_check = crc_check self._crc_check = crc_check
self._vol_list = [] 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 self._main = None
if mode != "r": if mode != "r":
@@ -548,8 +559,9 @@ class RarFile(object):
'''Returns file-like object (:class:`RarExtFile`), '''Returns file-like object (:class:`RarExtFile`),
from where the data can be read. from where the data can be read.
The object implements io.RawIOBase interface, so it can The object implements :class:`io.RawIOBase` interface, so it can
be further wrapped with io.BufferedReader and io.TextIOWrapper. be further wrapped with :class:`io.BufferedReader`
and :class:`io.TextIOWrapper`.
On older Python where io module is not available, it implements On older Python where io module is not available, it implements
only .read(), .seek(), .tell() and .close() methods. only .read(), .seek(), .tell() and .close() methods.
@@ -588,16 +600,19 @@ class RarFile(object):
psw = None psw = None
# is temp write usable? # is temp write usable?
if not USE_EXTRACT_HACK or not self._main: use_hack = 1
if not self._main:
use_hack = 0 use_hack = 0
elif self._main.flags & (RAR_MAIN_SOLID | RAR_MAIN_PASSWORD): elif self._main.flags & (RAR_MAIN_SOLID | RAR_MAIN_PASSWORD):
use_hack = 0 use_hack = 0
elif inf.flags & (RAR_FILE_SPLIT_BEFORE | RAR_FILE_SPLIT_AFTER): elif inf.flags & (RAR_FILE_SPLIT_BEFORE | RAR_FILE_SPLIT_AFTER):
use_hack = 0 use_hack = 0
elif is_filelike(self.rarfile):
pass
elif inf.file_size > HACK_SIZE_LIMIT: elif inf.file_size > HACK_SIZE_LIMIT:
use_hack = 0 use_hack = 0
else: elif not USE_EXTRACT_HACK:
use_hack = 1 use_hack = 0
# now extract # now extract
if inf.compress_type == RAR_M0 and (inf.flags & RAR_FILE_PASSWORD) == 0: if inf.compress_type == RAR_M0 and (inf.flags & RAR_FILE_PASSWORD) == 0:
@@ -610,7 +625,7 @@ class RarFile(object):
def read(self, fname, psw = None): def read(self, fname, psw = None):
"""Return uncompressed data for archive entry. """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: Parameters:
@@ -641,7 +656,7 @@ class RarFile(object):
Parameters: Parameters:
member member
filename or RarInfo instance filename or :class:`RarInfo` instance
path path
optional destination path optional destination path
pwd pwd
@@ -661,7 +676,7 @@ class RarFile(object):
path path
optional destination path optional destination path
members members
optional filename or RarInfo instance list to extract optional filename or :class:`RarInfo` instance list to extract
pwd pwd
optional password to use optional password to use
""" """
@@ -687,10 +702,23 @@ class RarFile(object):
output = p.communicate()[0] output = p.communicate()[0]
check_returncode(p, output) check_returncode(p, output)
def strerror(self):
"""Return error string if parsing failed,
or None if no problems.
"""
return self._parse_error
## ##
## private methods ## 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 # store entry
def _process_entry(self, item): def _process_entry(self, item):
if item.type == RAR_BLOCK_FILE: if item.type == RAR_BLOCK_FILE:
@@ -738,7 +766,7 @@ class RarFile(object):
self._fd = None self._fd = None
def _parse_real(self): def _parse_real(self):
fd = open(self.rarfile, "rb") fd = XFile(self.rarfile)
self._fd = fd self._fd = fd
id = fd.read(len(RAR_ID)) id = fd.read(len(RAR_ID))
if id != RAR_ID: if id != RAR_ID:
@@ -757,9 +785,13 @@ class RarFile(object):
if not h: if not h:
if more_vols: if more_vols:
volume += 1 volume += 1
volfile = self._next_volname(volfile)
fd.close() 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 self._fd = fd
more_vols = 0 more_vols = 0
endarc = 0 endarc = 0
@@ -824,8 +856,7 @@ class RarFile(object):
# now read actual header # now read actual header
return self._parse_block_header(fd) return self._parse_block_header(fd)
except struct.error: except struct.error:
if REPORT_BAD_HEADER: self._set_error('Broken header in RAR file')
raise BadRarFile('Broken header in RAR file')
return None return None
# common header # common header
@@ -852,8 +883,7 @@ class RarFile(object):
# unexpected EOF? # unexpected EOF?
if len(h.header_data) != h.header_size: if len(h.header_data) != h.header_size:
if REPORT_BAD_HEADER: self._set_error('Unexpected EOF when reading header')
raise BadRarFile('Unexpected EOF when reading header')
return None return None
# block has data assiciated with it? # block has data assiciated with it?
@@ -896,18 +926,9 @@ class RarFile(object):
if h.header_crc == calc_crc: if h.header_crc == calc_crc:
return h return h
# need to panic? # header parsing failed.
if REPORT_BAD_HEADER: self._set_error('Header CRC error (%02x): exp=%x got=%x (xlen = %d)',
xlen = len(crcdat) h.type, h.header_crc, calc_crc, 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)
# instead panicing, send eof # instead panicing, send eof
return None return None
@@ -1053,6 +1074,8 @@ class RarFile(object):
# given current vol name, construct next one # given current vol name, construct next one
def _next_volname(self, volfile): def _next_volname(self, volfile):
if is_filelike(volfile):
raise IOError("Working on single FD")
if self._main.flags & RAR_MAIN_NEWNUMBERING: if self._main.flags & RAR_MAIN_NEWNUMBERING:
return self._next_newvol(volfile) return self._next_newvol(volfile)
return self._next_oldvol(volfile) return self._next_oldvol(volfile)
@@ -1093,7 +1116,7 @@ class RarFile(object):
BSIZE = 32*1024 BSIZE = 32*1024
size = inf.compress_size + inf.header_size 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) rf.seek(inf.header_offset)
tmpfd, tmpname = mkstemp(suffix='.rar') tmpfd, tmpname = mkstemp(suffix='.rar')
@@ -1125,7 +1148,7 @@ class RarFile(object):
def _read_comment_v3(self, inf, psw=None): def _read_comment_v3(self, inf, psw=None):
# read data # read data
rf = open(inf.volume_file, "rb") rf = XFile(inf.volume_file)
rf.seek(inf.file_offset) rf.seek(inf.file_offset)
data = rf.read(inf.compress_size) data = rf.read(inf.compress_size)
rf.close() rf.close()
@@ -1146,6 +1169,8 @@ class RarFile(object):
# extract using unrar # extract using unrar
def _open_unrar(self, rarfile, inf, psw = None, tmpfile = None): 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) cmd = [UNRAR_TOOL] + list(OPEN_ARGS)
if psw is not None: if psw is not None:
cmd.append("-p" + psw) cmd.append("-p" + psw)
@@ -1553,7 +1578,7 @@ class DirectReader(RarExtFile):
RarExtFile._open(self) RarExtFile._open(self)
self.volfile = self.inf.volume_file 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.fd.seek(self.inf.header_offset, 0)
self.cur = self.rf._parse_header(self.fd) self.cur = self.rf._parse_header(self.fd)
self.cur_avail = self.cur.add_size self.cur_avail = self.cur.add_size
@@ -1705,10 +1730,47 @@ class HeaderDecrypt:
return res 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 ## 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): def rar3_s2k(psw, salt):
"""String-to-key hash for RAR3.""" """String-to-key hash for RAR3."""
@@ -1874,4 +1936,3 @@ def check_returncode(p, out):
msg = "%s [%d]" % (exc.__doc__, p.returncode) msg = "%s [%d]" % (exc.__doc__, p.returncode)
raise exc(msg) raise exc(msg)

60
kcc/shared.py Normal file
View File

@@ -0,0 +1,60 @@
# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
# Copyright (c) 2013-2014 Pawel Jastrzebski <pawelj@vulturis.eu>
#
# 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.
#
__license__ = 'ISC'
__copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
__docformat__ = 'restructuredtext en'
import os
from hashlib import md5
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 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 os.walk(some_dir):
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()

View File

@@ -1,35 +0,0 @@
--- qt-4.8.5/src/gui/kernel/qwidget_mac.mm 2013-06-07 07:16:59.000000000 +0200
+++ qt-4.8.5-fix/src/gui/kernel/qwidget_mac.mm 2013-10-11 23:00:15.000000000 +0200
@@ -4715,15 +4715,13 @@ void QWidgetPrivate::scroll_sys(int dx,
}
// Scroll the whole widget if qscrollRect is not valid:
- QRect validScrollRect = qscrollRect.isValid() ? qscrollRect : q->rect();
- validScrollRect &= clipRect();
+ QRect validScrollRect = qscrollRect.isValid() ? qscrollRect : QRect(0, 0, q->width(), q->height());
// If q is overlapped by other widgets, we cannot just blit pixels since
// this will move overlapping widgets as well. In case we just update:
const bool overlapped = isOverlapped(validScrollRect.translated(data.crect.topLeft()));
const bool accelerateScroll = accelEnv && isOpaque && !overlapped;
const bool isAlien = (q->internalWinId() == 0);
- const QPoint scrollDelta(dx, dy);
// If qscrollRect is valid, we are _not_ supposed to scroll q's children (as documented).
// But we do scroll children (and the whole of q) if qscrollRect is invalid. This case is
@@ -4745,7 +4743,6 @@ void QWidgetPrivate::scroll_sys(int dx,
}else {
update_sys(qscrollRect);
}
- return;
}
#ifdef QT_MAC_USE_COCOA
@@ -4762,6 +4759,7 @@ void QWidgetPrivate::scroll_sys(int dx,
// moved when the parent is scrolled. All directly or indirectly moved
// children will receive a move event before the function call returns.
QWidgetList movedChildren;
+ const QPoint scrollDelta(dx, dy);
if (scrollChildren) {
QObjectList children = q->children();

BIN
other/libEGL32.dll Normal file

Binary file not shown.

BIN
other/libEGL64.dll Normal file

Binary file not shown.

3
other/qt.conf Normal file
View File

@@ -0,0 +1,3 @@
; Qt Configuration file
[Paths]
Plugins = PlugIns

59
setup.py Normal file → Executable file
View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2 #!/usr/bin/env python3
""" """
cx_Freeze build script for KCC. cx_Freeze build script for KCC.
@@ -8,10 +8,13 @@ Usage (Mac OS X):
Usage (Windows): Usage (Windows):
python setup.py build python setup.py build
""" """
from sys import platform from sys import platform, version_info
if version_info[0] != 3:
print('ERROR: This is Python 3 script!')
exit(1)
NAME = "KindleComicConverter" NAME = "KindleComicConverter"
VERSION = "3.7.2" VERSION = "4.0.2"
MAIN = "kcc.py" MAIN = "kcc.py"
if platform == "darwin": if platform == "darwin":
@@ -23,25 +26,23 @@ if platform == "darwin":
py2app=dict( py2app=dict(
argv_emulation=True, argv_emulation=True,
iconfile='icons/comic2ebook.icns', iconfile='icons/comic2ebook.icns',
includes=['PIL', 'sip', 'PyQt4', 'PyQt4.QtCore', 'PyQt4.QtGui', 'PyQt4.QtNetwork'], includes=['PIL', 'sip', 'PyQt5', 'PyQt5.QtCore', 'PyQt5.QtGui', 'PyQt5.QtNetwork', 'PyQt5.QtWidgets',
qt_plugins=[], 'PyQt5.QtPrintSupport'],
excludes=['PyQt4.QtDeclarative', 'PyQt4.QtDesigner', 'PyQt4.QtHelp', 'PyQt4.QtMultimedia', resources=['LICENSE.txt', 'other/qt.conf', 'other/Additional-LICENSE.txt', 'other/unrar', 'other/7za'],
'PyQt4.QtOpenGL', 'PyQt4.QtScript', 'PyQt4.QtScriptTools', 'PyQt4.QtSql', 'PyQt4.QtSvg',
'PyQt4.QtXmlPatterns', 'PyQt4.QtXml', 'PyQt4.QtWebKit', 'PyQt4.QtTest', 'Tkinter'],
resources=['LICENSE.txt', 'other/Additional-LICENSE.txt', 'other/unrar', 'other/7za'],
plist=dict( plist=dict(
CFBundleName=NAME, CFBundleName=NAME,
CFBundleShortVersionString=VERSION, CFBundleShortVersionString=VERSION,
CFBundleGetInfoString=NAME + " " + VERSION + CFBundleGetInfoString=NAME + " " + VERSION +
", written 2012-2013 by Ciro Mattia Gonano and Pawel Jastrzebski", ", written 2012-2014 by Ciro Mattia Gonano and Pawel Jastrzebski",
CFBundleExecutable=NAME, CFBundleExecutable=NAME,
CFBundleIdentifier='com.github.ciromattia.kcc', CFBundleIdentifier='com.github.ciromattia.kcc',
CFBundleSignature='dplt', CFBundleSignature='dplt',
CFBundleDocumentTypes=[ CFBundleDocumentTypes=[
dict( dict(
CFBundleTypeExtensions=['cbz', 'cbr', 'cb7', 'zip', 'rar', '7z', 'pdf'], CFBundleTypeExtensions=['cbz', 'cbr', 'cb7', 'zip', 'rar', '7z', 'pdf'],
CFBundleTypeName='Comics',
CFBundleTypeIconFile='comic2ebook.icns', CFBundleTypeIconFile='comic2ebook.icns',
CFBundleTypeRole='Viewer', CFBundleTypeRole='Editor',
) )
], ],
LSMinimumSystemVersion='10.8.0', LSMinimumSystemVersion='10.8.0',
@@ -54,25 +55,33 @@ if platform == "darwin":
) )
) )
elif platform == "win32": elif platform == "win32":
import platform as arch
from cx_Freeze import setup, Executable from cx_Freeze import setup, Executable
if arch.architecture()[0] == '64bit':
library = 'libEGL64.dll'
else:
library = 'libEGL32.dll'
base = "Win32GUI" base = "Win32GUI"
extra_options = dict( extra_options = dict(
options={"build_exe": {"include_files": ['LICENSE.txt', options={"build_exe": {"optimize": 2,
"include_files": ['LICENSE.txt',
['other/UnRAR.exe', 'UnRAR.exe'], ['other/UnRAR.exe', 'UnRAR.exe'],
['other/7za.exe', '7za.exe'], ['other/7za.exe', '7za.exe'],
['other/Additional-LICENSE.txt', 'Additional-LICENSE.txt'] ['other/Additional-LICENSE.txt', 'Additional-LICENSE.txt'],
], "compressed": True, ['other/' + library, 'libEGL.dll']
"excludes": ['Tkinter']}}, ],
"copy_dependent_files": True,
"create_shared_zip": False,
"append_script_to_exe": True,
"replace_paths": '*=',
"excludes": ['tkinter']}},
executables=[Executable(MAIN, executables=[Executable(MAIN,
base=base, base=base,
targetName="KCC.exe", targetName="KCC.exe",
icon="icons/comic2ebook.ico", icon="icons/comic2ebook.ico",
copyDependentFiles=True, compress=False)])
appendScriptToExe=True,
appendScriptToLibrary=False,
compress=True)])
else: else:
print 'Please use setup.sh to build Linux package.' print('Please use setup.sh to build Linux package.')
exit() exit()
#noinspection PyUnboundLocalVariable #noinspection PyUnboundLocalVariable
@@ -85,11 +94,13 @@ setup(
license="ISC License (ISCL)", license="ISC License (ISCL)",
keywords="kindle comic mobipocket mobi cbz cbr manga", keywords="kindle comic mobipocket mobi cbz cbr manga",
url="http://github.com/ciromattia/kcc", url="http://github.com/ciromattia/kcc",
packages=['kcc'], requires=['Pillow'],
**extra_options **extra_options
) )
if platform == "darwin": if platform == "darwin":
from os import chmod from os import chmod, makedirs
chmod('dist/' + NAME + '.app/Contents/Resources/unrar', 0777) from shutil import copyfile
chmod('dist/' + NAME + '.app/Contents/Resources/7za', 0777) 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)

21
setup.sh Normal file → Executable file
View File

@@ -1,12 +1,25 @@
#!/bin/bash #!/bin/bash
# Linux Python package build script # Linux Python package build script
VERSION="3.7.2" VERSION="4.0.2"
cp kcc.py __main__.py cp kcc.py __main__.py
zip kcc.zip __main__.py kcc/*.py zip kcc.zip __main__.py kcc/*.py
echo "#!/usr/bin/env python2" > kcc-bin echo "#!/usr/bin/env python3" > kcc-bin
cat kcc.zip >> kcc-bin cat kcc.zip >> kcc-bin
chmod +x kcc-bin chmod +x kcc-bin
tar --xform s:^.*/:: --xform s/kcc-bin/kcc/ --xform s/comic2ebook/kcc/ -czf KindleComicConverter_linux_$VERSION.tar.gz kcc-bin LICENSE.txt icons/comic2ebook.png
rm __main__.py kcc.zip 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