mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Rather than remove matches for hidden text, simply mark them as not visible
This commit is contained in:
parent
ae109d8f91
commit
6c29207c87
@ -10,9 +10,9 @@ from threading import Thread
|
||||
|
||||
import regex
|
||||
from PyQt5.Qt import (
|
||||
QCheckBox, QComboBox, QHBoxLayout, QIcon, QLabel, QListWidget, QListWidgetItem,
|
||||
QStaticText, QStyle, QStyledItemDelegate, Qt, QToolButton, QVBoxLayout, QWidget,
|
||||
pyqtSignal
|
||||
QCheckBox, QComboBox, QHBoxLayout, QIcon, QLabel, QListWidget,
|
||||
QListWidgetItem, QStaticText, QStyle, QStyledItemDelegate, Qt, QToolButton,
|
||||
QVBoxLayout, QWidget, pyqtSignal
|
||||
)
|
||||
|
||||
from calibre.ebooks.conversion.search_replace import REGEX_FLAGS
|
||||
@ -20,7 +20,6 @@ from calibre.gui2 import warning_dialog
|
||||
from calibre.gui2.progress_indicator import ProgressIndicator
|
||||
from calibre.gui2.viewer.web_view import get_data, get_manifest, vprefs
|
||||
from calibre.gui2.widgets2 import HistoryComboBox
|
||||
from calibre.utils.monotonic import monotonic
|
||||
from polyglot.builtins import iteritems, unicode_type
|
||||
from polyglot.functools import lru_cache
|
||||
from polyglot.queue import Queue
|
||||
@ -116,7 +115,7 @@ class SearchFinished(object):
|
||||
|
||||
class SearchResult(object):
|
||||
|
||||
__slots__ = ('search_query', 'before', 'text', 'after', 'q', 'spine_idx', 'index', 'file_name', '_static_text')
|
||||
__slots__ = ('search_query', 'before', 'text', 'after', 'q', 'spine_idx', 'index', 'file_name', '_static_text', 'is_hidden')
|
||||
|
||||
def __init__(self, search_query, before, text, after, q, name, spine_idx, index):
|
||||
self.search_query = search_query
|
||||
@ -125,6 +124,7 @@ class SearchResult(object):
|
||||
self.spine_idx, self.index = spine_idx, index
|
||||
self.file_name = name
|
||||
self._static_text = None
|
||||
self.is_hidden = False
|
||||
|
||||
@property
|
||||
def static_text(self):
|
||||
@ -148,11 +148,11 @@ class SearchResult(object):
|
||||
def for_js(self):
|
||||
return {
|
||||
'file_name': self.file_name, 'spine_idx': self.spine_idx, 'index': self.index, 'text': self.text,
|
||||
'before': self.before, 'after': self.after, 'mode': self.search_query.mode
|
||||
'before': self.before, 'after': self.after, 'mode': self.search_query.mode, 'q': self.q
|
||||
}
|
||||
|
||||
def is_result(self, result_from_js):
|
||||
return result_from_js['spine_idx'] == self.spine_idx and self.index == result_from_js['index'] and result_from_js['text'] == self.text
|
||||
return result_from_js['spine_idx'] == self.spine_idx and self.index == result_from_js['index'] and result_from_js['q'] == self.q
|
||||
|
||||
def __str__(self):
|
||||
from collections import namedtuple
|
||||
@ -344,8 +344,14 @@ class ResultsDelegate(QStyledItemDelegate): # {{{
|
||||
c = p.color(group, c)
|
||||
painter.setClipRect(option.rect)
|
||||
painter.setPen(c)
|
||||
height = result.static_text.size().height()
|
||||
tl = option.rect.topLeft()
|
||||
x, y = tl.x(), tl.y()
|
||||
y += (option.rect.height() - height) // 2
|
||||
if result.is_hidden:
|
||||
x += option.decorationSize.width() + 4
|
||||
try:
|
||||
painter.drawStaticText(option.rect.topLeft(), result.static_text)
|
||||
painter.drawStaticText(x, y, result.static_text)
|
||||
except Exception:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
@ -360,21 +366,23 @@ class Results(QListWidget): # {{{
|
||||
def __init__(self, parent=None):
|
||||
QListWidget.__init__(self, parent)
|
||||
self.setFocusPolicy(Qt.NoFocus)
|
||||
self.setStyleSheet('QListWidget::item { padding: 3px; }')
|
||||
self.delegate = ResultsDelegate(self)
|
||||
self.setItemDelegate(self.delegate)
|
||||
self.itemClicked.connect(self.item_activated)
|
||||
self.blank_icon = QIcon(I('blank.png'))
|
||||
|
||||
def add_result(self, result):
|
||||
i = QListWidgetItem(' ', self)
|
||||
i.setData(Qt.UserRole, result)
|
||||
i.setIcon(self.blank_icon)
|
||||
return self.count()
|
||||
|
||||
def item_activated(self):
|
||||
i = self.currentItem()
|
||||
if i:
|
||||
sr = i.data(Qt.UserRole)
|
||||
self.show_search_result.emit(sr)
|
||||
if not sr.is_hidden:
|
||||
self.show_search_result.emit(sr)
|
||||
|
||||
def find_next(self, previous):
|
||||
if self.count() < 1:
|
||||
@ -386,24 +394,14 @@ class Results(QListWidget): # {{{
|
||||
self.item_activated()
|
||||
|
||||
def search_result_not_found(self, sr):
|
||||
remove = None
|
||||
for i in range(self.count()):
|
||||
item = self.item(i)
|
||||
r = item.data(Qt.UserRole)
|
||||
if r.is_result(sr):
|
||||
remove = i
|
||||
if remove is not None:
|
||||
q = sr['spine_idx']
|
||||
for i in range(remove + 1, self.count()):
|
||||
item = self.item(i)
|
||||
r = item.data(Qt.UserRole)
|
||||
if r.spine_index != q:
|
||||
break
|
||||
r.index -= 1
|
||||
self.takeItem(remove)
|
||||
if self.count():
|
||||
self.setCurrentRow(min(remove, self.count()-1))
|
||||
self.item_activated()
|
||||
r.is_hidden = True
|
||||
item.setToolTip(_('This text is hidden in the book, so cannot be displayed'))
|
||||
item.setIcon(QIcon(I('dialog_warning.png')))
|
||||
break
|
||||
# }}}
|
||||
|
||||
|
||||
@ -520,24 +518,8 @@ class SearchPanel(QWidget): # {{{
|
||||
|
||||
def search_result_not_found(self, sr):
|
||||
self.results.search_result_not_found(sr)
|
||||
if self.results.count():
|
||||
now = monotonic()
|
||||
if self.last_hidden_text_warning is None or self.current_search != self.last_hidden_text_warning[1] or now - self.last_hidden_text_warning[0] > 5:
|
||||
self.last_hidden_text_warning = now, self.current_search
|
||||
warning_dialog(self, _('Hidden text'), _(
|
||||
'Some search results were for hidden or non-reflowable text, they will be removed.'), show=True)
|
||||
elif self.last_hidden_text_warning is not None:
|
||||
self.last_hidden_text_warning = now, self.last_hidden_text_warning[1]
|
||||
|
||||
if not self.results.count() and not self.spinner.is_running:
|
||||
self.show_no_results_found()
|
||||
|
||||
def show_no_results_found(self):
|
||||
has_hidden_text = self.last_hidden_text_warning is not None and self.last_hidden_text_warning[1] == self.current_search
|
||||
if self.current_search:
|
||||
if has_hidden_text:
|
||||
msg = _('No displayable matches were found for:')
|
||||
else:
|
||||
msg = _('No matches were found for:')
|
||||
warning_dialog(self, _('No matches found'), msg + ' <b>{}</b>'.format(self.current_search.text), show=True)
|
||||
msg = _('No matches were found for:')
|
||||
warning_dialog(self, _('No matches found'), msg + ' <b>{}</b>'.format(self.current_search.text), show=True)
|
||||
# }}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user