%PDF- %PDF-
| Direktori : /usr/lib/calibre/calibre/gui2/actions/ |
| Current File : //usr/lib/calibre/calibre/gui2/actions/sort.py |
#!/usr/bin/env python3
__license__ = 'GPL v3'
__copyright__ = '2013, Kovid Goyal <kovid at kovidgoyal.net>'
from contextlib import suppress
from functools import partial
from qt.core import QAction, QDialog, QIcon, QToolButton, pyqtSignal
from calibre.gui2.actions import InterfaceAction
from calibre.utils.icu import primary_sort_key
from calibre.library.field_metadata import category_icon_map
from polyglot.builtins import iteritems
SORT_HIDDEN_PREF = 'sort-action-hidden-fields'
def change_hidden(key, visible):
from calibre.gui2.ui import get_gui
gui = get_gui()
if gui is not None:
db = gui.current_db.new_api
val = set(db.pref(SORT_HIDDEN_PREF) or ())
if visible:
val.discard(key)
else:
val.add(key)
db.set_pref(SORT_HIDDEN_PREF, tuple(val))
class SortAction(QAction):
sort_requested = pyqtSignal(object, object)
def __init__(self, text, key, ascending, parent):
QAction.__init__(self, text, parent)
self.key, self.ascending = key, ascending
self.triggered.connect(self)
ic = category_icon_map['custom:'] if self.key.startswith('#') else category_icon_map.get(key)
if ic:
self.setIcon(QIcon.ic(ic))
def __call__(self):
self.sort_requested.emit(self.key, self.ascending)
class SortByAction(InterfaceAction):
name = 'Sort By'
action_spec = (_('Sort by'), 'sort.png', _('Sort the list of books'), None)
action_type = 'current'
popup_type = QToolButton.ToolButtonPopupMode.InstantPopup
action_add_menu = True
dont_add_to = frozenset(('context-menu-cover-browser', ))
def genesis(self):
self.sorted_icon = QIcon(I('ok.png'))
self.qaction.menu().aboutToShow.connect(self.about_to_show)
def c(attr, title, tooltip, callback, keys=()):
ac = self.create_action(spec=(title, None, tooltip, keys), attr=attr)
ac.triggered.connect(callback)
self.gui.addAction(ac)
return ac
c('reverse_sort_action', _('Reverse current sort'), _('Reverse the current sort order'), self.reverse_sort, 'shift+f5')
c('reapply_sort_action', _('Re-apply current sort'), _('Re-apply the current sort'), self.reapply_sort, 'f5')
def reverse_sort(self):
self.gui.current_view().reverse_sort()
def reapply_sort(self):
self.gui.current_view().resort()
def location_selected(self, loc):
enabled = loc == 'library'
self.qaction.setEnabled(enabled)
self.menuless_qaction.setEnabled(enabled)
def about_to_show(self):
self.update_menu()
def update_menu(self, menu=None):
menu = self.qaction.menu() if menu is None else menu
for action in menu.actions():
if hasattr(action, 'sort_requested'):
action.sort_requested.disconnect()
with suppress(TypeError):
action.toggled.disconnect()
menu.clear()
lv = self.gui.library_view
m = lv.model()
db = m.db
try:
sort_col, order = m.sorted_on
except TypeError:
sort_col, order = 'date', True
fm = db.field_metadata
name_map = {v:k for k, v in iteritems(fm.ui_sortable_field_keys())}
hidden = frozenset(db.new_api.pref(SORT_HIDDEN_PREF, default=()) or ())
hidden_items_menu = menu.addMenu(_('Select sortable columns'))
menu.addAction(_('Sort on multiple columns'), self.choose_multisort)
menu.addSeparator()
all_names = sorted(name_map, key=primary_sort_key)
for name in all_names:
key = name_map[name]
ac = hidden_items_menu.addAction(name)
ac.setCheckable(True)
ac.setChecked(key not in hidden)
ac.setObjectName(key)
ac.toggled.connect(partial(change_hidden, key))
for name in all_names:
key = name_map[name]
if key == 'ondevice' and self.gui.device_connected is None:
continue
if key in hidden:
continue
ascending = None
if key == sort_col:
name = _('%s [reverse current sort]') % name
ascending = not order
sac = SortAction(name, key, ascending, menu)
if key == sort_col:
sac.setIcon(self.sorted_icon)
sac.sort_requested.connect(self.sort_requested)
if key == sort_col:
before = menu.actions()[0] if menu.actions() else None
menu.insertAction(before, sac)
menu.insertSeparator(before)
else:
menu.addAction(sac)
def choose_multisort(self):
from calibre.gui2.dialogs.multisort import ChooseMultiSort
d = ChooseMultiSort(self.gui.current_db, parent=self.gui, is_device_connected=self.gui.device_connected)
if d.exec() == QDialog.DialogCode.Accepted:
self.gui.library_view.multisort(d.current_sort_spec)
def sort_requested(self, key, ascending):
if ascending is None:
self.gui.library_view.intelligent_sort(key, True)
else:
self.gui.library_view.sort_by_named_field(key, ascending)