diff --git a/src/calibre/db/backend.py b/src/calibre/db/backend.py
index d68370ccbe..fd83e3aaf6 100644
--- a/src/calibre/db/backend.py
+++ b/src/calibre/db/backend.py
@@ -49,8 +49,8 @@ Differences in semantics from pysqlite:
3. There is no executescript
'''
-CUSTOM_DATA_TYPES = frozenset(['rating', 'text', 'comments', 'datetime',
- 'int', 'float', 'bool', 'series', 'composite', 'enumeration'])
+CUSTOM_DATA_TYPES = frozenset(('rating', 'text', 'comments', 'datetime',
+ '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())
@@ -479,6 +479,7 @@ class DB(object):
defs['field_under_covers_in_grid'] = 'title'
defs['cover_browser_title_template'] = '{title}'
defs['cover_browser_subtitle_field'] = 'rating'
+ defs['styled_columns'] = {}
# Migrate the bool tristate tweak
defs['bools_are_tristate'] = \
diff --git a/src/calibre/gui2/library/models.py b/src/calibre/gui2/library/models.py
index 552d5e8270..abaafa368f 100644
--- a/src/calibre/gui2/library/models.py
+++ b/src/calibre/gui2/library/models.py
@@ -9,7 +9,7 @@ import functools, re, os, traceback, errno, time
from collections import defaultdict, namedtuple
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)
from calibre import fit_image, force_unicode
@@ -175,6 +175,14 @@ class BooksModel(QAbstractTableModel): # {{{
def __init__(self, parent=None, buffer=40):
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 = {
'title' : _("Title"),
'ondevice' : _("On Device"),
@@ -258,6 +266,21 @@ class BooksModel(QAbstractTableModel): # {{{
self.dataChanged.emit(self.index(row, col), self.index(row,
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):
try:
return cc_label in self.custom_columns
@@ -280,6 +303,10 @@ class BooksModel(QAbstractTableModel): # {{{
def set_database(self, db):
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.ids_to_highlight_set = set()
self.current_highlighted_idx = None
@@ -968,6 +995,9 @@ class BooksModel(QAbstractTableModel): # {{{
ans = Qt.AlignVCenter | ALIGNMENT_MAP[self.alignment_map.get(cname,
'left')]
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():
# if self.column_map[index.column()] in self.editable_cols:
# return (_("Double click to edit me
"))
diff --git a/src/calibre/gui2/library/views.py b/src/calibre/gui2/library/views.py
index b856bb90ea..d6b38bac7b 100644
--- a/src/calibre/gui2/library/views.py
+++ b/src/calibre/gui2/library/views.py
@@ -403,6 +403,8 @@ class BooksView(QTableView): # {{{
elif action.startswith('align_'):
alignment = action.partition('_')[-1]
self._model.change_alignment(column, alignment)
+ elif action.startswith('font_'):
+ self._model.change_column_font(column, action[len('font_'):])
elif action == 'quickview':
from calibre.gui2.actions.show_quickview import get_quickview_action_plugin
qv = get_quickview_action_plugin()
@@ -437,6 +439,18 @@ class BooksView(QTableView): # {{{
if al == x:
a.setCheckable(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._model.db.field_metadata[col]['is_category']:
act = ans.addAction(_('Quickview column %s') % name, partial(handler, action='quickview'))