mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -04:00
ToC Editor: Allow creating toc from arbitrary xpath expressions
This commit is contained in:
parent
1f93448791
commit
6f7d6cf4ea
@ -22,10 +22,52 @@ from calibre.ebooks.oeb.polish.toc import (
|
|||||||
from calibre.gui2 import Application, error_dialog, gprefs
|
from calibre.gui2 import Application, error_dialog, gprefs
|
||||||
from calibre.gui2.progress_indicator import ProgressIndicator
|
from calibre.gui2.progress_indicator import ProgressIndicator
|
||||||
from calibre.gui2.toc.location import ItemEdit
|
from calibre.gui2.toc.location import ItemEdit
|
||||||
|
from calibre.gui2.convert.xpath_wizard import XPathEdit
|
||||||
from calibre.utils.logging import GUILog
|
from calibre.utils.logging import GUILog
|
||||||
|
|
||||||
ICON_SIZE = 24
|
ICON_SIZE = 24
|
||||||
|
|
||||||
|
class XPathDialog(QDialog): # {{{
|
||||||
|
|
||||||
|
def __init__(self, parent):
|
||||||
|
QDialog.__init__(self, parent)
|
||||||
|
self.setWindowTitle(_('Create ToC from XPath'))
|
||||||
|
self.l = l = QVBoxLayout()
|
||||||
|
self.setLayout(l)
|
||||||
|
self.la = la = QLabel(_(
|
||||||
|
'Specify a series of XPath expressions for the different levels of'
|
||||||
|
' the Table of Contents. You can use the wizard buttons to help'
|
||||||
|
' you create XPath expressions.'))
|
||||||
|
la.setWordWrap(True)
|
||||||
|
l.addWidget(la)
|
||||||
|
self.widgets = []
|
||||||
|
for i in xrange(5):
|
||||||
|
la = _('Level %s ToC:')%('&%d'%(i+1))
|
||||||
|
xp = XPathEdit(self)
|
||||||
|
xp.set_msg(la)
|
||||||
|
self.widgets.append(xp)
|
||||||
|
l.addWidget(xp)
|
||||||
|
|
||||||
|
self.bb = bb = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel)
|
||||||
|
bb.accepted.connect(self.accept)
|
||||||
|
bb.rejected.connect(self.reject)
|
||||||
|
l.addStretch()
|
||||||
|
l.addWidget(bb)
|
||||||
|
self.resize(self.sizeHint() + QSize(50, 75))
|
||||||
|
|
||||||
|
def accept(self):
|
||||||
|
for w in self.widgets:
|
||||||
|
if not w.check():
|
||||||
|
return error_dialog(self, _('Invalid XPath'),
|
||||||
|
_('The XPath expression %s is not valid.')%w.xpath,
|
||||||
|
show=True)
|
||||||
|
super(XPathDialog, self).accept()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def xpaths(self):
|
||||||
|
return [w.xpath for w in self.widgets if w.xpath.strip()]
|
||||||
|
# }}}
|
||||||
|
|
||||||
class ItemView(QFrame): # {{{
|
class ItemView(QFrame): # {{{
|
||||||
|
|
||||||
add_new_item = pyqtSignal(object, object)
|
add_new_item = pyqtSignal(object, object)
|
||||||
@ -90,6 +132,14 @@ class ItemView(QFrame): # {{{
|
|||||||
)))
|
)))
|
||||||
l.addWidget(b)
|
l.addWidget(b)
|
||||||
|
|
||||||
|
self.xpb = b = QPushButton(_('Generate ToC from &XPath'))
|
||||||
|
b.clicked.connect(self.create_from_user_xpath)
|
||||||
|
b.setToolTip(textwrap.fill(_(
|
||||||
|
'Generate a Table of Contents from arbitrary XPath expressions.'
|
||||||
|
)))
|
||||||
|
l.addWidget(b)
|
||||||
|
|
||||||
|
|
||||||
l.addStretch()
|
l.addStretch()
|
||||||
self.w1 = la = QLabel(_('<b>WARNING:</b> calibre only supports the '
|
self.w1 = la = QLabel(_('<b>WARNING:</b> calibre only supports the '
|
||||||
'creation of linear ToCs in AZW3 files. In a '
|
'creation of linear ToCs in AZW3 files. In a '
|
||||||
@ -151,18 +201,20 @@ class ItemView(QFrame): # {{{
|
|||||||
ip.b5 = b = QPushButton(QIcon(I('plus.png')), _('New entry &below this entry'))
|
ip.b5 = b = QPushButton(QIcon(I('plus.png')), _('New entry &below this entry'))
|
||||||
b.clicked.connect(partial(self.add_new, 'after'))
|
b.clicked.connect(partial(self.add_new, 'after'))
|
||||||
l.addWidget(b, l.rowCount(), 0, 1, 2)
|
l.addWidget(b, l.rowCount(), 0, 1, 2)
|
||||||
ip.hl4 = hl = QFrame()
|
|
||||||
hl.setFrameShape(hl.HLine)
|
|
||||||
l.addWidget(hl, l.rowCount(), 0, 1, 2)
|
|
||||||
l.setRowMinimumHeight(rs, 20)
|
|
||||||
|
|
||||||
# Flatten entry
|
# Flatten entry
|
||||||
rs = l.rowCount()
|
|
||||||
ip.b3 = b = QPushButton(QIcon(I('heuristics.png')), _('&Flatten this entry'))
|
ip.b3 = b = QPushButton(QIcon(I('heuristics.png')), _('&Flatten this entry'))
|
||||||
b.clicked.connect(self.flatten_item)
|
b.clicked.connect(self.flatten_item)
|
||||||
b.setToolTip(_('All children of this entry are brought to the same '
|
b.setToolTip(_('All children of this entry are brought to the same '
|
||||||
'level as this entry.'))
|
'level as this entry.'))
|
||||||
l.addWidget(b, l.rowCount()+1, 0, 1, 2)
|
l.addWidget(b, l.rowCount()+1, 0, 1, 2)
|
||||||
|
|
||||||
|
ip.hl4 = hl = QFrame()
|
||||||
|
hl.setFrameShape(hl.HLine)
|
||||||
|
l.addWidget(hl, l.rowCount(), 0, 1, 2)
|
||||||
|
l.setRowMinimumHeight(rs, 20)
|
||||||
|
|
||||||
|
# Return to welcome
|
||||||
|
rs = l.rowCount()
|
||||||
ip.b4 = b = QPushButton(QIcon(I('back.png')), _('&Return to welcome screen'))
|
ip.b4 = b = QPushButton(QIcon(I('back.png')), _('&Return to welcome screen'))
|
||||||
b.clicked.connect(self.go_to_root)
|
b.clicked.connect(self.go_to_root)
|
||||||
b.setToolTip(_('Go back to the top level view'))
|
b.setToolTip(_('Go back to the top level view'))
|
||||||
@ -183,6 +235,11 @@ class ItemView(QFrame): # {{{
|
|||||||
def create_from_all_headings(self):
|
def create_from_all_headings(self):
|
||||||
self.create_from_xpath.emit(['//h:h%d'%i for i in xrange(1, 7)])
|
self.create_from_xpath.emit(['//h:h%d'%i for i in xrange(1, 7)])
|
||||||
|
|
||||||
|
def create_from_user_xpath(self):
|
||||||
|
d = XPathDialog(self)
|
||||||
|
if d.exec_() == d.Accepted and d.xpaths:
|
||||||
|
self.create_from_xpath.emit(d.xpaths)
|
||||||
|
|
||||||
def hide_azw3_warning(self):
|
def hide_azw3_warning(self):
|
||||||
self.w1.setVisible(False), self.w2.setVisible(False)
|
self.w1.setVisible(False), self.w2.setVisible(False)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user