%PDF- %PDF-
Direktori : /usr/lib/calibre/calibre/gui2/viewer/ |
Current File : //usr/lib/calibre/calibre/gui2/viewer/widgets.py |
#!/usr/bin/env python3 # License: GPL v3 Copyright: 2020, Kovid Goyal <kovid at kovidgoyal.net> import re from qt.core import ( QAction, QFont, QFontMetrics, QStyle, QStyledItemDelegate, Qt, pyqtSignal, QPalette ) from calibre.gui2 import QT_HIDDEN_CLEAR_ACTION from calibre.gui2.widgets2 import HistoryComboBox class ResultsDelegate(QStyledItemDelegate): # {{{ add_ellipsis = True emphasize_text = True def result_data(self, result): if not hasattr(result, 'is_hidden'): return None, None, None, None, None return result.is_hidden, result.before, result.text, result.after, False def paint(self, painter, option, index): QStyledItemDelegate.paint(self, painter, option, index) result = index.data(Qt.ItemDataRole.UserRole) is_hidden, result_before, result_text, result_after, show_leading_dot = self.result_data(result) if result_text is None: return painter.save() try: p = option.palette c = QPalette.ColorRole.HighlightedText if option.state & QStyle.StateFlag.State_Selected else QPalette.ColorRole.Text group = (QPalette.ColorGroup.Active if option.state & QStyle.StateFlag.State_Active else QPalette.ColorGroup.Inactive) c = p.color(group, c) painter.setPen(c) font = option.font if self.emphasize_text: emphasis_font = QFont(font) emphasis_font.setBold(True) else: emphasis_font = font flags = Qt.AlignmentFlag.AlignTop | Qt.TextFlag.TextSingleLine | Qt.TextFlag.TextIncludeTrailingSpaces rect = option.rect.adjusted(option.decorationSize.width() + 4 if is_hidden else 0, 0, 0, 0) painter.setClipRect(rect) before = re.sub(r'\s+', ' ', result_before) if show_leading_dot: before = '•' + before before_width = 0 if before: before_width = painter.boundingRect(rect, flags, before).width() after = re.sub(r'\s+', ' ', result_after.rstrip()) after_width = 0 if after: after_width = painter.boundingRect(rect, flags, after).width() ellipsis_width = painter.boundingRect(rect, flags, '...').width() painter.setFont(emphasis_font) text = re.sub(r'\s+', ' ', result_text) match_width = painter.boundingRect(rect, flags, text).width() if match_width >= rect.width() - 3 * ellipsis_width: efm = QFontMetrics(emphasis_font) if show_leading_dot: text = '•' + text text = efm.elidedText(text, Qt.TextElideMode.ElideRight, rect.width()) painter.drawText(rect, flags, text) else: self.draw_match( painter, flags, before, text, after, rect, before_width, match_width, after_width, ellipsis_width, emphasis_font, font) except Exception: import traceback traceback.print_exc() painter.restore() def draw_match(self, painter, flags, before, text, after, rect, before_width, match_width, after_width, ellipsis_width, emphasis_font, normal_font): extra_width = int(rect.width() - match_width) if before_width < after_width: left_width = min(extra_width // 2, before_width) right_width = extra_width - left_width else: right_width = min(extra_width // 2, after_width) left_width = min(before_width, extra_width - right_width) x = rect.left() nfm = QFontMetrics(normal_font) if before_width and left_width: r = rect.adjusted(0, 0, 0, 0) r.setRight(x + left_width) painter.setFont(normal_font) ebefore = nfm.elidedText(before, Qt.TextElideMode.ElideLeft, left_width) if self.add_ellipsis and ebefore == before: ebefore = '…' + before[1:] r.setLeft(x) x += painter.drawText(r, flags, ebefore).width() painter.setFont(emphasis_font) r = rect.adjusted(0, 0, 0, 0) r.setLeft(x) painter.drawText(r, flags, text).width() x += match_width if after_width and right_width: painter.setFont(normal_font) r = rect.adjusted(0, 0, 0, 0) r.setLeft(x) eafter = nfm.elidedText(after, Qt.TextElideMode.ElideRight, right_width) if self.add_ellipsis and eafter == after: eafter = after[:-1] + '…' painter.setFont(normal_font) painter.drawText(r, flags, eafter) # }}} class SearchBox(HistoryComboBox): # {{{ history_saved = pyqtSignal(object, object) history_cleared = pyqtSignal() cleared = pyqtSignal() def __init__(self, parent=None): HistoryComboBox.__init__(self, parent) self.lineEdit().setPlaceholderText(_('Search')) self.lineEdit().setClearButtonEnabled(True) ac = self.lineEdit().findChild(QAction, QT_HIDDEN_CLEAR_ACTION) if ac is not None: ac.triggered.connect(self.cleared) def save_history(self): ret = HistoryComboBox.save_history(self) self.history_saved.emit(self.text(), self.history) return ret def clear_history(self): super().clear_history() self.history_cleared.emit() def contextMenuEvent(self, event): menu = self.lineEdit().createStandardContextMenu() menu.addSeparator() menu.addAction(_('Clear search history'), self.clear_history) menu.exec(event.globalPos()) # }}}