Edit ToC: Allow the size of the panels in the location view to be adjusted

This commit is contained in:
Kovid Goyal 2013-04-13 11:13:30 +05:30
parent cd1765b935
commit 4db56199ee
2 changed files with 59 additions and 35 deletions

View File

@ -11,11 +11,11 @@ from base64 import b64encode
from PyQt4.Qt import (QWidget, QGridLayout, QListWidget, QSize, Qt, QUrl,
pyqtSlot, pyqtSignal, QVBoxLayout, QFrame, QLabel,
QLineEdit, QTimer, QPushButton, QIcon)
QLineEdit, QTimer, QPushButton, QIcon, QSplitter)
from PyQt4.QtWebKit import QWebView, QWebPage, QWebElement
from calibre.ebooks.oeb.display.webview import load_html
from calibre.gui2 import error_dialog, question_dialog
from calibre.gui2 import error_dialog, question_dialog, gprefs
from calibre.utils.logging import default_log
class Page(QWebPage): # {{{
@ -106,38 +106,46 @@ class ItemEdit(QWidget):
def __init__(self, parent):
QWidget.__init__(self, parent)
self.l = l = QGridLayout()
self.setLayout(l)
self.setLayout(QVBoxLayout())
self.la = la = QLabel('<b>'+_(
'Select a destination for the Table of Contents entry'))
l.addWidget(la, 0, 0, 1, 3)
self.layout().addWidget(la)
self.splitter = sp = QSplitter(self)
self.layout().addWidget(sp)
self.layout().setStretch(1, 10)
sp.setOpaqueResize(False)
sp.setChildrenCollapsible(False)
self.dest_list = dl = QListWidget(self)
dl.setMinimumWidth(250)
dl.currentItemChanged.connect(self.current_changed)
l.addWidget(dl, 1, 0, 2, 1)
sp.addWidget(dl)
w = self.w = QWidget(self)
l = w.l = QGridLayout()
w.setLayout(l)
self.view = WebView(self)
self.view.elem_clicked.connect(self.elem_clicked)
l.addWidget(self.view, 1, 1, 1, 3)
l.addWidget(self.view, 0, 0, 1, 3)
sp.addWidget(w)
self.search_text = s = QLineEdit(self)
s.setPlaceholderText(_('Search for text...'))
l.addWidget(s, 1, 0)
self.ns_button = b = QPushButton(QIcon(I('arrow-down.png')), _('Find &next'), self)
b.clicked.connect(self.find_next)
l.addWidget(b, 1, 1)
self.ps_button = b = QPushButton(QIcon(I('arrow-up.png')), _('Find &previous'), self)
l.addWidget(b, 1, 2)
b.clicked.connect(self.find_previous)
self.f = f = QFrame()
f.setFrameShape(f.StyledPanel)
f.setMinimumWidth(250)
l.addWidget(f, 1, 4, 2, 1)
self.search_text = s = QLineEdit(self)
s.setPlaceholderText(_('Search for text...'))
l.addWidget(s, 2, 1, 1, 1)
self.ns_button = b = QPushButton(QIcon(I('arrow-down.png')), _('Find &next'), self)
b.clicked.connect(self.find_next)
l.addWidget(b, 2, 2, 1, 1)
self.ps_button = b = QPushButton(QIcon(I('arrow-up.png')), _('Find &previous'), self)
l.addWidget(b, 2, 3, 1, 1)
b.clicked.connect(self.find_previous)
l.setRowStretch(1, 10)
l = f.l = QVBoxLayout()
f.setLayout(l)
sp.addWidget(f)
f.la = la = QLabel('<p>'+_(
'Here you can choose a destination for the Table of Contents\' entry'
@ -167,6 +175,10 @@ class ItemEdit(QWidget):
l.addStretch()
state = gprefs.get('toc_edit_splitter_state', None)
if state is not None:
sp.restoreState(state)
def keyPressEvent(self, ev):
if ev.key() in (Qt.Key_Return, Qt.Key_Enter) and self.search_text.hasFocus():
# Prevent pressing enter in the search box from triggering the dialog's accept() method
@ -236,6 +248,7 @@ class ItemEdit(QWidget):
if item is not None:
if where is None:
self.name.setText(item.data(0, Qt.DisplayRole).toString())
self.name.setCursorPosition(0)
toc = item.data(0, Qt.UserRole).toPyObject()
if toc.dest:
for i in xrange(self.dest_list.count()):
@ -272,7 +285,6 @@ class ItemEdit(QWidget):
loctext = _('Approximately %d%% from the top')%frac
return loctext
def elem_clicked(self, tag, frac, elem_id, loc):
self.current_frag = elem_id or loc
base = _('Location: A &lt;%s&gt; tag inside the file')%tag

View File

@ -14,7 +14,7 @@ from functools import partial
from PyQt4.Qt import (QPushButton, QFrame, QVariant, QMenu, QInputDialog,
QDialog, QVBoxLayout, QDialogButtonBox, QSize, QStackedWidget, QWidget,
QLabel, Qt, pyqtSignal, QIcon, QTreeWidget, QGridLayout, QTreeWidgetItem,
QToolButton, QItemSelectionModel, QCursor)
QToolButton, QItemSelectionModel, QCursor, QKeySequence)
from calibre.ebooks.oeb.polish.container import get_container, AZW3Container
from calibre.ebooks.oeb.polish.toc import (
@ -207,7 +207,6 @@ class ItemView(QFrame): # {{{
)))
l.addWidget(b)
l.addStretch()
self.w1 = la = QLabel(_('<b>WARNING:</b> calibre only supports the '
'creation of linear ToCs in AZW3 files. In a '
@ -351,6 +350,8 @@ class ItemView(QFrame): # {{{
class TreeWidget(QTreeWidget): # {{{
edit_item = pyqtSignal()
def __init__(self, parent):
QTreeWidget.__init__(self, parent)
self.setHeaderLabel(_('Table of Contents'))
@ -510,20 +511,25 @@ class TreeWidget(QTreeWidget): # {{{
def show_context_menu(self, point):
item = self.currentItem()
def key(k):
sc = unicode(QKeySequence(k | Qt.CTRL).toString(QKeySequence.NativeText))
return ' [%s]'%sc
if item is not None:
m = QMenu()
ci = unicode(item.data(0, Qt.DisplayRole).toString())
p = item.parent() or self.invisibleRootItem()
idx = p.indexOfChild(item)
if idx > 0:
m.addAction(QIcon(I('arrow-up.png')), _('Move "%s" up')%ci, self.move_up)
m.addAction(QIcon(I('arrow-up.png')), (_('Move "%s" up')%ci)+key(Qt.Key_Up), self.move_up)
if idx + 1 < p.childCount():
m.addAction(QIcon(I('arrow-down.png')), _('Move "%s" down')%ci, self.move_down)
m.addAction(QIcon(I('arrow-down.png')), (_('Move "%s" down')%ci)+key(Qt.Key_Down), self.move_down)
m.addAction(QIcon(I('trash.png')), _('Remove all selected items'), self.del_items)
if item.parent() is not None:
m.addAction(QIcon(I('back.png')), _('Unindent "%s"')%ci, self.move_left)
m.addAction(QIcon(I('back.png')), (_('Unindent "%s"')%ci)+key(Qt.Key_Left), self.move_left)
if idx > 0:
m.addAction(QIcon(I('forward.png')), _('Indent "%s"')%ci, self.move_right)
m.addAction(QIcon(I('forward.png')), (_('Indent "%s"')%ci)+key(Qt.Key_Right), self.move_right)
m.addAction(QIcon(I('edit_input.png')), _('Change the location this entry points to'), self.edit_item)
m.addAction(_('Change all selected items to title case'), self.title_case)
m.exec_(QCursor.pos())
# }}}
@ -537,6 +543,7 @@ class TOCView(QWidget): # {{{
l = self.l = QGridLayout()
self.setLayout(l)
self.tocw = t = TreeWidget(self)
self.tocw.edit_item.connect(self.edit_item)
l.addWidget(t, 0, 0, 7, 3)
self.up_button = b = QToolButton(self)
b.setIcon(QIcon(I('arrow-up.png')))
@ -595,6 +602,9 @@ class TOCView(QWidget): # {{{
l.setColumnStretch(2, 10)
def edit_item(self):
self.item_view.edit_item()
def event(self, e):
if e.type() == e.StatusTip:
txt = unicode(e.tip()) or self.default_msg
@ -742,12 +752,12 @@ class TOCView(QWidget): # {{{
else:
parent = item.parent() or self.root
idx = parent.indexOfChild(item)
if where == 'after': idx += 1
if where == 'after':
idx += 1
c = self.create_item(parent, child, idx=idx)
self.tocw.setCurrentItem(c, 0, QItemSelectionModel.ClearAndSelect)
self.tocw.scrollToItem(c)
def create_toc(self):
root = TOC()
@ -857,6 +867,7 @@ class TOCEditor(QDialog): # {{{
def accept(self):
if self.stacks.currentIndex() == 2:
self.toc_view.update_item(*self.item_edit.result)
gprefs['toc_edit_splitter_state'] = bytearray(self.item_edit.splitter.saveState())
self.stacks.setCurrentIndex(1)
elif self.stacks.currentIndex() == 1:
self.working = False
@ -883,6 +894,7 @@ class TOCEditor(QDialog): # {{{
if not self.bb.isEnabled():
return
if self.stacks.currentIndex() == 2:
gprefs['toc_edit_splitter_state'] = bytearray(self.item_edit.splitter.saveState())
self.stacks.setCurrentIndex(1)
else:
self.working = False