mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
remove unused code
This commit is contained in:
parent
7cb53c9c96
commit
9c9e903e83
@ -1,320 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
|
||||||
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
|
||||||
__docformat__ = 'restructuredtext en'
|
|
||||||
|
|
||||||
from functools import partial
|
|
||||||
|
|
||||||
from qt.core import (
|
|
||||||
QAbstractListModel, Qt, QKeySequence, QListView, QVBoxLayout, QLabel, QAbstractItemView,
|
|
||||||
QHBoxLayout, QWidget, QApplication, QStyledItemDelegate, QStyle, QIcon, QAbstractItemDelegate,
|
|
||||||
QTextDocument, QRectF, QFrame, QSize, QFont, QKeyEvent, QRadioButton, QPushButton, QToolButton, QEvent
|
|
||||||
)
|
|
||||||
|
|
||||||
from calibre.gui2 import error_dialog
|
|
||||||
from calibre.utils.config import XMLConfig
|
|
||||||
from calibre.utils.icu import sort_key
|
|
||||||
|
|
||||||
DEFAULTS = Qt.ItemDataRole.UserRole
|
|
||||||
DESCRIPTION = Qt.ItemDataRole.UserRole + 1
|
|
||||||
CUSTOM = Qt.ItemDataRole.UserRole + 2
|
|
||||||
KEY = Qt.ItemDataRole.UserRole + 3
|
|
||||||
|
|
||||||
|
|
||||||
class Customize(QFrame):
|
|
||||||
|
|
||||||
def __init__(self, index, dup_check, parent=None):
|
|
||||||
QFrame.__init__(self, parent)
|
|
||||||
self.setFrameShape(QFrame.Shape.StyledPanel)
|
|
||||||
self.setFrameShadow(QFrame.Shadow.Raised)
|
|
||||||
self.setFocusPolicy(Qt.FocusPolicy.StrongFocus)
|
|
||||||
self.setAutoFillBackground(True)
|
|
||||||
self.l = l = QVBoxLayout(self)
|
|
||||||
self.header = la = QLabel(self)
|
|
||||||
la.setWordWrap(True)
|
|
||||||
l.addWidget(la)
|
|
||||||
self.default_shortcuts = QRadioButton(_("&Default"), self)
|
|
||||||
self.custom = QRadioButton(_("&Custom"), self)
|
|
||||||
self.custom.toggled.connect(self.custom_toggled)
|
|
||||||
l.addWidget(self.default_shortcuts)
|
|
||||||
l.addWidget(self.custom)
|
|
||||||
for which in 1, 2:
|
|
||||||
la = QLabel(_("&Shortcut:") if which == 1 else _("&Alternate shortcut:"))
|
|
||||||
setattr(self, 'label%d' % which, la)
|
|
||||||
h = QHBoxLayout()
|
|
||||||
l.addLayout(h)
|
|
||||||
h.setContentsMargins(25, -1, -1, -1)
|
|
||||||
h.addWidget(la)
|
|
||||||
b = QPushButton(_("Click to change"), self)
|
|
||||||
la.setBuddy(b)
|
|
||||||
b.clicked.connect(partial(self.capture_clicked, which=which))
|
|
||||||
b.installEventFilter(self)
|
|
||||||
setattr(self, 'button%d' % which, b)
|
|
||||||
h.addWidget(b)
|
|
||||||
c = QToolButton(self)
|
|
||||||
c.setIcon(QIcon(I('clear_left.png')))
|
|
||||||
c.setToolTip(_('Clear'))
|
|
||||||
h.addWidget(c)
|
|
||||||
c.clicked.connect(partial(self.clear_clicked, which=which))
|
|
||||||
setattr(self, 'clear%d' % which, c)
|
|
||||||
self.data_model = index.model()
|
|
||||||
self.capture = 0
|
|
||||||
self.key = None
|
|
||||||
self.shorcut1 = self.shortcut2 = None
|
|
||||||
self.dup_check = dup_check
|
|
||||||
self.custom_toggled(False)
|
|
||||||
|
|
||||||
def eventFilter(self, obj, event):
|
|
||||||
if self.capture == 0 or obj not in (self.button1, self.button2):
|
|
||||||
return QFrame.eventFilter(self, obj, event)
|
|
||||||
t = event.type()
|
|
||||||
if t == QEvent.Type.ShortcutOverride:
|
|
||||||
event.accept()
|
|
||||||
return True
|
|
||||||
if t == QEvent.Type.KeyPress:
|
|
||||||
self.key_press_event(event, 1 if obj is self.button1 else 2)
|
|
||||||
return True
|
|
||||||
return QFrame.eventFilter(self, obj, event)
|
|
||||||
|
|
||||||
def clear_button(self, which):
|
|
||||||
b = getattr(self, 'button%d' % which)
|
|
||||||
s = getattr(self, 'shortcut%d' % which, None)
|
|
||||||
b.setText(_('None') if s is None else s.toString(QKeySequence.SequenceFormat.NativeText))
|
|
||||||
b.setFont(QFont())
|
|
||||||
|
|
||||||
def clear_clicked(self, which=0):
|
|
||||||
setattr(self, 'shortcut%d'%which, None)
|
|
||||||
self.clear_button(which)
|
|
||||||
|
|
||||||
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
|
|
||||||
for w in 1, 2:
|
|
||||||
self.clear_button(w)
|
|
||||||
button = getattr(self, 'button%d'%which)
|
|
||||||
button.setText(_('Press a key...'))
|
|
||||||
button.setFocus(Qt.FocusReason.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.Key_unknown,
|
|
||||||
Qt.Key.Key_Shift, Qt.Key.Key_Control, Qt.Key.Key_Alt, Qt.Key.Key_Meta,
|
|
||||||
Qt.Key.Key_AltGr, Qt.Key.Key_CapsLock, Qt.Key.Key_NumLock, Qt.Key.Key_ScrollLock):
|
|
||||||
return QWidget.keyPressEvent(self, ev)
|
|
||||||
sequence = QKeySequence(code|(int(ev.modifiers()) & (~Qt.KeyboardModifier.KeypadModifier)))
|
|
||||||
setattr(self, 'shortcut%d'%which, sequence)
|
|
||||||
self.clear_button(which)
|
|
||||||
self.capture = 0
|
|
||||||
dup_desc = self.dup_check(sequence, self.key)
|
|
||||||
if dup_desc is not None:
|
|
||||||
error_dialog(self, _('Already assigned'),
|
|
||||||
str(sequence.toString(QKeySequence.SequenceFormat.NativeText)) + ' ' +
|
|
||||||
_('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 = {}
|
|
||||||
self.closeEditor.connect(self.editing_done)
|
|
||||||
|
|
||||||
def to_doc(self, index):
|
|
||||||
doc = QTextDocument()
|
|
||||||
doc.setHtml(index.data())
|
|
||||||
return doc
|
|
||||||
|
|
||||||
def editing_done(self, editor, hint):
|
|
||||||
remove = None
|
|
||||||
for row, w in self.editing_indices.items():
|
|
||||||
remove = (row, w.data_model.index(row))
|
|
||||||
if remove is not None:
|
|
||||||
self.editing_indices.pop(remove[0])
|
|
||||||
self.sizeHintChanged.emit(remove[1])
|
|
||||||
|
|
||||||
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.ControlElement.CE_ItemViewItem, option, painter)
|
|
||||||
elif option.state & QStyle.StateFlag.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, 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)
|
|
||||||
defs = _(' or ').join([str(x.toString(QKeySequence.SequenceFormat.NativeText)) for x in defs])
|
|
||||||
editor.key = str(index.data(KEY))
|
|
||||||
editor.default_shortcuts.setText(_('&Default') + ': %s' % defs)
|
|
||||||
editor.default_shortcuts.setChecked(True)
|
|
||||||
editor.header.setText('<b>%s: %s</b>'%(_('Customize shortcuts for'),
|
|
||||||
str(index.data(DESCRIPTION))))
|
|
||||||
custom = index.data(CUSTOM)
|
|
||||||
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(QKeySequence.SequenceFormat.NativeText))
|
|
||||||
setattr(editor, 'shortcut%d'%(x+1), seq)
|
|
||||||
|
|
||||||
def setModelData(self, editor, model, index):
|
|
||||||
self.closeEditor.emit(editor, QAbstractItemDelegate.EndEditHint.NoHint)
|
|
||||||
custom = []
|
|
||||||
if editor.custom.isChecked():
|
|
||||||
for x in ('1', '2'):
|
|
||||||
sc = getattr(editor, 'shortcut'+x, None)
|
|
||||||
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>
|
|
||||||
{2}: <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(key=lambda x : sort_key(self.descriptions[x]))
|
|
||||||
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()) & (~Qt.KeyboardModifier.KeypadModifier)))
|
|
||||||
for key in self.order:
|
|
||||||
if key not in ignore:
|
|
||||||
for seq in self.get_sequences(key):
|
|
||||||
if seq.matches(q) == QKeySequence.SequenceMatch.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 [str(x.toString(QKeySequence.SequenceFormat.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.ItemDataRole.DisplayRole:
|
|
||||||
return self.TEMPLATE.format(self.descriptions[key],
|
|
||||||
_(' or ').join(self.get_shortcuts(key)), _('Keys'))
|
|
||||||
if role == Qt.ItemDataRole.ToolTipRole:
|
|
||||||
return _('Double click to change')
|
|
||||||
if role == DEFAULTS:
|
|
||||||
return self.sequences[key]
|
|
||||||
if role == DESCRIPTION:
|
|
||||||
return self.descriptions[key]
|
|
||||||
if role == CUSTOM:
|
|
||||||
if key in self.custom:
|
|
||||||
return self.custom[key]
|
|
||||||
else:
|
|
||||||
return []
|
|
||||||
if role == KEY:
|
|
||||||
return key
|
|
||||||
return None
|
|
||||||
|
|
||||||
def set_data(self, index, custom):
|
|
||||||
key = self.order[index.row()]
|
|
||||||
if custom:
|
|
||||||
self.custom[key] = [str(x.toString(QKeySequence.SequenceFormat.PortableText)) for x in custom]
|
|
||||||
elif key in self.custom:
|
|
||||||
del self.custom[key]
|
|
||||||
|
|
||||||
def flags(self, index):
|
|
||||||
if not index.isValid():
|
|
||||||
return Qt.ItemFlag.ItemIsEnabled
|
|
||||||
return QAbstractListModel.flags(self, index) | Qt.ItemFlag.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.scrollTo,
|
|
||||||
type=Qt.ConnectionType.QueuedConnection)
|
|
||||||
|
|
||||||
def scrollTo(self, index):
|
|
||||||
self.view.scrollTo(index, QAbstractItemView.ScrollHint.EnsureVisible)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def is_editing(self):
|
|
||||||
return self.view.state() == QAbstractItemView.State.EditingState
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
app = QApplication([])
|
|
||||||
from calibre.gui2.viewer.keys import SHORTCUTS
|
|
||||||
model = Shortcuts(SHORTCUTS, 'shortcuts/viewer')
|
|
||||||
conf = ShortcutConfig(model)
|
|
||||||
conf.resize(400, 500)
|
|
||||||
conf.show()
|
|
||||||
app.exec()
|
|
Loading…
x
Reference in New Issue
Block a user