mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Store: Filter in Matches model.
This commit is contained in:
parent
f9a931dbfb
commit
b415c44cb6
@ -112,6 +112,9 @@ class SearchDialog(QDialog, Ui_Dialog):
|
|||||||
query = unicode(self.search_edit.text())
|
query = unicode(self.search_edit.text())
|
||||||
if not query.strip():
|
if not query.strip():
|
||||||
return
|
return
|
||||||
|
# Give the query to the results model so it can do
|
||||||
|
# futher filtering.
|
||||||
|
self.results_view.model().set_query(query)
|
||||||
|
|
||||||
# Plugins are in alphebetic order. Randomize the
|
# Plugins are in alphebetic order. Randomize the
|
||||||
# order of plugin names. This way plugins closer
|
# order of plugin names. This way plugins closer
|
||||||
@ -304,12 +307,11 @@ class SearchThread(Thread):
|
|||||||
while self._run and not self.tasks.empty():
|
while self._run and not self.tasks.empty():
|
||||||
try:
|
try:
|
||||||
query, store_name, store_plugin, timeout = self.tasks.get()
|
query, store_name, store_plugin, timeout = self.tasks.get()
|
||||||
squery = self._clean_query(query)
|
query = self._clean_query(query)
|
||||||
for res in store_plugin.search(squery, timeout=timeout):
|
for res in store_plugin.search(query, timeout=timeout):
|
||||||
if not self._run:
|
if not self._run:
|
||||||
return
|
return
|
||||||
res.store_name = store_name
|
res.store_name = store_name
|
||||||
if SearchFilter(res).parse(query):
|
|
||||||
self.results.put(res)
|
self.results.put(res)
|
||||||
self.tasks.task_done()
|
self.tasks.task_done()
|
||||||
except:
|
except:
|
||||||
@ -390,7 +392,14 @@ class Matches(QAbstractItemModel):
|
|||||||
self.DRM_UNLOCKED_ICON = QPixmap(I('drm-unlocked.png')).scaledToHeight(64)
|
self.DRM_UNLOCKED_ICON = QPixmap(I('drm-unlocked.png')).scaledToHeight(64)
|
||||||
self.DRM_UNKNOWN_ICON = QPixmap(I('dialog_warning.png')).scaledToHeight(64)
|
self.DRM_UNKNOWN_ICON = QPixmap(I('dialog_warning.png')).scaledToHeight(64)
|
||||||
|
|
||||||
|
# All matches. Used to determine the order to display
|
||||||
|
# self.matches because the SearchFilter returns
|
||||||
|
# matches unordered.
|
||||||
|
self.all_matches = []
|
||||||
|
# Only the showing matches.
|
||||||
self.matches = []
|
self.matches = []
|
||||||
|
self.query = ''
|
||||||
|
self.search_filter = SearchFilter()
|
||||||
self.cover_pool = CoverThreadPool(CoverThread, 2)
|
self.cover_pool = CoverThreadPool(CoverThread, 2)
|
||||||
self.cover_pool.start_threads()
|
self.cover_pool.start_threads()
|
||||||
|
|
||||||
@ -398,15 +407,21 @@ class Matches(QAbstractItemModel):
|
|||||||
self.cover_pool.abort()
|
self.cover_pool.abort()
|
||||||
|
|
||||||
def clear_results(self):
|
def clear_results(self):
|
||||||
|
self.all_matches = []
|
||||||
self.matches = []
|
self.matches = []
|
||||||
|
self.all_matches = []
|
||||||
|
self.search_filter.clear_search_results()
|
||||||
|
self.query = ''
|
||||||
self.cover_pool.abort()
|
self.cover_pool.abort()
|
||||||
self.cover_pool.start_threads()
|
self.cover_pool.start_threads()
|
||||||
self.reset()
|
self.reset()
|
||||||
|
|
||||||
def add_result(self, result):
|
def add_result(self, result):
|
||||||
self.layoutAboutToBeChanged.emit()
|
self.layoutAboutToBeChanged.emit()
|
||||||
self.matches.append(result)
|
self.all_matches.append(result)
|
||||||
self.cover_pool.add_task(result, self.update_result)
|
self.search_filter.add_search_result(result)
|
||||||
|
self.cover_pool.add_task(result, self.filter_results)
|
||||||
|
self.filter_results()
|
||||||
self.layoutChanged.emit()
|
self.layoutChanged.emit()
|
||||||
|
|
||||||
def get_result(self, index):
|
def get_result(self, index):
|
||||||
@ -416,9 +431,17 @@ class Matches(QAbstractItemModel):
|
|||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def update_result(self):
|
def filter_results(self):
|
||||||
self.layoutAboutToBeChanged.emit()
|
self.layoutAboutToBeChanged.emit()
|
||||||
self.layoutChanged.emit()
|
if self.query:
|
||||||
|
self.matches = list(self.search_filter.parse(self.query))
|
||||||
|
else:
|
||||||
|
self.matches = list(self.search_filter.universal_set())
|
||||||
|
self.reorder_matches()
|
||||||
|
self.layoutAboutToBeChanged.emit()
|
||||||
|
|
||||||
|
def set_query(self, query):
|
||||||
|
self.query = query
|
||||||
|
|
||||||
def index(self, row, column, parent=QModelIndex()):
|
def index(self, row, column, parent=QModelIndex()):
|
||||||
return self.createIndex(row, column)
|
return self.createIndex(row, column)
|
||||||
@ -497,12 +520,16 @@ class Matches(QAbstractItemModel):
|
|||||||
if not self.matches:
|
if not self.matches:
|
||||||
return
|
return
|
||||||
descending = order == Qt.DescendingOrder
|
descending = order == Qt.DescendingOrder
|
||||||
self.matches.sort(None,
|
self.all_matches.sort(None,
|
||||||
lambda x: sort_key(unicode(self.data_as_text(x, col))),
|
lambda x: sort_key(unicode(self.data_as_text(x, col))),
|
||||||
descending)
|
descending)
|
||||||
|
self.reorder_matches()
|
||||||
if reset:
|
if reset:
|
||||||
self.reset()
|
self.reset()
|
||||||
|
|
||||||
|
def reorder_matches(self):
|
||||||
|
self.matches = sorted(self.matches, key=lambda x: self.all_matches.index(x))
|
||||||
|
|
||||||
|
|
||||||
class SearchFilter(SearchQueryParser):
|
class SearchFilter(SearchQueryParser):
|
||||||
|
|
||||||
@ -517,12 +544,18 @@ class SearchFilter(SearchQueryParser):
|
|||||||
'store',
|
'store',
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, search_result):
|
def __init__(self):
|
||||||
SearchQueryParser.__init__(self, locations=self.USABLE_LOCATIONS)
|
SearchQueryParser.__init__(self, locations=self.USABLE_LOCATIONS)
|
||||||
self.search_result = search_result
|
self.srs = set([])
|
||||||
|
|
||||||
|
def add_search_result(self, search_result):
|
||||||
|
self.srs.add(search_result)
|
||||||
|
|
||||||
|
def clear_search_results(self):
|
||||||
|
self.srs = set([])
|
||||||
|
|
||||||
def universal_set(self):
|
def universal_set(self):
|
||||||
return set([self.search_result])
|
return self.srs
|
||||||
|
|
||||||
def get_matches(self, location, query):
|
def get_matches(self, location, query):
|
||||||
location = location.lower().strip()
|
location = location.lower().strip()
|
||||||
@ -548,33 +581,34 @@ class SearchFilter(SearchQueryParser):
|
|||||||
all_locs = set(self.USABLE_LOCATIONS) - set(['all'])
|
all_locs = set(self.USABLE_LOCATIONS) - set(['all'])
|
||||||
locations = all_locs if location == 'all' else [location]
|
locations = all_locs if location == 'all' else [location]
|
||||||
q = {
|
q = {
|
||||||
'author': self.search_result.author.lower(),
|
'author': lambda x: x.author.lower(),
|
||||||
'cover': self.search_result.cover_url,
|
'cover': lambda x: x.cover_url,
|
||||||
'drm': self.search_result.drm,
|
'drm': lambda x: x.drm,
|
||||||
'format': '',
|
'format': '',
|
||||||
'price': comparable_price(self.search_result.price),
|
'price': lambda x: comparable_price(x.price),
|
||||||
'store': self.search_result.store_name.lower(),
|
'store': lambda x: x.store_name.lower(),
|
||||||
'title': self.search_result.title.lower(),
|
'title': lambda x: x.title.lower(),
|
||||||
}
|
}
|
||||||
for x in ('author', 'format'):
|
for x in ('author', 'format'):
|
||||||
q[x+'s'] = q[x]
|
q[x+'s'] = q[x]
|
||||||
|
for sr in self.srs:
|
||||||
for locvalue in locations:
|
for locvalue in locations:
|
||||||
ac_val = q[locvalue]
|
accessor = q[locvalue]
|
||||||
if query == 'true':
|
if query == 'true':
|
||||||
if locvalue == 'drm':
|
if locvalue == 'drm':
|
||||||
if ac_val == True:
|
if accessor(sr) == True:
|
||||||
matches.add(self.search_result)
|
matches.add(sr)
|
||||||
else:
|
else:
|
||||||
if ac_val is not None:
|
if accessor(sr) is not None:
|
||||||
matches.add(self.search_result)
|
matches.add(sr)
|
||||||
continue
|
continue
|
||||||
if query == 'false':
|
if query == 'false':
|
||||||
if locvalue == 'drm':
|
if locvalue == 'drm':
|
||||||
if ac_val == False:
|
if accessor(sr) == False:
|
||||||
matches.add(self.search_result)
|
matches.add(sr)
|
||||||
else:
|
else:
|
||||||
if ac_val is None:
|
if accessor(sr) is None:
|
||||||
matches.add(self.search_result)
|
matches.add(sr)
|
||||||
continue
|
continue
|
||||||
# this is bool, so can't match below
|
# this is bool, so can't match below
|
||||||
if locvalue == 'drm':
|
if locvalue == 'drm':
|
||||||
@ -588,9 +622,9 @@ class SearchFilter(SearchQueryParser):
|
|||||||
else:
|
else:
|
||||||
m = matchkind
|
m = matchkind
|
||||||
|
|
||||||
vals = [ac_val]
|
vals = [accessor(sr)]
|
||||||
if _match(query, vals, m):
|
if _match(query, vals, m):
|
||||||
matches.add(self.search_result)
|
matches.add(sr)
|
||||||
break
|
break
|
||||||
except ValueError: # Unicode errors
|
except ValueError: # Unicode errors
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user