Book list: Allow changing the font used for any column to bold and/or italic by right clicking on the column header and choosing "Change font style". Note that this setting is per-library so it has to be done once for the book list in every calibre library. Fixes #1758434 [[enhancement] individual column font choice](https://bugs.launchpad.net/calibre/+bug/1758434)

This commit is contained in:
Kovid Goyal 2018-09-05 09:46:02 +05:30
parent eff7679d06
commit 2fcf979b3c
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 48 additions and 3 deletions

View File

@ -49,8 +49,8 @@ Differences in semantics from pysqlite:
3. There is no executescript 3. There is no executescript
''' '''
CUSTOM_DATA_TYPES = frozenset(['rating', 'text', 'comments', 'datetime', CUSTOM_DATA_TYPES = frozenset(('rating', 'text', 'comments', 'datetime',
'int', 'float', 'bool', 'series', 'composite', 'enumeration']) 'int', 'float', 'bool', 'series', 'composite', 'enumeration'))
WINDOWS_RESERVED_NAMES = frozenset('CON PRN AUX NUL COM1 COM2 COM3 COM4 COM5 COM6 COM7 COM8 COM9 LPT1 LPT2 LPT3 LPT4 LPT5 LPT6 LPT7 LPT8 LPT9'.split()) WINDOWS_RESERVED_NAMES = frozenset('CON PRN AUX NUL COM1 COM2 COM3 COM4 COM5 COM6 COM7 COM8 COM9 LPT1 LPT2 LPT3 LPT4 LPT5 LPT6 LPT7 LPT8 LPT9'.split())
@ -479,6 +479,7 @@ class DB(object):
defs['field_under_covers_in_grid'] = 'title' defs['field_under_covers_in_grid'] = 'title'
defs['cover_browser_title_template'] = '{title}' defs['cover_browser_title_template'] = '{title}'
defs['cover_browser_subtitle_field'] = 'rating' defs['cover_browser_subtitle_field'] = 'rating'
defs['styled_columns'] = {}
# Migrate the bool tristate tweak # Migrate the bool tristate tweak
defs['bools_are_tristate'] = \ defs['bools_are_tristate'] = \

View File

@ -9,7 +9,7 @@ import functools, re, os, traceback, errno, time
from collections import defaultdict, namedtuple from collections import defaultdict, namedtuple
from itertools import groupby from itertools import groupby
from PyQt5.Qt import (QAbstractTableModel, Qt, pyqtSignal, QIcon, QImage, from PyQt5.Qt import (QAbstractTableModel, Qt, pyqtSignal, QIcon, QImage, QFont,
QModelIndex, QDateTime, QColor, QPixmap, QPainter, QApplication) QModelIndex, QDateTime, QColor, QPixmap, QPainter, QApplication)
from calibre import fit_image, force_unicode from calibre import fit_image, force_unicode
@ -175,6 +175,14 @@ class BooksModel(QAbstractTableModel): # {{{
def __init__(self, parent=None, buffer=40): def __init__(self, parent=None, buffer=40):
QAbstractTableModel.__init__(self, parent) QAbstractTableModel.__init__(self, parent)
base_font = parent.font() if parent else QApplication.instance().font()
self.bold_font = QFont(base_font)
self.bold_font.setBold(True)
self.italic_font = QFont(base_font)
self.italic_font.setItalic(True)
self.bi_font = QFont(self.bold_font)
self.bi_font.setItalic(True)
self.styled_columns = {}
self.orig_headers = { self.orig_headers = {
'title' : _("Title"), 'title' : _("Title"),
'ondevice' : _("On Device"), 'ondevice' : _("On Device"),
@ -258,6 +266,21 @@ class BooksModel(QAbstractTableModel): # {{{
self.dataChanged.emit(self.index(row, col), self.index(row, self.dataChanged.emit(self.index(row, col), self.index(row,
col)) col))
def change_column_font(self, colname, font_type):
if colname in self.column_map and font_type in ('normal', 'bold', 'italic', 'bi'):
db = self.db.new_api
old = db.pref('styled_columns', {})
old.pop(colname, None)
self.styled_columns.pop(colname, None)
if font_type != 'normal':
self.styled_columns[colname] = getattr(self, '{}_font'.format(font_type))
old[colname] = font_type
self.db.new_api.set_pref('styled_columns', old)
col = self.column_map.index(colname)
for row in xrange(self.rowCount(QModelIndex())):
self.dataChanged.emit(self.index(row, col), self.index(row,
col))
def is_custom_column(self, cc_label): def is_custom_column(self, cc_label):
try: try:
return cc_label in self.custom_columns return cc_label in self.custom_columns
@ -280,6 +303,10 @@ class BooksModel(QAbstractTableModel): # {{{
def set_database(self, db): def set_database(self, db):
self.ids_to_highlight = [] self.ids_to_highlight = []
if db:
style_map = {'bold': self.bold_font, 'bi': self.bi_font, 'italic': self.italic_font}
self.styled_columns = {k: style_map.get(v, None) for k, v in db.new_api.pref('styled_columns', {}).iteritems()}
self.alignment_map = {} self.alignment_map = {}
self.ids_to_highlight_set = set() self.ids_to_highlight_set = set()
self.current_highlighted_idx = None self.current_highlighted_idx = None
@ -968,6 +995,9 @@ class BooksModel(QAbstractTableModel): # {{{
ans = Qt.AlignVCenter | ALIGNMENT_MAP[self.alignment_map.get(cname, ans = Qt.AlignVCenter | ALIGNMENT_MAP[self.alignment_map.get(cname,
'left')] 'left')]
return (ans) return (ans)
elif role == Qt.FontRole and self.styled_columns:
cname = self.column_map[index.column()]
return self.styled_columns.get(cname)
# elif role == Qt.ToolTipRole and index.isValid(): # elif role == Qt.ToolTipRole and index.isValid():
# if self.column_map[index.column()] in self.editable_cols: # if self.column_map[index.column()] in self.editable_cols:
# return (_("Double click to <b>edit</b> me<br><br>")) # return (_("Double click to <b>edit</b> me<br><br>"))

View File

@ -403,6 +403,8 @@ class BooksView(QTableView): # {{{
elif action.startswith('align_'): elif action.startswith('align_'):
alignment = action.partition('_')[-1] alignment = action.partition('_')[-1]
self._model.change_alignment(column, alignment) self._model.change_alignment(column, alignment)
elif action.startswith('font_'):
self._model.change_column_font(column, action[len('font_'):])
elif action == 'quickview': elif action == 'quickview':
from calibre.gui2.actions.show_quickview import get_quickview_action_plugin from calibre.gui2.actions.show_quickview import get_quickview_action_plugin
qv = get_quickview_action_plugin() qv = get_quickview_action_plugin()
@ -437,6 +439,18 @@ class BooksView(QTableView): # {{{
if al == x: if al == x:
a.setCheckable(True) a.setCheckable(True)
a.setChecked(True) a.setChecked(True)
if not isinstance(view, DeviceBooksView):
col_font = self._model.styled_columns.get(col)
m = ans.addMenu(_('Change font style for %s') % name)
for x, t, f in (
('normal', _('Normal font'), None), ('bold', _('Bold Font'), self._model.bold_font),
('italic', _('Italic font'), self._model.italic_font), ('bi', _('Bold and Italic font'), self._model.bi_font),
):
a = m.addAction(t, partial(handler, action='font_' + x))
if f is col_font:
a.setCheckable(True)
a.setChecked(True)
if self.is_library_view: if self.is_library_view:
if self._model.db.field_metadata[col]['is_category']: if self._model.db.field_metadata[col]['is_category']:
act = ans.addAction(_('Quickview column %s') % name, partial(handler, action='quickview')) act = ans.addAction(_('Quickview column %s') % name, partial(handler, action='quickview'))