mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Implement save/load for multisorts
This commit is contained in:
parent
ed9703a522
commit
ce37adcef7
@ -4,8 +4,8 @@
|
|||||||
|
|
||||||
|
|
||||||
from qt.core import (
|
from qt.core import (
|
||||||
QAbstractItemView, QHBoxLayout, QLabel, QListWidget, QListWidgetItem, QSize, Qt,
|
QAbstractItemView, QDialogButtonBox, QInputDialog, QLabel, QListWidget,
|
||||||
QVBoxLayout
|
QListWidgetItem, QMenu, QSize, Qt, QVBoxLayout
|
||||||
)
|
)
|
||||||
|
|
||||||
from calibre import prepare_string_for_xml
|
from calibre import prepare_string_for_xml
|
||||||
@ -37,23 +37,21 @@ class ChooseMultiSort(Dialog):
|
|||||||
|
|
||||||
def setup_ui(self):
|
def setup_ui(self):
|
||||||
self.vl = vl = QVBoxLayout(self)
|
self.vl = vl = QVBoxLayout(self)
|
||||||
self.hl = hl = QHBoxLayout()
|
|
||||||
self.la = la = QLabel(_(
|
self.la = la = QLabel(_(
|
||||||
'Pick multiple columns to sort by. Drag and drop to re-arrange. Higher columns are more important.'
|
'Pick multiple columns to sort by. Drag and drop to re-arrange. Higher columns are more important.'
|
||||||
' Ascending or descending order can be toggled by clicking the column name at the bottom'
|
' Ascending or descending order can be toggled by clicking the column name at the bottom'
|
||||||
' of this dialog, after having selected it.'))
|
' of this dialog, after having selected it.'))
|
||||||
la.setWordWrap(True)
|
la.setWordWrap(True)
|
||||||
vl.addWidget(la)
|
vl.addWidget(la)
|
||||||
vl.addLayout(hl)
|
self.order_label = la = QLabel('\xa0')
|
||||||
self.order_label = la = QLabel('')
|
|
||||||
la.setTextFormat(Qt.TextFormat.RichText)
|
la.setTextFormat(Qt.TextFormat.RichText)
|
||||||
la.setWordWrap(True)
|
la.setWordWrap(True)
|
||||||
la.linkActivated.connect(self.link_activated)
|
la.linkActivated.connect(self.link_activated)
|
||||||
vl.addWidget(la)
|
|
||||||
vl.addWidget(self.bb)
|
|
||||||
|
|
||||||
self.column_list = cl = QListWidget(self)
|
self.column_list = cl = QListWidget(self)
|
||||||
hl.addWidget(cl)
|
vl.addWidget(cl)
|
||||||
|
vl.addWidget(la)
|
||||||
|
vl.addWidget(self.bb)
|
||||||
for name in self.all_names:
|
for name in self.all_names:
|
||||||
i = QListWidgetItem(cl)
|
i = QListWidgetItem(cl)
|
||||||
i.setText(name)
|
i.setText(name)
|
||||||
@ -69,6 +67,18 @@ class ChooseMultiSort(Dialog):
|
|||||||
cl.itemChanged.connect(self.update_order_label)
|
cl.itemChanged.connect(self.update_order_label)
|
||||||
cl.model().rowsMoved.connect(self.update_order_label)
|
cl.model().rowsMoved.connect(self.update_order_label)
|
||||||
|
|
||||||
|
self.save_button = b = self.bb.addButton(_('&Save'), QDialogButtonBox.ButtonRole.ActionRole)
|
||||||
|
b.setToolTip(_('Save this sort order for easy re-use'))
|
||||||
|
b.clicked.connect(self.save)
|
||||||
|
b.setAutoDefault(False)
|
||||||
|
|
||||||
|
self.load_button = b = self.bb.addButton(_('&Load'), QDialogButtonBox.ButtonRole.ActionRole)
|
||||||
|
b.setToolTip(_('Load previously saved settings'))
|
||||||
|
b.setAutoDefault(False)
|
||||||
|
self.load_menu = QMenu(b)
|
||||||
|
b.setMenu(self.load_menu)
|
||||||
|
self.load_menu.aboutToShow.connect(self.populate_load_menu)
|
||||||
|
|
||||||
def item_double_clicked(self, item):
|
def item_double_clicked(self, item):
|
||||||
cs = item.checkState()
|
cs = item.checkState()
|
||||||
item.setCheckState(Qt.CheckState.Checked if cs == Qt.CheckState.Unchecked else Qt.CheckState.Unchecked)
|
item.setCheckState(Qt.CheckState.Checked if cs == Qt.CheckState.Unchecked else Qt.CheckState.Unchecked)
|
||||||
@ -79,8 +89,7 @@ class ChooseMultiSort(Dialog):
|
|||||||
@property
|
@property
|
||||||
def current_sort_spec(self):
|
def current_sort_spec(self):
|
||||||
ans = []
|
ans = []
|
||||||
cl = self.column_list
|
for item in self.iteritems():
|
||||||
for item in (cl.item(r) for r in range(cl.count())):
|
|
||||||
if item.checkState() == Qt.CheckState.Checked:
|
if item.checkState() == Qt.CheckState.Checked:
|
||||||
k = item.data(Qt.ItemDataRole.UserRole)
|
k = item.data(Qt.ItemDataRole.UserRole)
|
||||||
ans.append((k, self.sort_order_map[k]))
|
ans.append((k, self.sort_order_map[k]))
|
||||||
@ -105,12 +114,67 @@ class ChooseMultiSort(Dialog):
|
|||||||
self.sort_order_map[key] ^= True
|
self.sort_order_map[key] ^= True
|
||||||
self.update_order_label()
|
self.update_order_label()
|
||||||
|
|
||||||
|
def no_column_selected_error(self):
|
||||||
|
return error_dialog(self, _('No sort selected'), _(
|
||||||
|
'You must select at least one column on which to sort'), show=True)
|
||||||
|
|
||||||
def accept(self):
|
def accept(self):
|
||||||
if not self.current_sort_spec:
|
if not self.current_sort_spec:
|
||||||
return error_dialog(self, _('No sort selected'), _(
|
return self.no_column_selected_error()
|
||||||
'You must select at least one column on which to sort'), show=True)
|
|
||||||
super().accept()
|
super().accept()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def saved_specs(self):
|
||||||
|
return self.db.pref('saved_multisort_specs', {}).copy()
|
||||||
|
|
||||||
|
@saved_specs.setter
|
||||||
|
def saved_specs(self, val):
|
||||||
|
self.db.set_pref('saved_multisort_specs', val.copy())
|
||||||
|
|
||||||
|
def save(self):
|
||||||
|
spec = self.current_sort_spec
|
||||||
|
if not spec:
|
||||||
|
return self.no_column_selected_error()
|
||||||
|
name, ok = QInputDialog.getText(self, _('Choose name'),
|
||||||
|
_('Choose a name for these settings'))
|
||||||
|
if ok:
|
||||||
|
q = self.saved_specs
|
||||||
|
q[name] = spec
|
||||||
|
self.saved_specs = q
|
||||||
|
|
||||||
|
def populate_load_menu(self):
|
||||||
|
m = self.load_menu
|
||||||
|
m.clear()
|
||||||
|
specs = self.saved_specs
|
||||||
|
if not specs:
|
||||||
|
m.addAction(_('No saved sorts available'))
|
||||||
|
return
|
||||||
|
for name in sorted(specs, key=primary_sort_key):
|
||||||
|
ac = m.addAction(name, self.load_spec)
|
||||||
|
ac.setObjectName(name)
|
||||||
|
|
||||||
|
def load_spec(self):
|
||||||
|
name = self.sender().objectName()
|
||||||
|
spec = self.saved_specs[name]
|
||||||
|
self.apply_spec(spec)
|
||||||
|
|
||||||
|
def iteritems(self):
|
||||||
|
cl = self.column_list
|
||||||
|
return (cl.item(i) for i in range(cl.count()))
|
||||||
|
|
||||||
|
def apply_spec(self, spec):
|
||||||
|
cl = self.column_list
|
||||||
|
for item in self.iteritems():
|
||||||
|
item.setCheckState(Qt.CheckState.Unchecked)
|
||||||
|
imap = {item.data(Qt.ItemDataRole.UserRole): item for item in self.iteritems()}
|
||||||
|
for key, ascending in reversed(spec):
|
||||||
|
item = imap.get(key)
|
||||||
|
if item is not None:
|
||||||
|
item = cl.takeItem(cl.row(item))
|
||||||
|
cl.insertItem(0, item)
|
||||||
|
self.sort_order_map[key] = ascending
|
||||||
|
item.setCheckState(Qt.CheckState.Checked)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
from calibre.gui2 import Application
|
from calibre.gui2 import Application
|
||||||
|
Loading…
x
Reference in New Issue
Block a user