mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 18:54:09 -04:00
Hook up the cover generation customization and allow changing the cover size as well
This commit is contained in:
parent
a7c8de3357
commit
61cae6c03c
@ -13,7 +13,7 @@ from PyQt5.Qt import (
|
||||
QWidget, QHBoxLayout, QTabWidget, QLabel, QSizePolicy, QSize, QFormLayout,
|
||||
QSpinBox, pyqtSignal, QPixmap, QDialog, QVBoxLayout, QDialogButtonBox,
|
||||
QListWidget, QListWidgetItem, Qt, QGridLayout, QPushButton, QIcon,
|
||||
QColorDialog, QToolButton, QLineEdit, QColor, QFrame)
|
||||
QColorDialog, QToolButton, QLineEdit, QColor, QFrame, QTimer)
|
||||
|
||||
from calibre.ebooks.covers import all_styles, cprefs, generate_cover, override_prefs, default_color_themes
|
||||
from calibre.gui2 import gprefs, error_dialog
|
||||
@ -118,7 +118,7 @@ class CoverSettingsWidget(QWidget):
|
||||
self.mi = mi or self.default_mi()
|
||||
|
||||
self.colors_page = cp = QWidget(st)
|
||||
st.addTab(cp, _('Colors'))
|
||||
st.addTab(cp, _('&Colors'))
|
||||
cp.l = l = QGridLayout()
|
||||
cp.setLayout(l)
|
||||
if for_global_prefs:
|
||||
@ -147,7 +147,7 @@ class CoverSettingsWidget(QWidget):
|
||||
l.addWidget(rcs, l.rowCount()-1, 2)
|
||||
|
||||
self.styles_page = sp = QWidget(st)
|
||||
st.addTab(sp, _('Styles'))
|
||||
st.addTab(sp, _('&Styles'))
|
||||
sp.l = l = QVBoxLayout()
|
||||
sp.setLayout(l)
|
||||
if for_global_prefs:
|
||||
@ -167,9 +167,16 @@ class CoverSettingsWidget(QWidget):
|
||||
self.style_map = OrderedDict()
|
||||
|
||||
self.font_page = fp = QWidget(st)
|
||||
st.addTab(fp, _('Fonts'))
|
||||
st.addTab(fp, _('&Fonts and Sizes'))
|
||||
fp.l = l = QFormLayout()
|
||||
fp.setLayout(l)
|
||||
fp.f = []
|
||||
def add_hline():
|
||||
f = QFrame()
|
||||
fp.f.append(f)
|
||||
f.setFrameShape(f.HLine)
|
||||
l.addRow(f)
|
||||
|
||||
for x, label, size_label in (
|
||||
('title', _('&Title font family:'), _('&Title font size:')),
|
||||
('subtitle', _('&Subtitle font family'), _('&Subtitle font size:')),
|
||||
@ -187,9 +194,27 @@ class CoverSettingsWidget(QWidget):
|
||||
fs.setValue(prefs[attr])
|
||||
fs.valueChanged.connect(self.emit_changed)
|
||||
l.addRow(size_label, fs)
|
||||
add_hline()
|
||||
self.changed_timer = t = QTimer(self)
|
||||
t.setSingleShot(True), t.setInterval(500), t.timeout.connect(self.emit_changed)
|
||||
def create_sz(label):
|
||||
ans = QSpinBox(self)
|
||||
ans.setSuffix(' px'), ans.setMinimum(100), ans.setMaximum(10000)
|
||||
l.addRow(label, ans)
|
||||
ans.valueChanged.connect(self.changed_timer.start)
|
||||
return ans
|
||||
|
||||
self.cover_width = create_sz(_('Cover &width:'))
|
||||
self.cover_height = create_sz(_('Cover &height:'))
|
||||
fp.cla = la = QLabel(_(
|
||||
'Note that the preview to the side is of fixed aspect ratio, so changing the cover'
|
||||
' width above will not have any effect. If you change the height, you should also change the width nevertheless'
|
||||
' as it will be used in actual cover generation.'))
|
||||
la.setWordWrap(True)
|
||||
l.addRow(la)
|
||||
|
||||
self.templates_page = tp = QWidget(st)
|
||||
st.addTab(tp, _('Text'))
|
||||
st.addTab(tp, _('&Text'))
|
||||
tp.l = l = QVBoxLayout()
|
||||
tp.setLayout(l)
|
||||
tp.la = la = QLabel(_(
|
||||
@ -244,6 +269,9 @@ class CoverSettingsWidget(QWidget):
|
||||
|
||||
def apply_prefs(self, prefs):
|
||||
with self:
|
||||
self._apply_prefs(prefs)
|
||||
|
||||
def _apply_prefs(self, prefs):
|
||||
for x in ('title', 'subtitle', 'footer'):
|
||||
attr = '%s_font_family' % x
|
||||
getattr(self, attr).font_family = prefs[attr]
|
||||
@ -254,6 +282,10 @@ class CoverSettingsWidget(QWidget):
|
||||
x += '_template'
|
||||
getattr(self, x).setText(prefs[x])
|
||||
|
||||
for x in ('width', 'height'):
|
||||
x = 'cover_' + x
|
||||
getattr(self, x).setValue(prefs[x])
|
||||
|
||||
color_themes = prefs['color_themes'].copy()
|
||||
color_themes.update(default_color_themes)
|
||||
disabled = set(prefs['disabled_color_themes'])
|
||||
@ -339,6 +371,9 @@ class CoverSettingsWidget(QWidget):
|
||||
for x in ('title', 'subtitle', 'footer'):
|
||||
x += '_template'
|
||||
prefs[x] = getattr(self, x).text()
|
||||
for x in ('width', 'height'):
|
||||
x = 'cover_' + x
|
||||
prefs[x] = getattr(self, x).value()
|
||||
return prefs
|
||||
|
||||
def insert_scheme(self, name, li):
|
||||
@ -412,16 +447,21 @@ class CoverSettingsWidget(QWidget):
|
||||
getattr(self, attr).setText(templ)
|
||||
self.emit_changed()
|
||||
|
||||
@property
|
||||
def prefs_for_rendering(self):
|
||||
prefs = self.current_prefs
|
||||
prefs = override_prefs(prefs, override_style=self.current_style, override_color_theme=self.current_colors)
|
||||
return prefs
|
||||
|
||||
def update_preview(self):
|
||||
if self.ignore_changed:
|
||||
return
|
||||
prefs = self.current_prefs
|
||||
w, h = self.preview_label.sizeHint().width(), self.preview_label.sizeHint().height()
|
||||
prefs = self.prefs_for_rendering
|
||||
hr = h / prefs['cover_height']
|
||||
for x in ('title', 'subtitle', 'footer'):
|
||||
attr = '%s_font_size' % x
|
||||
prefs[attr] = int(prefs[attr] * hr)
|
||||
prefs = override_prefs(prefs, override_style=self.current_style, override_color_theme=self.current_colors)
|
||||
prefs['cover_width'], prefs['cover_height'] = w, h
|
||||
img = generate_cover(self.mi, prefs=prefs, as_qimage=True)
|
||||
self.preview_label.setPixmap(QPixmap.fromImage(img))
|
||||
@ -446,16 +486,15 @@ class CoverSettingsWidget(QWidget):
|
||||
self.apply_prefs(defaults)
|
||||
self.update_preview()
|
||||
|
||||
def save_defaults(self):
|
||||
cp = self.current_prefs
|
||||
with self.original_prefs:
|
||||
for k in self.original_prefs.defaults:
|
||||
self.original_prefs[k] = cp[k]
|
||||
|
||||
def save_state(self):
|
||||
self.original_prefs.set('last_used_colors', self.current_colors)
|
||||
self.original_prefs.set('last_used_style', self.current_style)
|
||||
|
||||
def save_as_prefs(self):
|
||||
with self.original_prefs:
|
||||
for k, v in self.current_prefs.iteritems():
|
||||
self.original_prefs[k] = v
|
||||
|
||||
class CoverSettingsDialog(QDialog):
|
||||
|
||||
def __init__(self, mi=None, prefs=None, parent=None):
|
||||
@ -468,11 +507,11 @@ class CoverSettingsDialog(QDialog):
|
||||
l.addWidget(bb)
|
||||
bb.accepted.connect(self.accept), bb.rejected.connect(self.reject)
|
||||
bb.b = b = bb.addButton(_('Restore &defaults'), bb.ActionRole)
|
||||
b.clicked.connect(self.settings.restore_defaults)
|
||||
bb.b2 = b = bb.addButton(_('&Save as default settings'), bb.ActionRole)
|
||||
b.clicked.connect(self.settings.save_defaults)
|
||||
b.clicked.connect(self.restore_defaults)
|
||||
bb.b2 = b = bb.addButton(_('&Save settings'), bb.ActionRole)
|
||||
b.clicked.connect(self.settings.save_as_prefs)
|
||||
b.setToolTip('<p>' + _(
|
||||
'Save the current settings as the default settings. Remember that'
|
||||
'Save the current settings as the settings to use always instead of just this time. Remember that'
|
||||
' for styles and colors the actual style or color used is chosen at random from'
|
||||
' the list of checked styles/colors.'))
|
||||
|
||||
@ -480,6 +519,11 @@ class CoverSettingsDialog(QDialog):
|
||||
geom = gprefs.get('cover_settings_dialog_geom', None)
|
||||
if geom is not None:
|
||||
self.restoreGeometry(geom)
|
||||
self.prefs_for_rendering = None
|
||||
|
||||
def restore_defaults(self):
|
||||
self.settings.restore_defaults()
|
||||
self.settings.save_as_prefs()
|
||||
|
||||
def sizeHint(self):
|
||||
return QSize(800, 600)
|
||||
@ -487,6 +531,7 @@ class CoverSettingsDialog(QDialog):
|
||||
def accept(self):
|
||||
gprefs.set('cover_settings_dialog_geom', bytearray(self.saveGeometry()))
|
||||
self.settings.save_state()
|
||||
self.prefs_for_rendering = self.settings.prefs_for_rendering
|
||||
QDialog.accept(self)
|
||||
|
||||
def reject(self):
|
||||
|
@ -1048,7 +1048,11 @@ class Cover(ImageView): # {{{
|
||||
self.remove_cover_button = CB(_('&Remove'), 'trash.png', self.remove_cover)
|
||||
|
||||
self.download_cover_button = CB(_('Download co&ver'), 'arrow-down.png', self.download_cover)
|
||||
self.generate_cover_button = CB(_('&Generate cover'), 'default_cover.png', self.generate_cover)
|
||||
self.generate_cover_button = b = CB(_('&Generate cover'), 'default_cover.png', self.generate_cover)
|
||||
b.m = m = QMenu()
|
||||
b.setMenu(m)
|
||||
m.addAction(_('Customize the styles and colors of the generated cover'), self.custom_cover)
|
||||
b.setPopupMode(b.DelayedPopup)
|
||||
self.buttons = [self.select_cover_button, self.remove_cover_button,
|
||||
self.trim_cover_button, self.download_cover_button,
|
||||
self.generate_cover_button]
|
||||
@ -1129,6 +1133,14 @@ class Cover(ImageView): # {{{
|
||||
mi = self.dialog.to_book_metadata()
|
||||
self.current_val = generate_cover(mi)
|
||||
|
||||
def custom_cover(self):
|
||||
from calibre.ebooks.covers import generate_cover
|
||||
from calibre.gui2.covers import CoverSettingsDialog
|
||||
mi = self.dialog.to_book_metadata()
|
||||
d = CoverSettingsDialog(mi=mi, parent=self)
|
||||
if d.exec_() == d.Accepted:
|
||||
self.current_val = generate_cover(mi, prefs=d.prefs_for_rendering)
|
||||
|
||||
def set_pixmap_from_data(self, data):
|
||||
if not data:
|
||||
self.current_val = None
|
||||
|
Loading…
x
Reference in New Issue
Block a user