Page Setup plugin for config dialog. Also move EPUB specific options from profiles to EPUB plugin.

This commit is contained in:
Kovid Goyal 2009-05-05 01:52:19 -07:00
parent 5cd88d2602
commit 02f808e399
8 changed files with 324 additions and 29 deletions

View File

@ -3,7 +3,6 @@ __license__ = 'GPL 3'
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
__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 <object>
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

View File

@ -6,7 +6,7 @@ __license__ = 'GPL v3'
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
__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,8 +250,6 @@ 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):
@ -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)

View File

@ -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

View File

@ -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)

View File

@ -13,15 +13,41 @@
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="2">
<widget class="QCheckBox" name="opt_dont_split_on_page_breaks">
<property name="text">
<string>Do not &amp;split on page breaks</string>
</property>
</widget>
</item>
<item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Split files &amp;larger than:</string>
</property>
<property name="buddy">
<cstring>opt_flow_size</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="opt_flow_size">
<property name="suffix">
<string> KB</string>
</property>
<property name="minimum">
<number>100</number>
</property>
<property name="maximum">
<number>1000000</number>
</property>
<property name="singleStep">
<number>20</number>
</property>
</widget>
</item>
<item row="2" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>

View File

@ -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 <kovid@kovidgoyal.net>'
__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)

View File

@ -0,0 +1,189 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>572</width>
<height>476</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>&amp;Output profile:</string>
</property>
<property name="buddy">
<cstring>opt_output_profile</cstring>
</property>
</widget>
</item>
<item>
<widget class="QListView" name="opt_output_profile"/>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>4</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Profile description</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="profile_description">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>4</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>&amp;Input profile:</string>
</property>
<property name="buddy">
<cstring>opt_input_profile</cstring>
</property>
</widget>
</item>
<item>
<widget class="QListView" name="opt_input_profile"/>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>4</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Margins</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>&amp;Left:</string>
</property>
<property name="buddy">
<cstring>opt_margin_left</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QDoubleSpinBox" name="opt_margin_left">
<property name="suffix">
<string> pt</string>
</property>
<property name="decimals">
<number>1</number>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>&amp;Top:</string>
</property>
<property name="buddy">
<cstring>opt_margin_top</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="opt_margin_top">
<property name="suffix">
<string> pt</string>
</property>
<property name="decimals">
<number>1</number>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>&amp;Right:</string>
</property>
<property name="buddy">
<cstring>opt_margin_right</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="opt_margin_right">
<property name="suffix">
<string> pt</string>
</property>
<property name="decimals">
<number>1</number>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>&amp;Bottom:</string>
</property>
<property name="buddy">
<cstring>opt_margin_bottom</cstring>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QDoubleSpinBox" name="opt_margin_bottom">
<property name="suffix">
<string> pt</string>
</property>
<property name="decimals">
<number>1</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -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,7 +236,7 @@ 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.show()