FTS dialog: Allow sorting by any column

This commit is contained in:
Kovid Goyal 2026-03-20 12:36:17 +05:30
parent 62150573cb
commit 6d02a8161a
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 25 additions and 31 deletions

View File

@ -30,6 +30,16 @@ from calibre.utils.icu import primary_sort_key
SORT_HIDDEN_PREF = 'sort-action-hidden-fields'
def hidden_fields(db):
return frozenset(db.new_api.pref(SORT_HIDDEN_PREF, default=()) or ())
def get_sorted_fields(db):
fm = db.field_metadata
name_map = [(v,k) for k, v in fm.ui_sortable_field_keys().items()]
return sorted(name_map, key=lambda x: primary_sort_key(x[0]))
class SortAction(QAction):
sort_requested = pyqtSignal(object, object)
@ -108,10 +118,7 @@ class SortByAction(InterfaceAction):
self.update_menu()
def get_sorted_fields(self):
db = self.gui.current_db
fm = db.field_metadata
name_map = [(v,k) for k, v in fm.ui_sortable_field_keys().items()]
return sorted(name_map, key=lambda x: primary_sort_key(x[0]))
return get_sorted_fields(self.gui.current_db)
def update_menu(self, menu=None):
menu = menu or self.qaction.menu()
@ -149,7 +156,7 @@ class SortByAction(InterfaceAction):
menu.addSeparator()
# Add the columns to the menu
hidden = frozenset(db.new_api.pref(SORT_HIDDEN_PREF, default=()) or ())
hidden = hidden_fields(self.gui.current_db)
for name, key in self.get_sorted_fields():
if key == 'ondevice' and self.gui.device_connected is None:
@ -164,7 +171,7 @@ class SortByAction(InterfaceAction):
def select_sortable_columns(self):
db = self.gui.current_db
hidden = frozenset(db.new_api.pref(SORT_HIDDEN_PREF, default=()) or ())
hidden = hidden_fields(db)
items = QListWidget()
items.setSelectionMode(QAbstractItemView.SelectionMode.MultiSelection)
for display_name, key in self.get_sorted_fields():

View File

@ -49,6 +49,7 @@ from calibre import fit_image, prepare_string_for_xml
from calibre.db import FTSQueryError
from calibre.ebooks.metadata import authors_to_string, fmt_sidx
from calibre.gui2 import config, error_dialog, gprefs, info_dialog, question_dialog
from calibre.gui2.actions.sort import get_sorted_fields, hidden_fields
from calibre.gui2.fts.cards import CardsView
from calibre.gui2.fts.utils import fts_url, get_db, help_panel, jump_shortcut, mark_shortcut, markup_text
from calibre.gui2.library.models import render_pin
@ -350,21 +351,11 @@ class ResultsModel(QAbstractItemModel):
return False
def do_sort_on_field(self, sort_key):
field_map = {
'newest': [('timestamp', False)],
'rating': [('rating', False)],
'pubdate': [('pubdate', False)],
'size': [('size', False)],
'pages': [('pages', False)],
}
fields = field_map.get(sort_key)
if fields is None:
return
db = get_db()
if sort_key == 'pages':
db.queue_pages_scan()
current_ids = frozenset(r.book_id for r in self.results)
sorted_ids = db.multisort(fields, ids_to_sort=current_ids)
sorted_ids = db.multisort([(sort_key, False)], ids_to_sort=current_ids)
results_by_id = {r.book_id: r for r in self.results}
self.results = [results_by_id[bid] for bid in sorted_ids if bid in results_by_id]
self.result_map = {r.book_id: i for i, r in enumerate(self.results)}
@ -679,24 +670,20 @@ class SearchInputPanel(QWidget):
ag = QActionGroup(b)
ag.setExclusive(True)
current_sort = gprefs['fts_sort_order']
self._sort_action_map = {}
self._sort_labels = {
'relevance': _('Relevance'),
'newest': _('Newest'),
'rating': _('Highest rated'),
'pubdate': _('Recently published'),
'size': _('Largest'),
}
db = get_db()
if db.pref('full_page_scan_requested'):
self._sort_labels['pages'] = _('Most pages')
for key, label in self._sort_labels.items():
hidden = hidden_fields(get_db())
self._sort_labels = {}
def add(key, label):
self._sort_labels[key] = label
ac = sort_menu.addAction(label)
ac.setCheckable(True)
ac.setChecked(key == current_sort)
ac.setData(key)
ag.addAction(ac)
self._sort_action_map[key] = ac
add('relevance', _('Relevance'))
for name, key in get_sorted_fields(get_db()):
if key in hidden or key == 'ondevice':
continue
add(key, name)
sort_menu.triggered.connect(self._sort_triggered)
self._update_sort_button_label()
@ -1156,7 +1143,7 @@ class ResultsPanel(QWidget):
query=query, fts_url=fts_url), det_msg=err_msg, show=True)
def develop(view='compact'):
def develop(view='cards'):
from calibre.gui2 import Application
from calibre.library import db
app = Application([])