diff --git a/src/calibre/customize/profiles.py b/src/calibre/customize/profiles.py index 12debef5cc..4c184ca36d 100644 --- a/src/calibre/customize/profiles.py +++ b/src/calibre/customize/profiles.py @@ -3,7 +3,6 @@ __license__ = 'GPL 3' __copyright__ = '2009, Kovid Goyal ' __docformat__ = 'restructuredtext en' -import re from itertools import izip from calibre.customize import Plugin as _Plugin @@ -141,13 +140,6 @@ class OutputProfile(Plugin): 'if you want to produce a document intended to be read at a ' 'computer or on a range of devices.') - # ADE dies an agonizing, long drawn out death if HTML files have more - # bytes than this. - flow_size = -1 - # ADE runs screaming when it sees these characters - remove_special_chars = re.compile(u'[\u200b\u00ad]') - # ADE falls to the ground in a dead faint when it sees an - remove_object_tags = True # The image size for comics comic_screen_size = (584, 754) @@ -162,7 +154,6 @@ class SonyReaderOutput(OutputProfile): description = _('This profile is intended for the SONY PRS line. ' 'The 500/505/700 etc.') - flow_size = 270000 screen_size = (600, 775) dpi = 168.451 fbase = 12 diff --git a/src/calibre/ebooks/epub/output.py b/src/calibre/ebooks/epub/output.py index aba9bff0d8..efd27ef8f3 100644 --- a/src/calibre/ebooks/epub/output.py +++ b/src/calibre/ebooks/epub/output.py @@ -6,7 +6,7 @@ __license__ = 'GPL v3' __copyright__ = '2009, Kovid Goyal ' __docformat__ = 'restructuredtext en' -import os, shutil +import os, shutil, re from urllib import unquote from calibre.customize.conversion import OutputFormatPlugin @@ -42,6 +42,13 @@ class EPUBOutput(OutputFormatPlugin): ) ), + OptionRecommendation(name='flow_size', recommended_value=260, + help=_('Split all HTML files larger than this size (in KB). ' + 'This is necessary as most EPUB readers cannot handle large ' + 'file sizes. The default of %defaultKB is the size required ' + 'for Adobe Digital Editions.') + ), + ]) @@ -104,7 +111,7 @@ class EPUBOutput(OutputFormatPlugin): from calibre.ebooks.oeb.transforms.split import Split split = Split(not self.opts.dont_split_on_page_breaks, - max_flow_size=self.opts.output_profile.flow_size + max_flow_size=self.opts.flow_size*1024 ) split(self.oeb, self.opts) @@ -243,14 +250,12 @@ class EPUBOutput(OutputFormatPlugin): br.tail = '' br.tail += sibling.tail - - if self.opts.output_profile.remove_object_tags: - for tag in XPath('//h:embed')(root): - tag.getparent().remove(tag) - for tag in XPath('//h:object')(root): - if tag.get('type', '').lower().strip() in ('image/svg+xml',): - continue - tag.getparent().remove(tag) + for tag in XPath('//h:embed')(root): + tag.getparent().remove(tag) + for tag in XPath('//h:object')(root): + if tag.get('type', '').lower().strip() in ('image/svg+xml',): + continue + tag.getparent().remove(tag) for tag in XPath('//h:title|//h:style')(root): if not tag.text: @@ -276,5 +281,12 @@ class EPUBOutput(OutputFormatPlugin): stylesheet.data.add('a[href] { color: blue; ' 'text-decoration: underline; cursor:pointer; }') + special_chars = re.compile(u'[\u200b\u00ad]') + for elem in root.iterdescendants(): + if getattr(elem, 'text', False): + elem.text = special_chars.sub('', elem.text) + if getattr(elem, 'tail', False): + elem.tail = special_chars.sub('', elem.tail) + diff --git a/src/calibre/gui2/convert/__init__.py b/src/calibre/gui2/convert/__init__.py index dddb6b0c00..dd24d05120 100644 --- a/src/calibre/gui2/convert/__init__.py +++ b/src/calibre/gui2/convert/__init__.py @@ -154,8 +154,9 @@ class Widget(QWidget): def get_value(self, g): - if self.get_value_handler(g): - return + ret = self.get_value_handler(g) + if ret != 'this is a dummy return value, xcswx1avcx4x': + return ret if isinstance(g, (QSpinBox, QDoubleSpinBox)): return g.value() elif isinstance(g, (QLineEdit, QTextEdit)): @@ -217,7 +218,7 @@ class Widget(QWidget): pass def get_value_handler(self, g): - return False + return 'this is a dummy return value, xcswx1avcx4x' def post_get_value(self, g): pass diff --git a/src/calibre/gui2/convert/epub_output.py b/src/calibre/gui2/convert/epub_output.py index a8caa23366..74f0913398 100644 --- a/src/calibre/gui2/convert/epub_output.py +++ b/src/calibre/gui2/convert/epub_output.py @@ -16,7 +16,7 @@ class PluginWidget(Widget, Ui_Form): def __init__(self, parent, get_option, get_help, db=None, book_id=None): Widget.__init__(self, parent, 'epub_output', - ['dont_split_on_page_breaks'] + ['dont_split_on_page_breaks', 'flow_size'] ) self.db, self.book_id = db, book_id self.initialize_options(get_option, get_help, db, book_id) diff --git a/src/calibre/gui2/convert/epub_output.ui b/src/calibre/gui2/convert/epub_output.ui index 3009e1e5ab..acd95beb7d 100644 --- a/src/calibre/gui2/convert/epub_output.ui +++ b/src/calibre/gui2/convert/epub_output.ui @@ -13,15 +13,41 @@ Form - - + + Do not &split on page breaks - + + + + Split files &larger than: + + + opt_flow_size + + + + + + + KB + + + 100 + + + 1000000 + + + 20 + + + + Qt::Vertical diff --git a/src/calibre/gui2/convert/page_setup.py b/src/calibre/gui2/convert/page_setup.py new file mode 100644 index 0000000000..0d2ce91dd1 --- /dev/null +++ b/src/calibre/gui2/convert/page_setup.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python +# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai +from __future__ import with_statement + +__license__ = 'GPL v3' +__copyright__ = '2009, Kovid Goyal ' +__docformat__ = 'restructuredtext en' + +from PyQt4.Qt import Qt, QAbstractListModel, QVariant, SIGNAL + +from calibre.gui2.convert.page_setup_ui import Ui_Form +from calibre.gui2.convert import Widget +from calibre.gui2 import NONE +from calibre.customize.ui import input_profiles, output_profiles + +class ProfileModel(QAbstractListModel): + + def __init__(self, profiles): + QAbstractListModel.__init__(self) + self.profiles = list(profiles) + + def rowCount(self, *args): + return len(self.profiles) + + def data(self, index, role): + profile = self.profiles[index.row()] + if role == Qt.DisplayRole: + return QVariant(profile.name) + if role in (Qt.ToolTipRole, Qt.StatusTipRole, Qt.WhatsThisRole): + return QVariant(profile.description) + return NONE + +class PageSetupWidget(Widget, Ui_Form): + + TITLE = _('Page Setup') + + def __init__(self, parent, get_option, get_help, db=None, book_id=None): + Widget.__init__(self, parent, 'lrf_output', + ['margin_top', 'margin_left', 'margin_right', 'margin_bottom', + 'input_profile', 'output_profile'] + ) + + self.db, self.book_id = db, book_id + self.input_model = ProfileModel(input_profiles()) + self.output_model = ProfileModel(output_profiles()) + self.opt_input_profile.setModel(self.input_model) + self.opt_output_profile.setModel(self.output_model) + for x in (self.opt_input_profile, self.opt_output_profile): + x.setMouseTracking(True) + self.connect(x, SIGNAL('entered(QModelIndex)'), self.show_desc) + self.initialize_options(get_option, get_help, db, book_id) + + def show_desc(self, index): + desc = index.model().data(index, Qt.StatusTipRole).toString() + self.profile_description.setText(desc) + + def set_value_handler(self, g, val): + if g in (self.opt_input_profile, self.opt_output_profile): + g.clearSelection() + for idx, p in enumerate(g.model().profiles): + if p.short_name == val: + break + idx = g.model().index(idx) + sm = g.selectionModel() + g.setCurrentIndex(idx) + sm.select(idx, sm.SelectCurrent) + return True + return False + + def get_value_handler(self, g): + if g in (self.opt_input_profile, self.opt_output_profile): + idx = g.currentIndex().row() + return g.model().profiles[idx].short_name + return Widget.get_value_handler(self, g) diff --git a/src/calibre/gui2/convert/page_setup.ui b/src/calibre/gui2/convert/page_setup.ui new file mode 100644 index 0000000000..0aa2a97e70 --- /dev/null +++ b/src/calibre/gui2/convert/page_setup.ui @@ -0,0 +1,189 @@ + + + Form + + + + 0 + 0 + 572 + 476 + + + + Form + + + + + + + + + + &Output profile: + + + opt_output_profile + + + + + + + + + + + + + 4 + 0 + + + + Profile description + + + + + + + 4 + 0 + + + + + + + true + + + + + + + + + + + + + + + + &Input profile: + + + opt_input_profile + + + + + + + + + + + + + 4 + 0 + + + + Margins + + + + + + &Left: + + + opt_margin_left + + + + + + + pt + + + 1 + + + + + + + &Top: + + + opt_margin_top + + + + + + + pt + + + 1 + + + + + + + &Right: + + + opt_margin_right + + + + + + + pt + + + 1 + + + + + + + &Bottom: + + + opt_margin_bottom + + + + + + + pt + + + 1 + + + + + + + + + + + + + diff --git a/src/calibre/gui2/convert/single.py b/src/calibre/gui2/convert/single.py index 0d75df3f1b..295656237b 100644 --- a/src/calibre/gui2/convert/single.py +++ b/src/calibre/gui2/convert/single.py @@ -16,6 +16,7 @@ from calibre.gui2.convert import GuiRecommendations, save_specifics, \ from calibre.gui2.convert.single_ui import Ui_Dialog from calibre.gui2.convert.metadata import MetadataWidget from calibre.gui2.convert.look_and_feel import LookAndFeelWidget +from calibre.gui2.convert.page_setup import PageSetupWidget from calibre.ebooks.conversion.plumber import Plumber, supported_input_formats, \ INPUT_FORMAT_PREFERENCES, OUTPUT_FORMAT_PREFERENCES @@ -132,6 +133,7 @@ class Config(ResizableDialog, Ui_Dialog): self.mw = widget_factory(MetadataWidget) self.setWindowTitle(_('Convert')+ ' ' + unicode(self.mw.title.text())) lf = widget_factory(LookAndFeelWidget) + ps = widget_factory(PageSetupWidget) output_widget = None name = self.plumber.output_plugin.name.lower().replace(' ', '_') @@ -159,7 +161,7 @@ class Config(ResizableDialog, Ui_Dialog): if not c: break self.stack.removeWidget(c) - widgets = [self.mw, lf] + widgets = [self.mw, lf, ps] if input_widget is not None: widgets.append(input_widget) if output_widget is not None: @@ -234,9 +236,9 @@ if __name__ == '__main__': from calibre.library.database2 import LibraryDatabase2 from calibre.gui2 import images_rc, Application images_rc - a=Application([]) + a = Application([]) db = LibraryDatabase2('/home/kovid/documents/library') - d = Config(None, db, 594) + d = Config(None, db, 594) d.show() a.exec_()