mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Sync to pluginize
This commit is contained in:
commit
bce9fce7f6
@ -304,6 +304,9 @@ class ComicInput(InputFormatPlugin):
|
|||||||
('chapter', None, OptionRecommendation.HIGH),
|
('chapter', None, OptionRecommendation.HIGH),
|
||||||
('page_breaks_brefore', None, OptionRecommendation.HIGH),
|
('page_breaks_brefore', None, OptionRecommendation.HIGH),
|
||||||
('use_auto_toc', False, OptionRecommendation.HIGH),
|
('use_auto_toc', False, OptionRecommendation.HIGH),
|
||||||
|
('page_breaks_before', None, OptionRecommendation.HIGH),
|
||||||
|
('disable_font_rescaling', True, OptionRecommendation.HIGH),
|
||||||
|
('linearize_tables', False, OptionRecommendation.HIGH),
|
||||||
])
|
])
|
||||||
|
|
||||||
def get_comics_from_collection(self, stream):
|
def get_comics_from_collection(self, stream):
|
||||||
|
@ -83,8 +83,11 @@ class GuiRecommendations(dict):
|
|||||||
if d:
|
if d:
|
||||||
self.update(d)
|
self.update(d)
|
||||||
|
|
||||||
def merge_recommendations(self, get_option, level, options):
|
def merge_recommendations(self, get_option, level, options,
|
||||||
|
only_existing=False):
|
||||||
for name in options:
|
for name in options:
|
||||||
|
if only_existing and name not in self:
|
||||||
|
continue
|
||||||
opt = get_option(name)
|
opt = get_option(name)
|
||||||
if opt is None: continue
|
if opt is None: continue
|
||||||
if opt.level == OptionRecommendation.HIGH:
|
if opt.level == OptionRecommendation.HIGH:
|
||||||
@ -125,8 +128,10 @@ class Widget(QWidget):
|
|||||||
if db is not None:
|
if db is not None:
|
||||||
specifics = load_specifics(db, book_id)
|
specifics = load_specifics(db, book_id)
|
||||||
specifics.merge_recommendations(get_option, OptionRecommendation.HIGH,
|
specifics.merge_recommendations(get_option, OptionRecommendation.HIGH,
|
||||||
self._options)
|
self._options, only_existing=True)
|
||||||
defaults.update(specifics)
|
defaults.update(specifics)
|
||||||
|
|
||||||
|
|
||||||
self.apply_recommendations(defaults)
|
self.apply_recommendations(defaults)
|
||||||
self.setup_help(get_help)
|
self.setup_help(get_help)
|
||||||
|
|
||||||
@ -154,6 +159,7 @@ class Widget(QWidget):
|
|||||||
|
|
||||||
|
|
||||||
def get_value(self, g):
|
def get_value(self, g):
|
||||||
|
from calibre.gui2.convert.xpath_wizard import XPathEdit
|
||||||
ret = self.get_value_handler(g)
|
ret = self.get_value_handler(g)
|
||||||
if ret != 'this is a dummy return value, xcswx1avcx4x':
|
if ret != 'this is a dummy return value, xcswx1avcx4x':
|
||||||
return ret
|
return ret
|
||||||
@ -169,11 +175,14 @@ class Widget(QWidget):
|
|||||||
return unicode(g.currentText())
|
return unicode(g.currentText())
|
||||||
elif isinstance(g, QCheckBox):
|
elif isinstance(g, QCheckBox):
|
||||||
return bool(g.isChecked())
|
return bool(g.isChecked())
|
||||||
|
elif isinstance(g, XPathEdit):
|
||||||
|
return g.xpath
|
||||||
else:
|
else:
|
||||||
raise Exception('Can\'t get value from %s'%type(g))
|
raise Exception('Can\'t get value from %s'%type(g))
|
||||||
|
|
||||||
|
|
||||||
def set_value(self, g, val):
|
def set_value(self, g, val):
|
||||||
|
from calibre.gui2.convert.xpath_wizard import XPathEdit
|
||||||
if self.set_value_handler(g, val):
|
if self.set_value_handler(g, val):
|
||||||
return
|
return
|
||||||
if isinstance(g, (QSpinBox, QDoubleSpinBox)):
|
if isinstance(g, (QSpinBox, QDoubleSpinBox)):
|
||||||
@ -190,13 +199,18 @@ class Widget(QWidget):
|
|||||||
g.setCurrentIndex(idx)
|
g.setCurrentIndex(idx)
|
||||||
elif isinstance(g, QCheckBox):
|
elif isinstance(g, QCheckBox):
|
||||||
g.setCheckState(Qt.Checked if bool(val) else Qt.Unchecked)
|
g.setCheckState(Qt.Checked if bool(val) else Qt.Unchecked)
|
||||||
|
elif isinstance(g, XPathEdit):
|
||||||
|
g.edit.setText(val if val else '')
|
||||||
else:
|
else:
|
||||||
raise Exception('Can\'t set value %s in %s'%(repr(val), type(g)))
|
raise Exception('Can\'t set value %s in %s'%(repr(val), type(g)))
|
||||||
self.post_set_value(g, val)
|
self.post_set_value(g, val)
|
||||||
|
|
||||||
def set_help(self, msg):
|
def set_help(self, msg):
|
||||||
if msg and getattr(msg, 'strip', lambda:True)():
|
if msg and getattr(msg, 'strip', lambda:True)():
|
||||||
self.emit(SIGNAL('set_help(PyQt_PyObject)'), msg)
|
try:
|
||||||
|
self.emit(SIGNAL('set_help(PyQt_PyObject)'), msg)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
def setup_help(self, help_provider):
|
def setup_help(self, help_provider):
|
||||||
for name in self._options:
|
for name in self._options:
|
||||||
@ -223,6 +237,9 @@ class Widget(QWidget):
|
|||||||
def post_get_value(self, g):
|
def post_get_value(self, g):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def pre_commit_check(self):
|
||||||
|
return True
|
||||||
|
|
||||||
def commit(self, save_defaults=False):
|
def commit(self, save_defaults=False):
|
||||||
return self.commit_options(save_defaults)
|
return self.commit_options(save_defaults)
|
||||||
|
|
||||||
|
@ -14,6 +14,8 @@ from calibre.customize.ui import available_output_formats
|
|||||||
from calibre.gui2 import ResizableDialog
|
from calibre.gui2 import ResizableDialog
|
||||||
from calibre.gui2.convert.look_and_feel import LookAndFeelWidget
|
from calibre.gui2.convert.look_and_feel import LookAndFeelWidget
|
||||||
from calibre.gui2.convert.page_setup import PageSetupWidget
|
from calibre.gui2.convert.page_setup import PageSetupWidget
|
||||||
|
from calibre.gui2.convert.structure_detection import StructureDetectionWidget
|
||||||
|
from calibre.gui2.convert.toc import TOCWidget
|
||||||
from calibre.gui2.convert import GuiRecommendations
|
from calibre.gui2.convert import GuiRecommendations
|
||||||
from calibre.ebooks.conversion.plumber import Plumber, OUTPUT_FORMAT_PREFERENCES
|
from calibre.ebooks.conversion.plumber import Plumber, OUTPUT_FORMAT_PREFERENCES
|
||||||
from calibre.utils.logging import Log
|
from calibre.utils.logging import Log
|
||||||
@ -42,6 +44,7 @@ class BulkConfig(Config):
|
|||||||
|
|
||||||
|
|
||||||
def setup_pipeline(self, *args):
|
def setup_pipeline(self, *args):
|
||||||
|
oidx = self.groups.currentIndex().row()
|
||||||
output_format = self.output_format
|
output_format = self.output_format
|
||||||
|
|
||||||
input_path = 'dummy.epub'
|
input_path = 'dummy.epub'
|
||||||
@ -54,9 +57,11 @@ class BulkConfig(Config):
|
|||||||
return cls(self.stack, self.plumber.get_option_by_name,
|
return cls(self.stack, self.plumber.get_option_by_name,
|
||||||
self.plumber.get_option_help, self.db)
|
self.plumber.get_option_help, self.db)
|
||||||
|
|
||||||
self.setWindowTitle(_('Convert Bulk'))
|
self.setWindowTitle(_('Bulk Convert'))
|
||||||
lf = widget_factory(LookAndFeelWidget)
|
lf = widget_factory(LookAndFeelWidget)
|
||||||
ps = widget_factory(PageSetupWidget)
|
ps = widget_factory(PageSetupWidget)
|
||||||
|
sd = widget_factory(StructureDetectionWidget)
|
||||||
|
toc = widget_factory(TOCWidget)
|
||||||
|
|
||||||
output_widget = None
|
output_widget = None
|
||||||
name = 'calibre.gui2.convert.%s' % self.plumber.output_plugin.name.lower().replace(' ', '_')
|
name = 'calibre.gui2.convert.%s' % self.plumber.output_plugin.name.lower().replace(' ', '_')
|
||||||
@ -75,7 +80,7 @@ class BulkConfig(Config):
|
|||||||
if not c: break
|
if not c: break
|
||||||
self.stack.removeWidget(c)
|
self.stack.removeWidget(c)
|
||||||
|
|
||||||
widgets = [lf, ps]
|
widgets = [lf, ps, sd, toc]
|
||||||
if output_widget is not None:
|
if output_widget is not None:
|
||||||
widgets.append(output_widget)
|
widgets.append(output_widget)
|
||||||
for w in widgets:
|
for w in widgets:
|
||||||
@ -86,8 +91,9 @@ class BulkConfig(Config):
|
|||||||
self._groups_model = GroupModel(widgets)
|
self._groups_model = GroupModel(widgets)
|
||||||
self.groups.setModel(self._groups_model)
|
self.groups.setModel(self._groups_model)
|
||||||
|
|
||||||
self.groups.setCurrentIndex(self._groups_model.index(0))
|
idx = oidx if -1 < oidx < self._groups_model.rowCount() else 0
|
||||||
|
self.groups.setCurrentIndex(self._groups_model.index(idx))
|
||||||
|
self.stack.setCurrentIndex(idx)
|
||||||
|
|
||||||
def setup_output_formats(self, db, preferred_output_format):
|
def setup_output_formats(self, db, preferred_output_format):
|
||||||
available_formats = ''
|
available_formats = ''
|
||||||
@ -106,6 +112,8 @@ class BulkConfig(Config):
|
|||||||
def accept(self):
|
def accept(self):
|
||||||
recs = GuiRecommendations()
|
recs = GuiRecommendations()
|
||||||
for w in self._groups_model.widgets:
|
for w in self._groups_model.widgets:
|
||||||
|
if not w.pre_commit_check():
|
||||||
|
return
|
||||||
x = w.commit(save_defaults=False)
|
x = w.commit(save_defaults=False)
|
||||||
recs.update(x)
|
recs.update(x)
|
||||||
self._recommendations = recs
|
self._recommendations = recs
|
||||||
|
@ -19,9 +19,9 @@ class LookAndFeelWidget(Widget, Ui_Form):
|
|||||||
def __init__(self, parent, get_option, get_help, db=None, book_id=None):
|
def __init__(self, parent, get_option, get_help, db=None, book_id=None):
|
||||||
Widget.__init__(self, parent, 'look_and_feel',
|
Widget.__init__(self, parent, 'look_and_feel',
|
||||||
['dont_justify', 'extra_css', 'base_font_size',
|
['dont_justify', 'extra_css', 'base_font_size',
|
||||||
'font_size_mapping', 'insert_metadata', 'line_height',
|
'font_size_mapping', 'line_height',
|
||||||
'linearize_tables', 'remove_first_image',
|
'linearize_tables',
|
||||||
'disable_font_rescaling',
|
'disable_font_rescaling', 'insert_blank_line',
|
||||||
'remove_paragraph_spacing', 'input_encoding']
|
'remove_paragraph_spacing', 'input_encoding']
|
||||||
)
|
)
|
||||||
self.db, self.book_id = db, book_id
|
self.db, self.book_id = db, book_id
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
<ui version="4.0" >
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
<class>Form</class>
|
<class>Form</class>
|
||||||
<widget class="QWidget" name="Form" >
|
<widget class="QWidget" name="Form">
|
||||||
<property name="geometry" >
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
@ -9,142 +10,135 @@
|
|||||||
<height>500</height>
|
<height>500</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle" >
|
<property name="windowTitle">
|
||||||
<string>Form</string>
|
<string>Form</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout" >
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QGridLayout" name="gridLayout_6" >
|
<layout class="QGridLayout" name="gridLayout_6">
|
||||||
<item row="1" column="0" colspan="2" >
|
<item row="1" column="0" colspan="2">
|
||||||
<widget class="QLabel" name="label_18" >
|
<widget class="QLabel" name="label_18">
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>Base &font size:</string>
|
<string>Base &font size:</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="buddy" >
|
<property name="buddy">
|
||||||
<cstring>opt_base_font_size</cstring>
|
<cstring>opt_base_font_size</cstring>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="2" >
|
<item row="1" column="2">
|
||||||
<widget class="QDoubleSpinBox" name="opt_base_font_size" >
|
<widget class="QDoubleSpinBox" name="opt_base_font_size">
|
||||||
<property name="suffix" >
|
<property name="suffix">
|
||||||
<string> pt</string>
|
<string> pt</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="decimals" >
|
<property name="decimals">
|
||||||
<number>1</number>
|
<number>1</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="minimum" >
|
<property name="minimum">
|
||||||
<double>0.000000000000000</double>
|
<double>0.000000000000000</double>
|
||||||
</property>
|
</property>
|
||||||
<property name="maximum" >
|
<property name="maximum">
|
||||||
<double>30.000000000000000</double>
|
<double>30.000000000000000</double>
|
||||||
</property>
|
</property>
|
||||||
<property name="singleStep" >
|
<property name="singleStep">
|
||||||
<double>1.000000000000000</double>
|
<double>1.000000000000000</double>
|
||||||
</property>
|
</property>
|
||||||
<property name="value" >
|
<property name="value">
|
||||||
<double>15.000000000000000</double>
|
<double>15.000000000000000</double>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0" >
|
<item row="3" column="0" colspan="2">
|
||||||
<widget class="QLabel" name="label" >
|
<widget class="QLabel" name="label">
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>Line &height:</string>
|
<string>Line &height:</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="buddy" >
|
<property name="buddy">
|
||||||
<cstring>opt_line_height</cstring>
|
<cstring>opt_line_height</cstring>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="2" >
|
<item row="3" column="2">
|
||||||
<widget class="QDoubleSpinBox" name="opt_line_height" >
|
<widget class="QDoubleSpinBox" name="opt_line_height">
|
||||||
<property name="suffix" >
|
<property name="suffix">
|
||||||
<string> pt</string>
|
<string> pt</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="decimals" >
|
<property name="decimals">
|
||||||
<number>1</number>
|
<number>1</number>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="0" colspan="2" >
|
<item row="5" column="0" colspan="3">
|
||||||
<widget class="QCheckBox" name="opt_remove_paragraph_spacing" >
|
<widget class="QCheckBox" name="opt_remove_paragraph_spacing">
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>Remove &spacing between paragraphs</string>
|
<string>Remove &spacing between paragraphs</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="0" colspan="2" >
|
<item row="7" column="0" colspan="3">
|
||||||
<widget class="QCheckBox" name="opt_dont_justify" >
|
<widget class="QCheckBox" name="opt_dont_justify">
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>No text &justification</string>
|
<string>No text &justification</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="7" column="0" colspan="2" >
|
<item row="8" column="0" colspan="3">
|
||||||
<widget class="QCheckBox" name="opt_linearize_tables" >
|
<widget class="QCheckBox" name="opt_linearize_tables">
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>&Linearize tables</string>
|
<string>&Linearize tables</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="8" column="0" colspan="2" >
|
<item row="2" column="0">
|
||||||
<widget class="QCheckBox" name="opt_remove_first_image" >
|
<widget class="QLabel" name="label_2">
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>Remove &first image from source file</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0" >
|
|
||||||
<widget class="QLabel" name="label_2" >
|
|
||||||
<property name="text" >
|
|
||||||
<string>Font size &key:</string>
|
<string>Font size &key:</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="buddy" >
|
<property name="buddy">
|
||||||
<cstring>opt_font_size_mapping</cstring>
|
<cstring>opt_font_size_mapping</cstring>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1" colspan="2" >
|
<item row="2" column="1" colspan="2">
|
||||||
<widget class="QLineEdit" name="opt_font_size_mapping" />
|
<widget class="QLineEdit" name="opt_font_size_mapping"/>
|
||||||
</item>
|
</item>
|
||||||
<item row="9" column="0" colspan="2" >
|
<item row="4" column="0" colspan="2">
|
||||||
<widget class="QCheckBox" name="opt_insert_metadata" >
|
<widget class="QLabel" name="label_3">
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>Insert &metadata at start of book</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="0" colspan="2" >
|
|
||||||
<widget class="QLabel" name="label_3" >
|
|
||||||
<property name="text" >
|
|
||||||
<string>Input character &encoding</string>
|
<string>Input character &encoding</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="buddy" >
|
<property name="buddy">
|
||||||
<cstring>opt_input_encoding</cstring>
|
<cstring>opt_input_encoding</cstring>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="2" >
|
<item row="4" column="2">
|
||||||
<widget class="QLineEdit" name="opt_input_encoding" />
|
<widget class="QLineEdit" name="opt_input_encoding"/>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="0" >
|
<item row="0" column="0" colspan="3">
|
||||||
<widget class="QCheckBox" name="opt_disable_font_rescaling" >
|
<widget class="QCheckBox" name="opt_disable_font_rescaling">
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>&Disable font size rescaling</string>
|
<string>&Disable font size rescaling</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="6" column="0" colspan="3">
|
||||||
|
<widget class="QCheckBox" name="opt_insert_blank_line">
|
||||||
|
<property name="text">
|
||||||
|
<string>Insert &blank line</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox" >
|
<widget class="QGroupBox" name="groupBox">
|
||||||
<property name="title" >
|
<property name="title">
|
||||||
<string>Extra &CSS</string>
|
<string>Extra &CSS</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_3" >
|
<layout class="QGridLayout" name="gridLayout_3">
|
||||||
<item row="0" column="0" >
|
<item row="0" column="0">
|
||||||
<widget class="QTextEdit" name="opt_extra_css" />
|
<widget class="QTextEdit" name="opt_extra_css"/>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
@ -152,8 +146,8 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="../images.qrc" />
|
<include location="../images.qrc"/>
|
||||||
<include location="../images.qrc" />
|
<include location="../images.qrc"/>
|
||||||
</resources>
|
</resources>
|
||||||
<connections>
|
<connections>
|
||||||
<connection>
|
<connection>
|
||||||
@ -162,11 +156,11 @@
|
|||||||
<receiver>opt_base_font_size</receiver>
|
<receiver>opt_base_font_size</receiver>
|
||||||
<slot>setDisabled(bool)</slot>
|
<slot>setDisabled(bool)</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel" >
|
<hint type="sourcelabel">
|
||||||
<x>154</x>
|
<x>154</x>
|
||||||
<y>16</y>
|
<y>16</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel" >
|
<hint type="destinationlabel">
|
||||||
<x>385</x>
|
<x>385</x>
|
||||||
<y>40</y>
|
<y>40</y>
|
||||||
</hint>
|
</hint>
|
||||||
@ -178,11 +172,11 @@
|
|||||||
<receiver>opt_font_size_mapping</receiver>
|
<receiver>opt_font_size_mapping</receiver>
|
||||||
<slot>setDisabled(bool)</slot>
|
<slot>setDisabled(bool)</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel" >
|
<hint type="sourcelabel">
|
||||||
<x>80</x>
|
<x>80</x>
|
||||||
<y>20</y>
|
<y>20</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel" >
|
<hint type="destinationlabel">
|
||||||
<x>285</x>
|
<x>285</x>
|
||||||
<y>72</y>
|
<y>72</y>
|
||||||
</hint>
|
</hint>
|
||||||
|
@ -17,6 +17,9 @@ from calibre.gui2.convert.single_ui import Ui_Dialog
|
|||||||
from calibre.gui2.convert.metadata import MetadataWidget
|
from calibre.gui2.convert.metadata import MetadataWidget
|
||||||
from calibre.gui2.convert.look_and_feel import LookAndFeelWidget
|
from calibre.gui2.convert.look_and_feel import LookAndFeelWidget
|
||||||
from calibre.gui2.convert.page_setup import PageSetupWidget
|
from calibre.gui2.convert.page_setup import PageSetupWidget
|
||||||
|
from calibre.gui2.convert.structure_detection import StructureDetectionWidget
|
||||||
|
from calibre.gui2.convert.toc import TOCWidget
|
||||||
|
|
||||||
|
|
||||||
from calibre.ebooks.conversion.plumber import Plumber, supported_input_formats, \
|
from calibre.ebooks.conversion.plumber import Plumber, supported_input_formats, \
|
||||||
INPUT_FORMAT_PREFERENCES, OUTPUT_FORMAT_PREFERENCES
|
INPUT_FORMAT_PREFERENCES, OUTPUT_FORMAT_PREFERENCES
|
||||||
@ -115,6 +118,7 @@ class Config(ResizableDialog, Ui_Dialog):
|
|||||||
|
|
||||||
|
|
||||||
def setup_pipeline(self, *args):
|
def setup_pipeline(self, *args):
|
||||||
|
oidx = self.groups.currentIndex().row()
|
||||||
input_format = self.input_format
|
input_format = self.input_format
|
||||||
output_format = self.output_format
|
output_format = self.output_format
|
||||||
input_path = self.db.format_abspath(self.book_id, input_format,
|
input_path = self.db.format_abspath(self.book_id, input_format,
|
||||||
@ -134,6 +138,8 @@ class Config(ResizableDialog, Ui_Dialog):
|
|||||||
self.setWindowTitle(_('Convert')+ ' ' + unicode(self.mw.title.text()))
|
self.setWindowTitle(_('Convert')+ ' ' + unicode(self.mw.title.text()))
|
||||||
lf = widget_factory(LookAndFeelWidget)
|
lf = widget_factory(LookAndFeelWidget)
|
||||||
ps = widget_factory(PageSetupWidget)
|
ps = widget_factory(PageSetupWidget)
|
||||||
|
sd = widget_factory(StructureDetectionWidget)
|
||||||
|
toc = widget_factory(TOCWidget)
|
||||||
|
|
||||||
output_widget = None
|
output_widget = None
|
||||||
name = 'calibre.gui2.convert.%s' % self.plumber.output_plugin.name.lower().replace(' ', '_')
|
name = 'calibre.gui2.convert.%s' % self.plumber.output_plugin.name.lower().replace(' ', '_')
|
||||||
@ -162,7 +168,7 @@ class Config(ResizableDialog, Ui_Dialog):
|
|||||||
if not c: break
|
if not c: break
|
||||||
self.stack.removeWidget(c)
|
self.stack.removeWidget(c)
|
||||||
|
|
||||||
widgets = [self.mw, lf, ps]
|
widgets = [self.mw, lf, ps, sd, toc]
|
||||||
if input_widget is not None:
|
if input_widget is not None:
|
||||||
widgets.append(input_widget)
|
widgets.append(input_widget)
|
||||||
if output_widget is not None:
|
if output_widget is not None:
|
||||||
@ -175,7 +181,9 @@ class Config(ResizableDialog, Ui_Dialog):
|
|||||||
self._groups_model = GroupModel(widgets)
|
self._groups_model = GroupModel(widgets)
|
||||||
self.groups.setModel(self._groups_model)
|
self.groups.setModel(self._groups_model)
|
||||||
|
|
||||||
self.groups.setCurrentIndex(self._groups_model.index(0))
|
idx = oidx if -1 < oidx < self._groups_model.rowCount() else 0
|
||||||
|
self.groups.setCurrentIndex(self._groups_model.index(idx))
|
||||||
|
self.stack.setCurrentIndex(idx)
|
||||||
|
|
||||||
|
|
||||||
def setup_input_output_formats(self, db, book_id, preferred_input_format,
|
def setup_input_output_formats(self, db, book_id, preferred_input_format,
|
||||||
@ -213,6 +221,8 @@ class Config(ResizableDialog, Ui_Dialog):
|
|||||||
def accept(self):
|
def accept(self):
|
||||||
recs = GuiRecommendations()
|
recs = GuiRecommendations()
|
||||||
for w in self._groups_model.widgets:
|
for w in self._groups_model.widgets:
|
||||||
|
if not w.pre_commit_check():
|
||||||
|
return
|
||||||
x = w.commit(save_defaults=False)
|
x = w.commit(save_defaults=False)
|
||||||
recs.update(x)
|
recs.update(x)
|
||||||
self.opf_path, self.cover_path = self.mw.opf_file, self.mw.cover_file
|
self.opf_path, self.cover_path = self.mw.opf_file, self.mw.cover_file
|
||||||
|
42
src/calibre/gui2/convert/structure_detection.py
Normal file
42
src/calibre/gui2/convert/structure_detection.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#!/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 calibre.gui2.convert.structure_detection_ui import Ui_Form
|
||||||
|
from calibre.gui2.convert import Widget
|
||||||
|
from calibre.gui2 import error_dialog
|
||||||
|
|
||||||
|
class StructureDetectionWidget(Widget, Ui_Form):
|
||||||
|
|
||||||
|
TITLE = _('Structure\nDetection')
|
||||||
|
ICON = ':/images/chapters.svg'
|
||||||
|
HELP = _('Fine tune the detection of chapter headings and '
|
||||||
|
'other document structure.')
|
||||||
|
|
||||||
|
def __init__(self, parent, get_option, get_help, db=None, book_id=None):
|
||||||
|
Widget.__init__(self, parent, 'structure_detection',
|
||||||
|
['chapter', 'chapter_mark',
|
||||||
|
'remove_first_image',
|
||||||
|
'insert_metadata', 'page_breaks_before',
|
||||||
|
'preprocess_html']
|
||||||
|
)
|
||||||
|
self.db, self.book_id = db, book_id
|
||||||
|
self.initialize_options(get_option, get_help, db, book_id)
|
||||||
|
self.opt_chapter.set_msg(_('Detect chapters at (XPath expression):'))
|
||||||
|
self.opt_page_breaks_before.set_msg(_('Insert page breaks before '
|
||||||
|
'(XPath expression):'))
|
||||||
|
|
||||||
|
|
||||||
|
def pre_commit_check(self):
|
||||||
|
for x in ('chapter', 'page_breaks_before'):
|
||||||
|
x = getattr(self, 'opt_'+x)
|
||||||
|
if not x.check():
|
||||||
|
error_dialog(self, _('Invalid XPath'),
|
||||||
|
_('The XPath expression %s is invalid.')%x.text).exec_()
|
||||||
|
return False
|
||||||
|
return True
|
103
src/calibre/gui2/convert/structure_detection.ui
Normal file
103
src/calibre/gui2/convert/structure_detection.ui
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
<?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>657</width>
|
||||||
|
<height>479</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Chapter &mark:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>opt_chapter_mark</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QComboBox" name="opt_chapter_mark">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>pagebreak</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>rule</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>both</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>none</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QCheckBox" name="opt_remove_first_image">
|
||||||
|
<property name="text">
|
||||||
|
<string>Remove first &image</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QCheckBox" name="opt_insert_metadata">
|
||||||
|
<property name="text">
|
||||||
|
<string>Insert &metadata as page at start of book</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0" colspan="2">
|
||||||
|
<widget class="QCheckBox" name="opt_preprocess_html">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Preprocess input file to possibly improve structure detection</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0" colspan="2">
|
||||||
|
<widget class="XPathEdit" name="opt_page_breaks_before" native="true"/>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0" colspan="2">
|
||||||
|
<widget class="XPathEdit" name="opt_chapter" native="true"/>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="0">
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>XPathEdit</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>convert/xpath_wizard.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
41
src/calibre/gui2/convert/toc.py
Normal file
41
src/calibre/gui2/convert/toc.py
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#!/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 calibre.gui2.convert.toc_ui import Ui_Form
|
||||||
|
from calibre.gui2.convert import Widget
|
||||||
|
from calibre.gui2 import error_dialog
|
||||||
|
|
||||||
|
class TOCWidget(Widget, Ui_Form):
|
||||||
|
|
||||||
|
TITLE = _('Table of\nContents')
|
||||||
|
ICON = ':/images/series.svg'
|
||||||
|
HELP = _('Control the creation/conversion of the Table of Contents.')
|
||||||
|
|
||||||
|
def __init__(self, parent, get_option, get_help, db=None, book_id=None):
|
||||||
|
Widget.__init__(self, parent, 'structure_detection',
|
||||||
|
['level1_toc', 'level2_toc', 'level3_toc',
|
||||||
|
'toc_threshold', 'max_toc_links', 'no_chapters_in_toc',
|
||||||
|
'use_auto_toc', 'toc_filter',
|
||||||
|
]
|
||||||
|
)
|
||||||
|
self.db, self.book_id = db, book_id
|
||||||
|
self.initialize_options(get_option, get_help, db, book_id)
|
||||||
|
self.opt_level1_toc.set_msg(_('Level &1 TOC (XPath expression):'))
|
||||||
|
self.opt_level2_toc.set_msg(_('Level &2 TOC (XPath expression):'))
|
||||||
|
self.opt_level3_toc.set_msg(_('Level &3 TOC (XPath expression):'))
|
||||||
|
|
||||||
|
|
||||||
|
def pre_commit_check(self):
|
||||||
|
for x in ('level1', 'level2', 'level3'):
|
||||||
|
x = getattr(self, 'opt_'+x+'_toc')
|
||||||
|
if not x.check():
|
||||||
|
error_dialog(self, _('Invalid XPath'),
|
||||||
|
_('The XPath expression %s is invalid.')%x.text).exec_()
|
||||||
|
return False
|
||||||
|
return True
|
104
src/calibre/gui2/convert/toc.ui
Normal file
104
src/calibre/gui2/convert/toc.ui
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
<?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>436</width>
|
||||||
|
<height>382</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="1" column="0" colspan="2">
|
||||||
|
<widget class="QCheckBox" name="opt_no_chapters_in_toc">
|
||||||
|
<property name="text">
|
||||||
|
<string>Do not add &detected chapters to the Table of Contents</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label_10">
|
||||||
|
<property name="text">
|
||||||
|
<string>Number of &links to add to Table of Contents</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>opt_max_toc_links</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QSpinBox" name="opt_max_toc_links"/>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="label_16">
|
||||||
|
<property name="text">
|
||||||
|
<string>Chapter &threshold</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>opt_toc_threshold</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QSpinBox" name="opt_toc_threshold"/>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0" colspan="2">
|
||||||
|
<widget class="QCheckBox" name="opt_use_auto_toc">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Force use of auto-generated Table of Contents</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>TOC &Filter:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>opt_toc_filter</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1">
|
||||||
|
<widget class="QLineEdit" name="opt_toc_filter"/>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0" colspan="2">
|
||||||
|
<widget class="XPathEdit" name="opt_level1_toc" native="true"/>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="0" colspan="2">
|
||||||
|
<widget class="XPathEdit" name="opt_level2_toc" native="true"/>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="0" colspan="2">
|
||||||
|
<widget class="XPathEdit" name="opt_level3_toc" native="true"/>
|
||||||
|
</item>
|
||||||
|
<item row="8" column="0">
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>XPathEdit</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>convert/xpath_wizard.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
63
src/calibre/gui2/convert/xpath_edit.ui
Normal file
63
src/calibre/gui2/convert/xpath_edit.ui
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<?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>400</width>
|
||||||
|
<height>64</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="msg">
|
||||||
|
<property name="text">
|
||||||
|
<string>TextLabel</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>edit</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="edit"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QToolButton" name="button">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Use a wizard to help construct the XPath expression</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../images.qrc">
|
||||||
|
<normaloff>:/images/wizard.svg</normaloff>:/images/wizard.svg</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources>
|
||||||
|
<include location="../images.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
96
src/calibre/gui2/convert/xpath_wizard.py
Normal file
96
src/calibre/gui2/convert/xpath_wizard.py
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
#!/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 QDialog, QWidget, SIGNAL, Qt, QDialogButtonBox, QVBoxLayout
|
||||||
|
|
||||||
|
from calibre.gui2.convert.xpath_wizard_ui import Ui_Form
|
||||||
|
from calibre.gui2.convert.xpath_edit_ui import Ui_Form as Ui_Edit
|
||||||
|
|
||||||
|
|
||||||
|
class WizardWidget(QWidget, Ui_Form):
|
||||||
|
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
QWidget.__init__(self, parent)
|
||||||
|
self.setupUi(self)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def xpath(self):
|
||||||
|
tag = unicode(self.tag.currentText()).strip()
|
||||||
|
if tag != '*':
|
||||||
|
tag = 'h:'+tag
|
||||||
|
attr, val = map(unicode, (self.attribute.text(), self.value.text()))
|
||||||
|
attr, val = attr.strip(), val.strip()
|
||||||
|
q = ''
|
||||||
|
if attr:
|
||||||
|
if val:
|
||||||
|
q = '[re:test(@%s, "%s", "i")]'%(attr, val)
|
||||||
|
else:
|
||||||
|
q = '[@%s]'%attr
|
||||||
|
expr = '//'+tag + q
|
||||||
|
return expr
|
||||||
|
|
||||||
|
class Wizard(QDialog):
|
||||||
|
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
QDialog.__init__(self, parent)
|
||||||
|
self.resize(400, 300)
|
||||||
|
self.verticalLayout = QVBoxLayout(self)
|
||||||
|
self.widget = WizardWidget(self)
|
||||||
|
self.verticalLayout.addWidget(self.widget)
|
||||||
|
self.buttonBox = QDialogButtonBox(self)
|
||||||
|
self.buttonBox.setOrientation(Qt.Horizontal)
|
||||||
|
self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok)
|
||||||
|
self.verticalLayout.addWidget(self.buttonBox)
|
||||||
|
|
||||||
|
self.connect(self.buttonBox, SIGNAL("accepted()"), self.accept)
|
||||||
|
self.connect(self.buttonBox, SIGNAL("rejected()"), self.reject)
|
||||||
|
self.setModal(Qt.WindowModal)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def xpath(self):
|
||||||
|
return self.widget.xpath
|
||||||
|
|
||||||
|
|
||||||
|
class XPathEdit(QWidget, Ui_Edit):
|
||||||
|
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
QWidget.__init__(self, parent)
|
||||||
|
self.setupUi(self)
|
||||||
|
self.connect(self.button, SIGNAL('clicked()'), self.wizard)
|
||||||
|
|
||||||
|
def wizard(self):
|
||||||
|
wiz = Wizard(self)
|
||||||
|
if wiz.exec_() == wiz.Accepted:
|
||||||
|
self.edit.setText(wiz.xpath)
|
||||||
|
|
||||||
|
|
||||||
|
def set_msg(self, msg):
|
||||||
|
self.msg.setText(msg)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def text(self):
|
||||||
|
return unicode(self.edit.text())
|
||||||
|
|
||||||
|
@property
|
||||||
|
def xpath(self):
|
||||||
|
return self.text
|
||||||
|
|
||||||
|
def check(self):
|
||||||
|
from calibre.ebooks.oeb.base import XPNSMAP
|
||||||
|
from lxml.etree import XPath
|
||||||
|
try:
|
||||||
|
if self.text.strip():
|
||||||
|
XPath(self.text, namespaces=XPNSMAP)
|
||||||
|
except:
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
|
143
src/calibre/gui2/convert/xpath_wizard.ui
Normal file
143
src/calibre/gui2/convert/xpath_wizard.ui
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
<ui version="4.0" >
|
||||||
|
<class>Form</class>
|
||||||
|
<widget class="QWidget" name="Form" >
|
||||||
|
<property name="geometry" >
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>400</width>
|
||||||
|
<height>381</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle" >
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout" >
|
||||||
|
<item row="0" column="0" colspan="2" >
|
||||||
|
<widget class="QLabel" name="label" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Match HTML &tags with tag name:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy" >
|
||||||
|
<cstring>tag</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0" >
|
||||||
|
<widget class="QComboBox" name="tag" >
|
||||||
|
<property name="editable" >
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<property name="text" >
|
||||||
|
<string>*</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text" >
|
||||||
|
<string>a</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text" >
|
||||||
|
<string>br</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text" >
|
||||||
|
<string>div</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text" >
|
||||||
|
<string>h1</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text" >
|
||||||
|
<string>h2</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text" >
|
||||||
|
<string>h3</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text" >
|
||||||
|
<string>h4</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text" >
|
||||||
|
<string>h5</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text" >
|
||||||
|
<string>h6</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text" >
|
||||||
|
<string>hr</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text" >
|
||||||
|
<string>span</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0" colspan="2" >
|
||||||
|
<widget class="QLabel" name="label_2" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Having the &attribute:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy" >
|
||||||
|
<cstring>attribute</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0" colspan="2" >
|
||||||
|
<widget class="QLineEdit" name="attribute" />
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0" >
|
||||||
|
<widget class="QLabel" name="label_3" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>With &value:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy" >
|
||||||
|
<cstring>value</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0" >
|
||||||
|
<widget class="QLineEdit" name="value" />
|
||||||
|
</item>
|
||||||
|
<item row="5" column="1" >
|
||||||
|
<widget class="QLabel" name="label_4" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>(A regular expression)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="0" colspan="2" >
|
||||||
|
<widget class="QLabel" name="label_5" >
|
||||||
|
<property name="text" >
|
||||||
|
<string><p>For example, to match all h2 tags that have class="chapter", set tag to <i>h2</i>, attribute to <i>class</i> and value to <i>chapter</i>.</p><p>Leaving attribute blank will match any attribute and leaving value blank will match any value. Setting tag to * will match any tag.</p><p>To learn more advanced usage of XPath see the <a href="http://calibre.kovidgoyal.net/user_manual/xpath.html">XPath Tutorial</a>.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap" >
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="openExternalLinks" >
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
@ -8,7 +8,7 @@ from PyQt4.Qt import QDialog, QMessageBox, QListWidgetItem, QIcon, \
|
|||||||
QStringListModel, QAbstractItemModel, QFont, \
|
QStringListModel, QAbstractItemModel, QFont, \
|
||||||
SIGNAL, QTimer, Qt, QSize, QVariant, QUrl, \
|
SIGNAL, QTimer, Qt, QSize, QVariant, QUrl, \
|
||||||
QModelIndex, QInputDialog, QAbstractTableModel, \
|
QModelIndex, QInputDialog, QAbstractTableModel, \
|
||||||
QDialogButtonBox
|
QDialogButtonBox, QTabWidget
|
||||||
|
|
||||||
from calibre.constants import islinux, iswindows
|
from calibre.constants import islinux, iswindows
|
||||||
from calibre.gui2.dialogs.config_ui import Ui_Dialog
|
from calibre.gui2.dialogs.config_ui import Ui_Dialog
|
||||||
@ -23,8 +23,72 @@ from calibre.ebooks.oeb.iterator import is_supported
|
|||||||
from calibre.library import server_config
|
from calibre.library import server_config
|
||||||
from calibre.customize.ui import initialized_plugins, is_disabled, enable_plugin, \
|
from calibre.customize.ui import initialized_plugins, is_disabled, enable_plugin, \
|
||||||
disable_plugin, customize_plugin, \
|
disable_plugin, customize_plugin, \
|
||||||
plugin_customization, add_plugin, remove_plugin
|
plugin_customization, add_plugin, \
|
||||||
|
remove_plugin, input_format_plugins, \
|
||||||
|
output_format_plugins
|
||||||
from calibre.utils.smtp import config as smtp_prefs
|
from calibre.utils.smtp import config as smtp_prefs
|
||||||
|
from calibre.gui2.convert.look_and_feel import LookAndFeelWidget
|
||||||
|
from calibre.gui2.convert.page_setup import PageSetupWidget
|
||||||
|
from calibre.gui2.convert.structure_detection import StructureDetectionWidget
|
||||||
|
from calibre.ebooks.conversion.plumber import Plumber
|
||||||
|
from calibre.utils.logging import Log
|
||||||
|
from calibre.gui2.convert.toc import TOCWidget
|
||||||
|
|
||||||
|
class ConfigTabs(QTabWidget):
|
||||||
|
|
||||||
|
def __init__(self, parent):
|
||||||
|
QTabWidget.__init__(self, parent)
|
||||||
|
log = Log()
|
||||||
|
log.outputs = []
|
||||||
|
|
||||||
|
self.plumber = Plumber('dummt.epub', 'dummy.epub', log)
|
||||||
|
|
||||||
|
def widget_factory(cls):
|
||||||
|
return cls(self, self.plumber.get_option_by_name,
|
||||||
|
self.plumber.get_option_help, None, None)
|
||||||
|
|
||||||
|
lf = widget_factory(LookAndFeelWidget)
|
||||||
|
ps = widget_factory(PageSetupWidget)
|
||||||
|
sd = widget_factory(StructureDetectionWidget)
|
||||||
|
toc = widget_factory(TOCWidget)
|
||||||
|
|
||||||
|
self.widgets = [lf, ps, sd, toc]
|
||||||
|
|
||||||
|
for plugin in input_format_plugins():
|
||||||
|
name = plugin.name.lower().replace(' ', '_')
|
||||||
|
try:
|
||||||
|
input_widget = __import__('calibre.gui2.convert.'+name,
|
||||||
|
fromlist=[1])
|
||||||
|
pw = input_widget.PluginWidget
|
||||||
|
pw.ICON = ':/images/forward.svg'
|
||||||
|
pw.HELP = _('Options specific to the input format.')
|
||||||
|
self.widgets.append(widget_factory(pw))
|
||||||
|
except ImportError:
|
||||||
|
continue
|
||||||
|
|
||||||
|
for plugin in output_format_plugins():
|
||||||
|
name = plugin.name.lower().replace(' ', '_')
|
||||||
|
try:
|
||||||
|
output_widget = __import__('calibre.gui2.convert.'+name,
|
||||||
|
fromlist=[1])
|
||||||
|
pw = output_widget.PluginWidget
|
||||||
|
pw.ICON = ':/images/forward.svg'
|
||||||
|
pw.HELP = _('Options specific to the input format.')
|
||||||
|
self.widgets.append(widget_factory(pw))
|
||||||
|
except ImportError:
|
||||||
|
continue
|
||||||
|
|
||||||
|
for widget in self.widgets:
|
||||||
|
self.addTab(widget, widget.TITLE.replace('\n', ' ').replace('&',
|
||||||
|
'&&'))
|
||||||
|
|
||||||
|
def commit(self):
|
||||||
|
for widget in self.widgets:
|
||||||
|
if not widget.pre_commit_check():
|
||||||
|
return False
|
||||||
|
widget.commit(save_defaults=True)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class PluginModel(QAbstractItemModel):
|
class PluginModel(QAbstractItemModel):
|
||||||
|
|
||||||
@ -124,10 +188,12 @@ class CategoryModel(QStringListModel):
|
|||||||
|
|
||||||
def __init__(self, *args):
|
def __init__(self, *args):
|
||||||
QStringListModel.__init__(self, *args)
|
QStringListModel.__init__(self, *args)
|
||||||
self.setStringList([_('General'), _('Interface'), _('Email\nDelivery'),
|
self.setStringList([_('General'), _('Interface'), _('Conversion'),
|
||||||
|
_('Email\nDelivery'),
|
||||||
_('Advanced'), _('Content\nServer'), _('Plugins')])
|
_('Advanced'), _('Content\nServer'), _('Plugins')])
|
||||||
self.icons = list(map(QVariant, map(QIcon,
|
self.icons = list(map(QVariant, map(QIcon,
|
||||||
[':/images/dialog_information.svg', ':/images/lookfeel.svg',
|
[':/images/dialog_information.svg', ':/images/lookfeel.svg',
|
||||||
|
':/images/convert.svg',
|
||||||
':/images/mail.svg', ':/images/view.svg',
|
':/images/mail.svg', ':/images/view.svg',
|
||||||
':/images/network-server.svg', ':/images/plugins.svg'])))
|
':/images/network-server.svg', ':/images/plugins.svg'])))
|
||||||
|
|
||||||
@ -401,6 +467,11 @@ class ConfigDialog(QDialog, Ui_Dialog):
|
|||||||
self.delete_news.setEnabled(bool(self.sync_news.isChecked()))
|
self.delete_news.setEnabled(bool(self.sync_news.isChecked()))
|
||||||
self.connect(self.sync_news, SIGNAL('toggled(bool)'),
|
self.connect(self.sync_news, SIGNAL('toggled(bool)'),
|
||||||
self.delete_news.setEnabled)
|
self.delete_news.setEnabled)
|
||||||
|
self.setup_conversion_options()
|
||||||
|
|
||||||
|
def setup_conversion_options(self):
|
||||||
|
self.conversion_options = ConfigTabs(self)
|
||||||
|
self.stackedWidget.insertWidget(2, self.conversion_options)
|
||||||
|
|
||||||
def setup_email_page(self):
|
def setup_email_page(self):
|
||||||
opts = smtp_prefs().parse()
|
opts = smtp_prefs().parse()
|
||||||
@ -670,6 +741,8 @@ class ConfigDialog(QDialog, Ui_Dialog):
|
|||||||
return
|
return
|
||||||
if not self.set_email_settings():
|
if not self.set_email_settings():
|
||||||
return
|
return
|
||||||
|
if not self.conversion_options.commit():
|
||||||
|
return
|
||||||
config['use_roman_numerals_for_series_number'] = bool(self.roman_numerals.isChecked())
|
config['use_roman_numerals_for_series_number'] = bool(self.roman_numerals.isChecked())
|
||||||
config['new_version_notification'] = bool(self.new_version_notification.isChecked())
|
config['new_version_notification'] = bool(self.new_version_notification.isChecked())
|
||||||
prefs['network_timeout'] = int(self.timeout.value())
|
prefs['network_timeout'] = int(self.timeout.value())
|
||||||
|
1385
src/calibre/gui2/images/wizard.svg
Normal file
1385
src/calibre/gui2/images/wizard.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 98 KiB |
@ -312,6 +312,8 @@ class gui(OptionlessCommand):
|
|||||||
dat = dat.replace('import images_rc', 'from calibre.gui2 import images_rc')
|
dat = dat.replace('import images_rc', 'from calibre.gui2 import images_rc')
|
||||||
dat = dat.replace('from library import', 'from calibre.gui2.library import')
|
dat = dat.replace('from library import', 'from calibre.gui2.library import')
|
||||||
dat = dat.replace('from widgets import', 'from calibre.gui2.widgets import')
|
dat = dat.replace('from widgets import', 'from calibre.gui2.widgets import')
|
||||||
|
dat = dat.replace('from convert.xpath_wizard import',
|
||||||
|
'from calibre.gui2.convert.xpath_wizard import')
|
||||||
dat = re.compile(r'QtGui.QApplication.translate\(.+?,\s+"(.+?)(?<!\\)",.+?\)', re.DOTALL).sub(r'_("\1")', dat)
|
dat = re.compile(r'QtGui.QApplication.translate\(.+?,\s+"(.+?)(?<!\\)",.+?\)', re.DOTALL).sub(r'_("\1")', dat)
|
||||||
|
|
||||||
# Workaround bug in Qt 4.4 on Windows
|
# Workaround bug in Qt 4.4 on Windows
|
||||||
|
Loading…
x
Reference in New Issue
Block a user