diff --git a/src/calibre/gui2/metadata/single.py b/src/calibre/gui2/metadata/single.py index d551e47883..ef75edd88a 100644 --- a/src/calibre/gui2/metadata/single.py +++ b/src/calibre/gui2/metadata/single.py @@ -11,10 +11,10 @@ import os from datetime import datetime from functools import partial from qt.core import ( - QApplication, QDialog, QDialogButtonBox, QFont, QFrame, - QGridLayout, QGroupBox, QHBoxLayout, QIcon, QInputDialog, QKeySequence, QMenu, - QPushButton, QScrollArea, QShortcut, QSize, QSizePolicy, QSpacerItem, QSplitter, - Qt, QTabWidget, QToolButton, QVBoxLayout, QWidget, pyqtSignal + QApplication, QDialog, QDialogButtonBox, QFont, QFrame, QGridLayout, QGroupBox, + QHBoxLayout, QIcon, QInputDialog, QKeySequence, QMenu, QPushButton, QScrollArea, + QShortcut, QSize, QSizePolicy, QSpacerItem, QSplitter, Qt, QTabWidget, + QToolButton, QVBoxLayout, QWidget, pyqtSignal ) from calibre.constants import ismacos @@ -30,6 +30,7 @@ from calibre.gui2.metadata.basic_widgets import ( TitleSortEdit, show_locked_file_error ) from calibre.gui2.metadata.single_download import FullFetch +from calibre.gui2.widgets2 import CenteredToolButton from calibre.library.comments import merge_comments as merge_two_comments from calibre.utils.config import tweaks from calibre.utils.date import local_tz @@ -269,26 +270,14 @@ class MetadataSingleDialogBase(QDialog): self.pubdate = PubdateEdit(self) self.basic_metadata_widgets.extend([self.timestamp, self.pubdate]) - self.fetch_metadata_button = b = RightClickButton(self) - # The following rigmarole is needed so that Qt gives the button the - # same height as the other buttons in the dialog. There is no way to - # center the text in a QToolButton with an icon, so we can't just set an - # icon - b.setIcon(QIcon(I('download-metadata.png'))) - b.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) - b.setMinimumHeight(b.sizeHint().height()) - b.setIcon(QIcon()) - b.setText(_('&Download metadata')), b.setPopupMode(QToolButton.ToolButtonPopupMode.DelayedPopup) + self.fetch_metadata_button = b = CenteredToolButton(QIcon(I('download-metadata.png')), _('&Download metadata'), self) + b.setPopupMode(QToolButton.ToolButtonPopupMode.DelayedPopup) b.setToolTip(_('Download metadata for this book [%s]') % self.download_shortcut.key().toString(QKeySequence.SequenceFormat.NativeText)) - b.setSizePolicy(QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)) self.fetch_metadata_button.clicked.connect(self.fetch_metadata) self.fetch_metadata_menu = m = QMenu(self.fetch_metadata_button) m.addAction(QIcon(I('edit-undo.png')), _('Undo last metadata download'), self.undo_fetch_metadata) self.fetch_metadata_button.setMenu(m) self.download_shortcut.activated.connect(self.fetch_metadata_button.click) - font = self.fmb_font = QFont() - font.setBold(True) - self.fetch_metadata_button.setFont(font) if self.use_toolbutton_for_config_metadata: self.config_metadata_button = QToolButton(self) diff --git a/src/calibre/gui2/widgets2.py b/src/calibre/gui2/widgets2.py index 90e18d3939..0dc71d0052 100644 --- a/src/calibre/gui2/widgets2.py +++ b/src/calibre/gui2/widgets2.py @@ -10,7 +10,7 @@ from qt.core import ( QFontInfo, QFontMetrics, QIcon, QKeySequence, QLabel, QLayout, QMenu, QMimeData, QPalette, QPixmap, QPoint, QPushButton, QRect, QScrollArea, QSize, QSizePolicy, QStyle, QStyledItemDelegate, Qt, QTabWidget, QTextBrowser, QToolButton, QTextCursor, - QUndoCommand, QUndoStack, QUrl, QWidget, pyqtSignal, QBrush, QPainter + QUndoCommand, QUndoStack, QUrl, QWidget, pyqtSignal, QBrush, QPainter, QProxyStyle ) from calibre.ebooks.metadata import rating_to_stars @@ -158,6 +158,59 @@ class RightClickButton(QToolButton): return QToolButton.mousePressEvent(self, ev) +class CenteredToolButtonStyle(QProxyStyle): + + def __init__(self, ctb): + super().__init__() + self.setParent(ctb) + self.draw_text_called = self.draw_pixmap_called = False + + def drawItemText(self, painter, rect, flags, palette, enabled, text, text_role=QPalette.ColorRole.NoRole): + b = self.parent() + if text != b.text(): + return super().drawItemText(painter, rect, flags, palette, enabled, text, QPalette.ColorRole.NoRole) + self.text_rect = rect + self.text_flags = flags | Qt.AlignmentFlag.AlignCenter + self.text_palette = palette + self.text_enabled = enabled + self.text_role = text_role + self.draw_text_called = True + self.draw_both(painter) + + def drawItemPixmap(self, painter, rect, alignment, pixmap): + self.pixmap_rect = rect + self.pixmap = pixmap + self.draw_pixmap_called = True + self.draw_both(painter) + + def draw_both(self, painter): + if not self.draw_pixmap_called or not self.draw_text_called: + return + self.draw_text_called = self.draw_pixmap_called = False + b = self.parent() + fm = QFontMetrics(b.font()) + w = b.iconSize().width() + full_rect = QRect(self.pixmap_rect.topLeft(), self.text_rect.bottomRight()) + space = self.text_rect.left() - self.pixmap_rect.right() + 1 + super().drawItemText(painter, full_rect, self.text_flags, self.text_palette, self.text_enabled, b.text(), self.text_role) + text_rect = self.itemTextRect(fm, full_rect, self.text_flags, self.text_enabled, b.text()) + left = max(0, text_rect.left() - w - space) + pixmap_rect = QRect(left, self.pixmap_rect.top(), text_rect.right() - space - left, self.pixmap_rect.height()) + super().drawItemPixmap(painter, pixmap_rect, Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter, self.pixmap) + + +class CenteredToolButton(RightClickButton): + + def __init__(self, icon, text, parent=None): + super().__init__(parent) + self.setText(text) + self.ps = CenteredToolButtonStyle(self) + self.setStyle(self.ps) + self.setIcon(icon) + self.setSizePolicy(QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)) + self.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) + + class Dialog(QDialog): '''