mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 10:44:09 -04:00
Add context menu entries to clear metadata edit spinboxes for date and number fields
This commit is contained in:
parent
ecce202556
commit
270b6f403f
@ -8,12 +8,13 @@ __docformat__ = 'restructuredtext en'
|
||||
import sys
|
||||
|
||||
from PyQt5.Qt import (Qt, QApplication, QStyle, QIcon, QDoubleSpinBox, QStyleOptionViewItem,
|
||||
QSpinBox, QStyledItemDelegate, QComboBox, QTextDocument, QSize,
|
||||
QSpinBox, QStyledItemDelegate, QComboBox, QTextDocument, QSize, QMenu, QKeySequence,
|
||||
QAbstractTextDocumentLayout, QFont, QFontInfo, QDate, QDateTimeEdit, QDateTime)
|
||||
|
||||
from calibre.gui2 import UNDEFINED_QDATETIME, error_dialog, rating_font
|
||||
from calibre.constants import iswindows
|
||||
from calibre.gui2.widgets import EnLineEdit
|
||||
from calibre.gui2.widgets2 import populate_standard_spinbox_context_menu
|
||||
from calibre.gui2.complete2 import EditWithComplete
|
||||
from calibre.utils.date import now, format_date, qt_to_dt, is_date_undefined
|
||||
from calibre.utils.config import tweaks
|
||||
@ -33,10 +34,21 @@ class DateTimeEdit(QDateTimeEdit): # {{{
|
||||
self.setCalendarPopup(True)
|
||||
self.setDisplayFormat(format)
|
||||
|
||||
def contextMenuEvent(self, ev):
|
||||
m = QMenu(self)
|
||||
m.addAction(_('Set date to undefined') + '\t' + QKeySequence(Qt.Key_Minus).toString(QKeySequence.NativeText),
|
||||
self.clear_date)
|
||||
m.addSeparator()
|
||||
populate_standard_spinbox_context_menu(self, m)
|
||||
m.popup(ev.globalPos())
|
||||
|
||||
def clear_date(self):
|
||||
self.setDateTime(UNDEFINED_QDATETIME)
|
||||
|
||||
def keyPressEvent(self, ev):
|
||||
if ev.key() == Qt.Key_Minus:
|
||||
ev.accept()
|
||||
self.setDateTime(UNDEFINED_QDATETIME)
|
||||
self.clear_date()
|
||||
elif ev.key() == Qt.Key_Equal:
|
||||
ev.accept()
|
||||
self.setDateTime(QDateTime.currentDateTime())
|
||||
@ -44,20 +56,33 @@ class DateTimeEdit(QDateTimeEdit): # {{{
|
||||
return QDateTimeEdit.keyPressEvent(self, ev)
|
||||
# }}}
|
||||
|
||||
class ClearingSpinBox(QSpinBox): # {{{
|
||||
def keyPressEvent(self, ev):
|
||||
if ev.key() == Qt.Key_Space:
|
||||
self.setValue(-1000000)
|
||||
else:
|
||||
return QSpinBox.keyPressEvent(self, ev)
|
||||
# }}}
|
||||
# Number Editor {{{
|
||||
|
||||
def make_clearing_spinbox(spinbox):
|
||||
|
||||
class SpinBox(spinbox):
|
||||
|
||||
def contextMenuEvent(self, ev):
|
||||
m = QMenu(self)
|
||||
m.addAction(_('Set to undefined') + '\t' + QKeySequence(Qt.Key_Space).toString(QKeySequence.NativeText),
|
||||
self.clear_to_undefined)
|
||||
m.addSeparator()
|
||||
populate_standard_spinbox_context_menu(self, m)
|
||||
m.popup(ev.globalPos())
|
||||
|
||||
def clear_to_undefined(self):
|
||||
self.setValue(self.minimum())
|
||||
|
||||
def keyPressEvent(self, ev):
|
||||
if ev.key() == Qt.Key_Space:
|
||||
self.clear_to_undefined()
|
||||
else:
|
||||
return spinbox.keyPressEvent(self, ev)
|
||||
return SpinBox
|
||||
|
||||
ClearingSpinBox = make_clearing_spinbox(QSpinBox)
|
||||
ClearingDoubleSpinBox = make_clearing_spinbox(QDoubleSpinBox)
|
||||
|
||||
class ClearingDoubleSpinBox(QDoubleSpinBox): # {{{
|
||||
def keyPressEvent(self, ev):
|
||||
if ev.key() == Qt.Key_Space:
|
||||
self.setValue(-1000000.0)
|
||||
else:
|
||||
return QDoubleSpinBox.keyPressEvent(self, ev)
|
||||
# }}}
|
||||
|
||||
class RatingDelegate(QStyledItemDelegate): # {{{
|
||||
@ -145,6 +170,7 @@ class PubDateDelegate(QStyledItemDelegate): # {{{
|
||||
# }}}
|
||||
|
||||
class TextDelegate(QStyledItemDelegate): # {{{
|
||||
|
||||
def __init__(self, parent):
|
||||
'''
|
||||
Delegate for text data. If auto_complete_function needs to return a list
|
||||
@ -179,9 +205,10 @@ class TextDelegate(QStyledItemDelegate): # {{{
|
||||
else:
|
||||
QStyledItemDelegate.setModelData(self, editor, model, index)
|
||||
|
||||
#}}}
|
||||
# }}}
|
||||
|
||||
class CompleteDelegate(QStyledItemDelegate): # {{{
|
||||
|
||||
def __init__(self, parent, sep, items_func_name, space_before_sep=False):
|
||||
QStyledItemDelegate.__init__(self, parent)
|
||||
self.sep = sep
|
||||
@ -239,6 +266,7 @@ class LanguagesDelegate(QStyledItemDelegate): # {{{
|
||||
# }}}
|
||||
|
||||
class CcDateDelegate(QStyledItemDelegate): # {{{
|
||||
|
||||
'''
|
||||
Delegate for custom columns dates. Because this delegate stores the
|
||||
format as an instance variable, a new instance must be created for each
|
||||
@ -278,6 +306,7 @@ class CcDateDelegate(QStyledItemDelegate): # {{{
|
||||
# }}}
|
||||
|
||||
class CcTextDelegate(QStyledItemDelegate): # {{{
|
||||
|
||||
'''
|
||||
Delegate for text data.
|
||||
'''
|
||||
@ -303,6 +332,7 @@ class CcTextDelegate(QStyledItemDelegate): # {{{
|
||||
# }}}
|
||||
|
||||
class CcNumberDelegate(QStyledItemDelegate): # {{{
|
||||
|
||||
'''
|
||||
Delegate for text/int/float data.
|
||||
'''
|
||||
@ -338,6 +368,7 @@ class CcNumberDelegate(QStyledItemDelegate): # {{{
|
||||
# }}}
|
||||
|
||||
class CcEnumDelegate(QStyledItemDelegate): # {{{
|
||||
|
||||
'''
|
||||
Delegate for text/int/float data.
|
||||
'''
|
||||
@ -370,6 +401,7 @@ class CcEnumDelegate(QStyledItemDelegate): # {{{
|
||||
# }}}
|
||||
|
||||
class CcCommentsDelegate(QStyledItemDelegate): # {{{
|
||||
|
||||
'''
|
||||
Delegate for comments data.
|
||||
'''
|
||||
@ -422,6 +454,7 @@ class DelegateCB(QComboBox): # {{{
|
||||
# }}}
|
||||
|
||||
class CcBoolDelegate(QStyledItemDelegate): # {{{
|
||||
|
||||
def __init__(self, parent):
|
||||
'''
|
||||
Delegate for custom_column bool data.
|
||||
@ -470,6 +503,7 @@ class CcBoolDelegate(QStyledItemDelegate): # {{{
|
||||
# }}}
|
||||
|
||||
class CcTemplateDelegate(QStyledItemDelegate): # {{{
|
||||
|
||||
def __init__(self, parent):
|
||||
'''
|
||||
Delegate for custom_column bool data.
|
||||
@ -506,5 +540,3 @@ class CcTemplateDelegate(QStyledItemDelegate): # {{{
|
||||
|
||||
|
||||
# }}}
|
||||
|
||||
|
||||
|
@ -17,6 +17,7 @@ from PyQt5.Qt import (
|
||||
QUndoStack)
|
||||
|
||||
from calibre.gui2.widgets import EnLineEdit, FormatList as _FormatList, ImageView
|
||||
from calibre.gui2.widgets2 import access_key, populate_standard_spinbox_context_menu
|
||||
from calibre.utils.icu import sort_key
|
||||
from calibre.utils.config import tweaks, prefs
|
||||
from calibre.ebooks.metadata import (
|
||||
@ -109,11 +110,6 @@ class ToMetadataMixin(object):
|
||||
def make_undoable(spinbox):
|
||||
'Add a proper undo/redo capability to spinbox which must be a sub-class of QAbstractSpinBox'
|
||||
|
||||
def access_key(k):
|
||||
if QKeySequence.keyBindings(k):
|
||||
return '\t' + QKeySequence(k).toString(QKeySequence.NativeText)
|
||||
return ''
|
||||
|
||||
class UndoCommand(QUndoCommand):
|
||||
|
||||
def __init__(self, widget, val):
|
||||
@ -157,20 +153,13 @@ def make_undoable(spinbox):
|
||||
|
||||
def contextMenuEvent(self, ev):
|
||||
m = QMenu(self)
|
||||
if hasattr(self, 'setDateTime'):
|
||||
m.addAction(_('Set date to undefined') + '\t' + QKeySequence(Qt.Key_Minus).toString(QKeySequence.NativeText),
|
||||
lambda : self.setDateTime(self.minimumDateTime()))
|
||||
m.addAction(_('&Undo') + access_key(QKeySequence.Undo), self.undo).setEnabled(self.undo_stack.canUndo())
|
||||
m.addAction(_('&Redo') + access_key(QKeySequence.Redo), self.redo).setEnabled(self.undo_stack.canRedo())
|
||||
m.addSeparator()
|
||||
le = self.lineEdit()
|
||||
m.addAction(_('Cu&t') + access_key(QKeySequence.Cut), le.cut).setEnabled(not le.isReadOnly() and le.hasSelectedText())
|
||||
m.addAction(_('&Copy') + access_key(QKeySequence.Copy), le.copy).setEnabled(le.hasSelectedText())
|
||||
m.addAction(_('&Paste') + access_key(QKeySequence.Paste), le.paste).setEnabled(not le.isReadOnly())
|
||||
m.addAction(_('Delete') + access_key(QKeySequence.Delete), le.del_).setEnabled(not le.isReadOnly() and le.hasSelectedText())
|
||||
m.addSeparator()
|
||||
m.addAction(_('Select &All') + access_key(QKeySequence.SelectAll), self.selectAll)
|
||||
m.addSeparator()
|
||||
m.addAction(_('&Step up'), self.stepUp)
|
||||
m.addAction(_('Step &down'), self.stepDown)
|
||||
m.setAttribute(Qt.WA_DeleteOnClose)
|
||||
populate_standard_spinbox_context_menu(self, m)
|
||||
m.popup(ev.globalPos())
|
||||
|
||||
def set_spinbox_value(self, val):
|
||||
|
@ -6,7 +6,7 @@ from __future__ import (unicode_literals, division, absolute_import,
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2013, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||
|
||||
from PyQt5.Qt import QPushButton, QPixmap, QIcon, QColor, Qt, QColorDialog, pyqtSignal
|
||||
from PyQt5.Qt import QPushButton, QPixmap, QIcon, QColor, Qt, QColorDialog, pyqtSignal, QKeySequence
|
||||
|
||||
from calibre.gui2.complete2 import LineEdit, EditWithComplete
|
||||
from calibre.gui2.widgets import history
|
||||
@ -99,3 +99,24 @@ class ColorButton(QPushButton):
|
||||
if col.isValid():
|
||||
self.color = unicode(col.name())
|
||||
|
||||
|
||||
def access_key(k):
|
||||
'Return shortcut text suitable for adding to a menu item'
|
||||
if QKeySequence.keyBindings(k):
|
||||
return '\t' + QKeySequence(k).toString(QKeySequence.NativeText)
|
||||
return ''
|
||||
|
||||
def populate_standard_spinbox_context_menu(spinbox, menu, add_clear=False):
|
||||
m = menu
|
||||
le = spinbox.lineEdit()
|
||||
m.addAction(_('Cu&t') + access_key(QKeySequence.Cut), le.cut).setEnabled(not le.isReadOnly() and le.hasSelectedText())
|
||||
m.addAction(_('&Copy') + access_key(QKeySequence.Copy), le.copy).setEnabled(le.hasSelectedText())
|
||||
m.addAction(_('&Paste') + access_key(QKeySequence.Paste), le.paste).setEnabled(not le.isReadOnly())
|
||||
m.addAction(_('Delete') + access_key(QKeySequence.Delete), le.del_).setEnabled(not le.isReadOnly() and le.hasSelectedText())
|
||||
m.addSeparator()
|
||||
m.addAction(_('Select &All') + access_key(QKeySequence.SelectAll), spinbox.selectAll)
|
||||
m.addSeparator()
|
||||
m.addAction(_('&Step up'), spinbox.stepUp)
|
||||
m.addAction(_('Step &down'), spinbox.stepDown)
|
||||
m.setAttribute(Qt.WA_DeleteOnClose)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user