mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 02:34:06 -04:00
Implement #3793 (Viewer Key Assignments)
This commit is contained in:
parent
745a2effce
commit
244c9368c8
266
src/calibre/gui2/shortcuts.py
Normal file
266
src/calibre/gui2/shortcuts.py
Normal file
@ -0,0 +1,266 @@
|
|||||||
|
#!/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 functools import partial
|
||||||
|
|
||||||
|
from PyQt4.Qt import QAbstractListModel, Qt, QKeySequence, QListView, \
|
||||||
|
QHBoxLayout, QWidget, QApplication, QStyledItemDelegate, QStyle, \
|
||||||
|
QVariant, QTextDocument, QRectF, QFrame, QSize, QFont, QKeyEvent
|
||||||
|
|
||||||
|
from calibre.gui2 import NONE, error_dialog
|
||||||
|
from calibre.utils.config import XMLConfig
|
||||||
|
from calibre.gui2.shortcuts_ui import Ui_Frame
|
||||||
|
|
||||||
|
DEFAULTS = Qt.UserRole
|
||||||
|
DESCRIPTION = Qt.UserRole + 1
|
||||||
|
CUSTOM = Qt.UserRole + 2
|
||||||
|
KEY = Qt.UserRole + 3
|
||||||
|
|
||||||
|
class Customize(QFrame, Ui_Frame):
|
||||||
|
|
||||||
|
def __init__(self, dup_check, parent=None):
|
||||||
|
QFrame.__init__(self, parent)
|
||||||
|
self.setupUi(self)
|
||||||
|
self.setFocusPolicy(Qt.StrongFocus)
|
||||||
|
self.setAutoFillBackground(True)
|
||||||
|
self.custom.toggled.connect(self.custom_toggled)
|
||||||
|
self.custom_toggled(False)
|
||||||
|
self.capture = 0
|
||||||
|
self.key = None
|
||||||
|
self.shorcut1 = self.shortcut2 = None
|
||||||
|
self.dup_check = dup_check
|
||||||
|
for x in (1, 2):
|
||||||
|
button = getattr(self, 'button%d'%x)
|
||||||
|
button.clicked.connect(partial(self.capture_clicked, which=x))
|
||||||
|
button.keyPressEvent = partial(self.key_press_event, which=x)
|
||||||
|
clear = getattr(self, 'clear%d'%x)
|
||||||
|
clear.clicked.connect(partial(self.clear_clicked, which=x))
|
||||||
|
|
||||||
|
def clear_clicked(self, which=0):
|
||||||
|
button = getattr(self, 'button%d'%which)
|
||||||
|
button.setText(_('None'))
|
||||||
|
setattr(self, 'shortcut%d'%which, None)
|
||||||
|
|
||||||
|
def custom_toggled(self, checked):
|
||||||
|
for w in ('1', '2'):
|
||||||
|
for o in ('label', 'button', 'clear'):
|
||||||
|
getattr(self, o+w).setEnabled(checked)
|
||||||
|
|
||||||
|
def capture_clicked(self, which=1):
|
||||||
|
self.capture = which
|
||||||
|
button = getattr(self, 'button%d'%which)
|
||||||
|
button.setText(_('Press a key...'))
|
||||||
|
button.setFocus(Qt.OtherFocusReason)
|
||||||
|
font = QFont()
|
||||||
|
font.setBold(True)
|
||||||
|
button.setFont(font)
|
||||||
|
|
||||||
|
def key_press_event(self, ev, which=0):
|
||||||
|
code = ev.key()
|
||||||
|
if self.capture == 0 or code in (0, Qt.Key_unknown,
|
||||||
|
Qt.Key_Shift, Qt.Key_Control, Qt.Key_Alt, Qt.Key_Meta,
|
||||||
|
Qt.Key_AltGr, Qt.Key_CapsLock, Qt.Key_NumLock, Qt.Key_ScrollLock):
|
||||||
|
return QWidget.keyPressEvent(self, ev)
|
||||||
|
button = getattr(self, 'button%d'%which)
|
||||||
|
font = QFont()
|
||||||
|
button.setFont(font)
|
||||||
|
sequence = QKeySequence(code|int(ev.modifiers()))
|
||||||
|
button.setText(sequence.toString())
|
||||||
|
self.capture = 0
|
||||||
|
setattr(self, 'shortcut%d'%which, sequence)
|
||||||
|
dup_desc = self.dup_check(sequence, self.key)
|
||||||
|
if dup_desc is not None:
|
||||||
|
error_dialog(self, _('Already assigned'),
|
||||||
|
unicode(sequence.toString()) + ' ' +
|
||||||
|
_('already assigned to') + ' ' + dup_desc, show=True)
|
||||||
|
self.clear_clicked(which=which)
|
||||||
|
|
||||||
|
|
||||||
|
class Delegate(QStyledItemDelegate):
|
||||||
|
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
QStyledItemDelegate.__init__(self, parent)
|
||||||
|
self.editing_indices = {}
|
||||||
|
|
||||||
|
def to_doc(self, index):
|
||||||
|
doc = QTextDocument()
|
||||||
|
doc.setHtml(index.data().toString())
|
||||||
|
return doc
|
||||||
|
|
||||||
|
def sizeHint(self, option, index):
|
||||||
|
if index.row() in self.editing_indices:
|
||||||
|
return QSize(200, 200)
|
||||||
|
ans = self.to_doc(index).size().toSize()
|
||||||
|
ans.setHeight(ans.height()+10)
|
||||||
|
return ans
|
||||||
|
|
||||||
|
def paint(self, painter, option, index):
|
||||||
|
painter.save()
|
||||||
|
painter.setClipRect(QRectF(option.rect))
|
||||||
|
if hasattr(QStyle, 'CE_ItemViewItem'):
|
||||||
|
QApplication.style().drawControl(QStyle.CE_ItemViewItem, option, painter)
|
||||||
|
elif option.state & QStyle.State_Selected:
|
||||||
|
painter.fillRect(option.rect, option.palette.highlight())
|
||||||
|
painter.translate(option.rect.topLeft())
|
||||||
|
self.to_doc(index).drawContents(painter)
|
||||||
|
painter.restore()
|
||||||
|
|
||||||
|
def createEditor(self, parent, option, index):
|
||||||
|
w = Customize(index.model().duplicate_check, parent=parent)
|
||||||
|
self.editing_indices[index.row()] = w
|
||||||
|
self.sizeHintChanged.emit(index)
|
||||||
|
return w
|
||||||
|
|
||||||
|
def setEditorData(self, editor, index):
|
||||||
|
defs = index.data(DEFAULTS).toPyObject()
|
||||||
|
defs = _(' or ').join([unicode(x.toString(x.NativeText)) for x in defs])
|
||||||
|
editor.key = unicode(index.data(KEY).toString())
|
||||||
|
editor.default_shortcuts.setText(_('&Default') + ': %s' % defs)
|
||||||
|
editor.default_shortcuts.setChecked(True)
|
||||||
|
editor.header.setText('<b>%s: %s</b>'%(_('Customize shortcuts for'),
|
||||||
|
unicode(index.data(DESCRIPTION).toString())))
|
||||||
|
custom = index.data(CUSTOM).toPyObject()
|
||||||
|
if custom:
|
||||||
|
editor.custom.setChecked(True)
|
||||||
|
for x in (0, 1):
|
||||||
|
button = getattr(editor, 'button%d'%(x+1))
|
||||||
|
if len(custom) > x:
|
||||||
|
seq = QKeySequence(custom[x])
|
||||||
|
button.setText(seq.toString(seq.NativeText))
|
||||||
|
setattr(editor, 'shortcut%d'%(x+1), seq)
|
||||||
|
|
||||||
|
def setModelData(self, editor, model, index):
|
||||||
|
self.editing_indices.pop(index.row())
|
||||||
|
self.sizeHintChanged.emit(index)
|
||||||
|
self.closeEditor.emit(editor, self.NoHint)
|
||||||
|
custom = []
|
||||||
|
if editor.custom.isChecked():
|
||||||
|
for x in ('1', '2'):
|
||||||
|
sc = getattr(editor, 'shortcut'+x)
|
||||||
|
if sc is not None:
|
||||||
|
custom.append(sc)
|
||||||
|
|
||||||
|
model.set_data(index, custom)
|
||||||
|
|
||||||
|
def updateEditorGeometry(self, editor, option, index):
|
||||||
|
editor.setGeometry(option.rect)
|
||||||
|
|
||||||
|
class Shortcuts(QAbstractListModel):
|
||||||
|
|
||||||
|
TEMPLATE = '''
|
||||||
|
<p><b>{0}</b><br>
|
||||||
|
Keys: <code>{1}</code></p>
|
||||||
|
'''
|
||||||
|
|
||||||
|
def __init__(self, shortcuts, config_file_base_name, parent=None):
|
||||||
|
QAbstractListModel.__init__(self, parent)
|
||||||
|
|
||||||
|
self.descriptions = {}
|
||||||
|
for k, v in shortcuts.items():
|
||||||
|
self.descriptions[k] = v[-1]
|
||||||
|
self.keys = {}
|
||||||
|
for k, v in shortcuts.items():
|
||||||
|
self.keys[k] = v[0]
|
||||||
|
self.order = list(shortcuts)
|
||||||
|
self.order.sort(cmp=lambda x,y : cmp(self.descriptions[x],
|
||||||
|
self.descriptions[y]))
|
||||||
|
self.sequences = {}
|
||||||
|
for k, v in self.keys.items():
|
||||||
|
self.sequences[k] = [QKeySequence(x) for x in v]
|
||||||
|
|
||||||
|
self.custom = XMLConfig(config_file_base_name)
|
||||||
|
|
||||||
|
def rowCount(self, parent):
|
||||||
|
return len(self.order)
|
||||||
|
|
||||||
|
def get_sequences(self, key):
|
||||||
|
custom = self.custom.get(key, [])
|
||||||
|
if custom:
|
||||||
|
return [QKeySequence(x) for x in custom]
|
||||||
|
return self.sequences[key]
|
||||||
|
|
||||||
|
def get_match(self, event_or_sequence, ignore=tuple()):
|
||||||
|
q = event_or_sequence
|
||||||
|
if isinstance(q, QKeyEvent):
|
||||||
|
q = QKeySequence(q.key()|int(q.modifiers()))
|
||||||
|
for key in self.order:
|
||||||
|
if key not in ignore:
|
||||||
|
for seq in self.get_sequences(key):
|
||||||
|
if seq.matches(q) == QKeySequence.ExactMatch:
|
||||||
|
return key
|
||||||
|
return None
|
||||||
|
|
||||||
|
def duplicate_check(self, seq, ignore):
|
||||||
|
key = self.get_match(seq, ignore=[ignore])
|
||||||
|
if key is not None:
|
||||||
|
return self.descriptions[key]
|
||||||
|
|
||||||
|
def get_shortcuts(self, key):
|
||||||
|
return [unicode(x.toString(x.NativeText)) for x in
|
||||||
|
self.get_sequences(key)]
|
||||||
|
|
||||||
|
|
||||||
|
def data(self, index, role):
|
||||||
|
row = index.row()
|
||||||
|
if row < 0 or row >= len(self.order):
|
||||||
|
return NONE
|
||||||
|
key = self.order[row]
|
||||||
|
if role == Qt.DisplayRole:
|
||||||
|
return QVariant(self.TEMPLATE.format(self.descriptions[key],
|
||||||
|
_(' or ').join(self.get_shortcuts(key))))
|
||||||
|
if role == Qt.ToolTipRole:
|
||||||
|
return QVariant(_('Double click to change'))
|
||||||
|
if role == DEFAULTS:
|
||||||
|
return QVariant(self.sequences[key])
|
||||||
|
if role == DESCRIPTION:
|
||||||
|
return QVariant(self.descriptions[key])
|
||||||
|
if role == CUSTOM:
|
||||||
|
if key in self.custom:
|
||||||
|
return QVariant(self.custom[key])
|
||||||
|
else:
|
||||||
|
return QVariant([])
|
||||||
|
if role == KEY:
|
||||||
|
return QVariant(key)
|
||||||
|
return NONE
|
||||||
|
|
||||||
|
def set_data(self, index, custom):
|
||||||
|
key = self.order[index.row()]
|
||||||
|
if custom:
|
||||||
|
self.custom[key] = [unicode(x.toString()) for x in custom]
|
||||||
|
elif key in self.custom:
|
||||||
|
del self.custom[key]
|
||||||
|
|
||||||
|
|
||||||
|
def flags(self, index):
|
||||||
|
if not index.isValid():
|
||||||
|
return Qt.ItemIsEnabled
|
||||||
|
return QAbstractListModel.flags(self, index) | Qt.ItemIsEditable
|
||||||
|
|
||||||
|
class ShortcutConfig(QWidget):
|
||||||
|
|
||||||
|
def __init__(self, model, parent=None):
|
||||||
|
QWidget.__init__(self, parent)
|
||||||
|
self._layout = QHBoxLayout()
|
||||||
|
self.setLayout(self._layout)
|
||||||
|
self.view = QListView(self)
|
||||||
|
self._layout.addWidget(self.view)
|
||||||
|
self.view.setModel(model)
|
||||||
|
self.delegate = Delegate()
|
||||||
|
self.view.setItemDelegate(self.delegate)
|
||||||
|
self.delegate.sizeHintChanged.connect(self.view.scrollTo)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
from calibre.gui2 import is_ok_to_use_qt
|
||||||
|
from calibre.gui2.viewer.keys import SHORTCUTS
|
||||||
|
is_ok_to_use_qt()
|
||||||
|
model = Shortcuts(SHORTCUTS, 'shortcuts/viewer')
|
||||||
|
conf = ShortcutConfig(model)
|
||||||
|
conf.resize(400, 500)
|
||||||
|
conf.show()
|
||||||
|
QApplication.instance().exec_()
|
135
src/calibre/gui2/shortcuts.ui
Normal file
135
src/calibre/gui2/shortcuts.ui
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>Frame</class>
|
||||||
|
<widget class="QFrame" name="Frame">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>400</width>
|
||||||
|
<height>170</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Frame</string>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::StyledPanel</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="1" column="0" colspan="2">
|
||||||
|
<widget class="QRadioButton" name="default_shortcuts">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Default</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0" colspan="2">
|
||||||
|
<widget class="QRadioButton" name="custom">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Custom</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0" colspan="2">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>25</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label1">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Shortcut:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>button1</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="button1">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Click to change</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>None</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="clear1">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Clear</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../../resources/images.qrc">
|
||||||
|
<normaloff>:/images/clear_left.svg</normaloff>:/images/clear_left.svg</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0" colspan="2">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>25</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label2">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Alternate shortcut:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>button1</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="button2">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Click to change</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>None</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="clear2">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Clear</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../../resources/images.qrc">
|
||||||
|
<normaloff>:/images/clear_left.svg</normaloff>:/images/clear_left.svg</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0" colspan="2">
|
||||||
|
<widget class="QLabel" name="header">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources>
|
||||||
|
<include location="../../../resources/images.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
@ -18,203 +18,6 @@
|
|||||||
<normaloff>:/images/config.svg</normaloff>:/images/config.svg</iconset>
|
<normaloff>:/images/config.svg</normaloff>:/images/config.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_4">
|
<layout class="QGridLayout" name="gridLayout_4">
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QGroupBox" name="groupBox">
|
|
||||||
<property name="title">
|
|
||||||
<string>&Font options</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QGridLayout" name="gridLayout_3">
|
|
||||||
<item row="0" column="0">
|
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Se&rif family:</string>
|
|
||||||
</property>
|
|
||||||
<property name="buddy">
|
|
||||||
<cstring>serif_family</cstring>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QFontComboBox" name="serif_family"/>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QLabel" name="label_2">
|
|
||||||
<property name="text">
|
|
||||||
<string>&Sans family:</string>
|
|
||||||
</property>
|
|
||||||
<property name="buddy">
|
|
||||||
<cstring>sans_family</cstring>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QFontComboBox" name="sans_family"/>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QLabel" name="label_3">
|
|
||||||
<property name="text">
|
|
||||||
<string>&Monospace family:</string>
|
|
||||||
</property>
|
|
||||||
<property name="buddy">
|
|
||||||
<cstring>mono_family</cstring>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="QFontComboBox" name="mono_family"/>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="label_4">
|
|
||||||
<property name="text">
|
|
||||||
<string>&Default font size:</string>
|
|
||||||
</property>
|
|
||||||
<property name="buddy">
|
|
||||||
<cstring>default_font_size</cstring>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QSpinBox" name="default_font_size">
|
|
||||||
<property name="suffix">
|
|
||||||
<string> px</string>
|
|
||||||
</property>
|
|
||||||
<property name="minimum">
|
|
||||||
<number>8</number>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>40</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QLabel" name="label_5">
|
|
||||||
<property name="text">
|
|
||||||
<string>Monospace &font size:</string>
|
|
||||||
</property>
|
|
||||||
<property name="buddy">
|
|
||||||
<cstring>mono_font_size</cstring>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QSpinBox" name="mono_font_size">
|
|
||||||
<property name="suffix">
|
|
||||||
<string> px</string>
|
|
||||||
</property>
|
|
||||||
<property name="minimum">
|
|
||||||
<number>8</number>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>50</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QLabel" name="label_6">
|
|
||||||
<property name="text">
|
|
||||||
<string>S&tandard font:</string>
|
|
||||||
</property>
|
|
||||||
<property name="buddy">
|
|
||||||
<cstring>standard_font</cstring>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="QComboBox" name="standard_font">
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Serif</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Sans-serif</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Monospace</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="6" column="0" colspan="2">
|
|
||||||
<widget class="QCheckBox" name="opt_remember_window_size">
|
|
||||||
<property name="text">
|
|
||||||
<string>Remember last used &window size</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="1">
|
|
||||||
<widget class="QSpinBox" name="max_view_width">
|
|
||||||
<property name="suffix">
|
|
||||||
<string> px</string>
|
|
||||||
</property>
|
|
||||||
<property name="minimum">
|
|
||||||
<number>100</number>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>10000</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0">
|
|
||||||
<widget class="QLabel" name="label_7">
|
|
||||||
<property name="text">
|
|
||||||
<string>Maximum &view width:</string>
|
|
||||||
</property>
|
|
||||||
<property name="buddy">
|
|
||||||
<cstring>max_view_width</cstring>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="0" colspan="2">
|
|
||||||
<widget class="QCheckBox" name="hyphenate">
|
|
||||||
<property name="text">
|
|
||||||
<string>H&yphenate (break line in the middle of large words)</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="1">
|
|
||||||
<widget class="QComboBox" name="hyphenate_default_lang">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>The default language to use for hyphenation rules. If the book does not specify a language, this will be used.</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="0">
|
|
||||||
<widget class="QLabel" name="label_8">
|
|
||||||
<property name="text">
|
|
||||||
<string>Default &language for hyphenation:</string>
|
|
||||||
</property>
|
|
||||||
<property name="buddy">
|
|
||||||
<cstring>hyphenate_default_lang</cstring>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0">
|
|
||||||
<widget class="QGroupBox" name="groupBox_2">
|
|
||||||
<property name="title">
|
|
||||||
<string>&User stylesheet</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QGridLayout" name="gridLayout_5">
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QPlainTextEdit" name="css"/>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
@ -225,6 +28,234 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QTabWidget" name="tabs">
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="tab">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>&General</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>&Font options</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_3">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Se&rif family:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>serif_family</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QFontComboBox" name="serif_family"/>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Sans family:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>sans_family</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QFontComboBox" name="sans_family"/>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Monospace family:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>mono_family</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QFontComboBox" name="mono_family"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Default font size:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>default_font_size</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QSpinBox" name="default_font_size">
|
||||||
|
<property name="suffix">
|
||||||
|
<string> px</string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>8</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>40</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_5">
|
||||||
|
<property name="text">
|
||||||
|
<string>Monospace &font size:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>mono_font_size</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QSpinBox" name="mono_font_size">
|
||||||
|
<property name="suffix">
|
||||||
|
<string> px</string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>8</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>50</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label_6">
|
||||||
|
<property name="text">
|
||||||
|
<string>S&tandard font:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>standard_font</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QComboBox" name="standard_font">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Serif</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Sans-serif</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Monospace</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="0" colspan="2">
|
||||||
|
<widget class="QCheckBox" name="opt_remember_window_size">
|
||||||
|
<property name="text">
|
||||||
|
<string>Remember last used &window size</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QSpinBox" name="max_view_width">
|
||||||
|
<property name="suffix">
|
||||||
|
<string> px</string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>100</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>10000</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="label_7">
|
||||||
|
<property name="text">
|
||||||
|
<string>Maximum &view width:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>max_view_width</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0" colspan="2">
|
||||||
|
<widget class="QCheckBox" name="hyphenate">
|
||||||
|
<property name="text">
|
||||||
|
<string>H&yphenate (break line in the middle of large words)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="1">
|
||||||
|
<widget class="QComboBox" name="hyphenate_default_lang">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>The default language to use for hyphenation rules. If the book does not specify a language, this will be used.</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<widget class="QLabel" name="label_8">
|
||||||
|
<property name="text">
|
||||||
|
<string>Default &language for hyphenation:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>hyphenate_default_lang</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QGroupBox" name="groupBox_2">
|
||||||
|
<property name="title">
|
||||||
|
<string>&User stylesheet</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_5">
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QPlainTextEdit" name="css"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tab_2">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>&Keyboard shortcuts</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_9">
|
||||||
|
<property name="text">
|
||||||
|
<string>Double click to change a keyborad shortcut</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<tabstops>
|
<tabstops>
|
||||||
|
@ -15,9 +15,11 @@ from PyQt4.QtWebKit import QWebPage, QWebView, QWebSettings
|
|||||||
from calibre.utils.config import Config, StringConfig
|
from calibre.utils.config import Config, StringConfig
|
||||||
from calibre.utils.localization import get_language
|
from calibre.utils.localization import get_language
|
||||||
from calibre.gui2.viewer.config_ui import Ui_Dialog
|
from calibre.gui2.viewer.config_ui import Ui_Dialog
|
||||||
|
from calibre.gui2.shortcuts import Shortcuts, ShortcutConfig
|
||||||
from calibre.ptempfile import PersistentTemporaryFile
|
from calibre.ptempfile import PersistentTemporaryFile
|
||||||
from calibre.constants import iswindows
|
from calibre.constants import iswindows
|
||||||
from calibre import prints, guess_type
|
from calibre import prints, guess_type
|
||||||
|
from calibre.gui2.viewer.keys import SHORTCUTS
|
||||||
|
|
||||||
bookmarks = referencing = hyphenation = jquery = jquery_scrollTo = hyphenator = None
|
bookmarks = referencing = hyphenation = jquery = jquery_scrollTo = hyphenator = None
|
||||||
|
|
||||||
@ -73,8 +75,8 @@ class PythonJS(QObject):
|
|||||||
|
|
||||||
class ConfigDialog(QDialog, Ui_Dialog):
|
class ConfigDialog(QDialog, Ui_Dialog):
|
||||||
|
|
||||||
def __init__(self, *args):
|
def __init__(self, shortcuts, parent=None):
|
||||||
QDialog.__init__(self, *args)
|
QDialog.__init__(self, parent)
|
||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
|
|
||||||
opts = config().parse()
|
opts = config().parse()
|
||||||
@ -104,6 +106,10 @@ class ConfigDialog(QDialog, Ui_Dialog):
|
|||||||
self.hyphenate_default_lang.setCurrentIndex(idx)
|
self.hyphenate_default_lang.setCurrentIndex(idx)
|
||||||
self.hyphenate.setChecked(opts.hyphenate)
|
self.hyphenate.setChecked(opts.hyphenate)
|
||||||
self.hyphenate_default_lang.setEnabled(opts.hyphenate)
|
self.hyphenate_default_lang.setEnabled(opts.hyphenate)
|
||||||
|
self.shortcuts = shortcuts
|
||||||
|
self.shortcut_config = ShortcutConfig(shortcuts, parent=self)
|
||||||
|
p = self.tabs.widget(1)
|
||||||
|
p.layout().addWidget(self.shortcut_config)
|
||||||
|
|
||||||
|
|
||||||
def accept(self, *args):
|
def accept(self, *args):
|
||||||
@ -139,15 +145,15 @@ class Document(QWebPage):
|
|||||||
settings.setFontFamily(QWebSettings.FixedFont, opts.mono_family)
|
settings.setFontFamily(QWebSettings.FixedFont, opts.mono_family)
|
||||||
|
|
||||||
def do_config(self, parent=None):
|
def do_config(self, parent=None):
|
||||||
d = ConfigDialog(parent)
|
d = ConfigDialog(self.shortcuts, parent)
|
||||||
if d.exec_() == QDialog.Accepted:
|
if d.exec_() == QDialog.Accepted:
|
||||||
self.set_font_settings()
|
self.set_font_settings()
|
||||||
self.set_user_stylesheet()
|
self.set_user_stylesheet()
|
||||||
self.misc_config()
|
self.misc_config()
|
||||||
self.triggerAction(QWebPage.Reload)
|
self.triggerAction(QWebPage.Reload)
|
||||||
|
|
||||||
def __init__(self, *args):
|
def __init__(self, shortcuts, parent=None):
|
||||||
QWebPage.__init__(self, *args)
|
QWebPage.__init__(self, parent)
|
||||||
self.setObjectName("py_bridge")
|
self.setObjectName("py_bridge")
|
||||||
self.debug_javascript = False
|
self.debug_javascript = False
|
||||||
self.current_language = None
|
self.current_language = None
|
||||||
@ -155,6 +161,7 @@ class Document(QWebPage):
|
|||||||
|
|
||||||
self.setLinkDelegationPolicy(self.DelegateAllLinks)
|
self.setLinkDelegationPolicy(self.DelegateAllLinks)
|
||||||
self.scroll_marks = []
|
self.scroll_marks = []
|
||||||
|
self.shortcuts = shortcuts
|
||||||
pal = self.palette()
|
pal = self.palette()
|
||||||
pal.setBrush(QPalette.Background, QColor(0xee, 0xee, 0xee))
|
pal.setBrush(QPalette.Background, QColor(0xee, 0xee, 0xee))
|
||||||
self.setPalette(pal)
|
self.setPalette(pal)
|
||||||
@ -366,13 +373,14 @@ class DocumentView(QWebView):
|
|||||||
def __init__(self, *args):
|
def __init__(self, *args):
|
||||||
QWebView.__init__(self, *args)
|
QWebView.__init__(self, *args)
|
||||||
self.debug_javascript = False
|
self.debug_javascript = False
|
||||||
|
self.shortcuts = Shortcuts(SHORTCUTS, 'shortcuts/viewer')
|
||||||
self.self_closing_pat = re.compile(r'<([a-z]+)\s+([^>]+)/>',
|
self.self_closing_pat = re.compile(r'<([a-z]+)\s+([^>]+)/>',
|
||||||
re.IGNORECASE)
|
re.IGNORECASE)
|
||||||
self.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding))
|
self.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding))
|
||||||
self._size_hint = QSize(510, 680)
|
self._size_hint = QSize(510, 680)
|
||||||
self.initial_pos = 0.0
|
self.initial_pos = 0.0
|
||||||
self.to_bottom = False
|
self.to_bottom = False
|
||||||
self.document = Document(self)
|
self.document = Document(self.shortcuts, parent=self)
|
||||||
self.setPage(self.document)
|
self.setPage(self.document)
|
||||||
self.manager = None
|
self.manager = None
|
||||||
self._reference_mode = False
|
self._reference_mode = False
|
||||||
@ -407,6 +415,7 @@ class DocumentView(QWebView):
|
|||||||
self.document.do_config(parent)
|
self.document.do_config(parent)
|
||||||
if self.manager is not None:
|
if self.manager is not None:
|
||||||
self.manager.set_max_width()
|
self.manager.set_max_width()
|
||||||
|
self.setFocus(Qt.OtherFocusReason)
|
||||||
|
|
||||||
def bookmark(self):
|
def bookmark(self):
|
||||||
return self.document.bookmark()
|
return self.document.bookmark()
|
||||||
@ -663,30 +672,30 @@ class DocumentView(QWebView):
|
|||||||
return ret
|
return ret
|
||||||
|
|
||||||
def keyPressEvent(self, event):
|
def keyPressEvent(self, event):
|
||||||
key = event.key()
|
key = self.shortcuts.get_match(event)
|
||||||
if key in [Qt.Key_PageDown, Qt.Key_Space, Qt.Key_Down]:
|
if key == 'Next Page':
|
||||||
self.next_page()
|
self.next_page()
|
||||||
elif key in [Qt.Key_PageUp, Qt.Key_Backspace, Qt.Key_Up]:
|
elif key == 'Previous Page':
|
||||||
self.previous_page()
|
self.previous_page()
|
||||||
elif key in [Qt.Key_Home]:
|
elif key == 'Section Top':
|
||||||
if event.modifiers() & Qt.ControlModifier:
|
if event.modifiers() & Qt.ControlModifier:
|
||||||
if self.manager is not None:
|
if self.manager is not None:
|
||||||
self.manager.goto_start()
|
self.manager.goto_start()
|
||||||
else:
|
else:
|
||||||
self.scroll_to(0)
|
self.scroll_to(0)
|
||||||
elif key in [Qt.Key_End]:
|
elif key == 'Section Bottom':
|
||||||
if event.modifiers() & Qt.ControlModifier:
|
if event.modifiers() & Qt.ControlModifier:
|
||||||
if self.manager is not None:
|
if self.manager is not None:
|
||||||
self.manager.goto_end()
|
self.manager.goto_end()
|
||||||
else:
|
else:
|
||||||
self.scroll_to(1)
|
self.scroll_to(1)
|
||||||
elif key in [Qt.Key_J]:
|
elif key == 'Down':
|
||||||
self.scroll_by(y=15)
|
self.scroll_by(y=15)
|
||||||
elif key in [Qt.Key_K]:
|
elif key == 'Up':
|
||||||
self.scroll_by(y=-15)
|
self.scroll_by(y=-15)
|
||||||
elif key in [Qt.Key_H]:
|
elif key == 'Left':
|
||||||
self.scroll_by(x=-15)
|
self.scroll_by(x=-15)
|
||||||
elif key in [Qt.Key_L]:
|
elif key == 'Right':
|
||||||
self.scroll_by(x=15)
|
self.scroll_by(x=15)
|
||||||
else:
|
else:
|
||||||
return QWebView.keyPressEvent(self, event)
|
return QWebView.keyPressEvent(self, event)
|
||||||
|
47
src/calibre/gui2/viewer/keys.py
Normal file
47
src/calibre/gui2/viewer/keys.py
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#!/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'
|
||||||
|
|
||||||
|
|
||||||
|
SHORTCUTS = {
|
||||||
|
'Next Page' : (['PgDown', 'Space'],
|
||||||
|
_('Scroll to the next page')),
|
||||||
|
|
||||||
|
'Previous Page' : (['PgUp', 'Backspace'],
|
||||||
|
_('Scroll to the previous page')),
|
||||||
|
|
||||||
|
'Next Section' : (['Ctrl+PgDown', 'Ctrl+Down'],
|
||||||
|
_('Scroll to the next section')),
|
||||||
|
|
||||||
|
'Previous Section' : (['Ctrl+PgUp', 'Ctrl+Up'],
|
||||||
|
_('Scroll to the previous section')),
|
||||||
|
|
||||||
|
'Section Bottom' : (['End'],
|
||||||
|
_('Scroll to the bottom of the section')),
|
||||||
|
|
||||||
|
'Section Top' : (['Home'],
|
||||||
|
_('Scroll to the top of the section')),
|
||||||
|
|
||||||
|
'Document Bottom' : (['Ctrl+End'],
|
||||||
|
_('Scroll to the end of the document')),
|
||||||
|
|
||||||
|
'Document Top' : (['Ctrl+Home'],
|
||||||
|
_('Scroll to the start of the document')),
|
||||||
|
|
||||||
|
'Down' : (['J', 'Down'],
|
||||||
|
_('Scroll down')),
|
||||||
|
|
||||||
|
'Up' : (['K', 'Up'],
|
||||||
|
_('Scroll up')),
|
||||||
|
|
||||||
|
'Left' : (['H', 'Left'],
|
||||||
|
_('Scroll left')),
|
||||||
|
|
||||||
|
'Right' : (['L', 'Right'],
|
||||||
|
_('Scroll right')),
|
||||||
|
|
||||||
|
}
|
@ -264,7 +264,7 @@ Why does |app| show only some of my fonts on OS X?
|
|||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|app| embeds fonts in ebook files it creates. E-book files support embedding only TrueType (.ttf) fonts. Most fonts on OS X systems are in .dfont format, thus they cannot be embedded. |app| shows only TrueType fonts founf on your system. You can obtain many TrueType fonts on the web. Simply download the .ttf files and add them to the Library/Fonts directory in your home directory.
|
|app| embeds fonts in ebook files it creates. E-book files support embedding only TrueType (.ttf) fonts. Most fonts on OS X systems are in .dfont format, thus they cannot be embedded. |app| shows only TrueType fonts founf on your system. You can obtain many TrueType fonts on the web. Simply download the .ttf files and add them to the Library/Fonts directory in your home directory.
|
||||||
|
|
||||||
The graphical user interface of |app| is not starting on Windows?
|
|app| is not starting on Windows?
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
There can be several causes for this:
|
There can be several causes for this:
|
||||||
|
|
||||||
@ -279,8 +279,20 @@ If it still wont launch, start a command prompt (press the windows key and R; th
|
|||||||
calibre-debug -g
|
calibre-debug -g
|
||||||
|
|
||||||
Post any output you see in a help message on the `Forum <http://www.mobileread.com/forums/forumdisplay.php?f=166>`_.
|
Post any output you see in a help message on the `Forum <http://www.mobileread.com/forums/forumdisplay.php?f=166>`_.
|
||||||
|
|
||||||
My antivirus programs claims |app| is a virus/trojan?
|
|app| is not starting on OS X?
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
You can obtain debug output about why |app| is not starting by running `Console.app`. Debug output will
|
||||||
|
be printed to it. If the debug output contains a line that looks like::
|
||||||
|
|
||||||
|
Qt: internal: -108: Error ATSUMeasureTextImage text/qfontengine_mac.mm
|
||||||
|
|
||||||
|
then the problem is a corrupted font cache. You can clear the cache by following these
|
||||||
|
`instructions <http://www.macworld.com/article/139383/2009/03/fontcacheclear.html>`_.
|
||||||
|
|
||||||
|
|
||||||
|
My antivirus program claims |app| is a virus/trojan?
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
Your antivirus program is wrong. |app| is a completely open source product. You can actually browse the source code yourself (or hire someone to do it for you) to verify that it is not a virus. Please report the false identification to whatever company you buy your antivirus software from. If the antivirus program is preventing you from downloading/installing |app|, disable it temporarily, install |app| and then re-enable it.
|
Your antivirus program is wrong. |app| is a completely open source product. You can actually browse the source code yourself (or hire someone to do it for you) to verify that it is not a virus. Please report the false identification to whatever company you buy your antivirus software from. If the antivirus program is preventing you from downloading/installing |app|, disable it temporarily, install |app| and then re-enable it.
|
||||||
|
|
||||||
|
@ -608,6 +608,10 @@ class XMLConfig(dict):
|
|||||||
def set(self, key, val):
|
def set(self, key, val):
|
||||||
self.__setitem__(key, val)
|
self.__setitem__(key, val)
|
||||||
|
|
||||||
|
def __delitem__(self, key):
|
||||||
|
dict.__delitem__(self, key)
|
||||||
|
self.commit()
|
||||||
|
|
||||||
def commit(self):
|
def commit(self):
|
||||||
if hasattr(self, 'file_path') and self.file_path:
|
if hasattr(self, 'file_path') and self.file_path:
|
||||||
dpath = os.path.dirname(self.file_path)
|
dpath = os.path.dirname(self.file_path)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user