mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Mark matching books for deletion feature.
The changes to device.py fix a bug that is independent of the feature.
This commit is contained in:
parent
c484f4316e
commit
94598bd844
@ -471,6 +471,21 @@ class DeleteAction(object): # {{{
|
||||
if ids:
|
||||
self.tags_view.recount()
|
||||
|
||||
def mark_matching_for_removal(self, *args):
|
||||
ids = self._get_selected_ids()
|
||||
if not ids:
|
||||
return
|
||||
db = self.library_view.model().db
|
||||
for model in (self.memory_view.model(), self.card_a_view.model(),
|
||||
self.card_b_view.model()):
|
||||
ids_to_mark = []
|
||||
for id in ids:
|
||||
uuid = db.uuid(id, index_is_id=True)
|
||||
for book in model.db:
|
||||
if getattr(book, 'uuid', None) == uuid:
|
||||
ids_to_mark.append(id)
|
||||
break
|
||||
model.clear_ondevice(ids_to_mark, to_what=False)
|
||||
|
||||
def delete_covers(self, *args):
|
||||
ids = self._get_selected_ids()
|
||||
|
@ -1347,7 +1347,7 @@ class DeviceMixin(object): # {{{
|
||||
if reset:
|
||||
# First build a cache of the library, so the search isn't On**2
|
||||
self.db_book_title_cache = {}
|
||||
self.db_book_uuid_cache = set()
|
||||
self.db_book_uuid_cache = {}
|
||||
db = self.library_view.model().db
|
||||
for id in db.data.iterallids():
|
||||
mi = db.get_metadata(id, index_is_id=True)
|
||||
@ -1364,7 +1364,7 @@ class DeviceMixin(object): # {{{
|
||||
aus = re.sub('(?u)\W|[_]', '', aus)
|
||||
self.db_book_title_cache[title]['author_sort'][aus] = mi
|
||||
self.db_book_title_cache[title]['db_ids'][mi.application_id] = mi
|
||||
self.db_book_uuid_cache.add(mi.uuid)
|
||||
self.db_book_uuid_cache[mi.uuid] = mi.application_id
|
||||
|
||||
# Now iterate through all the books on the device, setting the
|
||||
# in_library field Fastest and most accurate key is the uuid. Second is
|
||||
@ -1376,11 +1376,13 @@ class DeviceMixin(object): # {{{
|
||||
for book in booklist:
|
||||
if getattr(book, 'uuid', None) in self.db_book_uuid_cache:
|
||||
book.in_library = True
|
||||
# ensure that the correct application_id is set
|
||||
book.application_id = self.db_book_uuid_cache[book.uuid]
|
||||
continue
|
||||
|
||||
book_title = book.title.lower() if book.title else ''
|
||||
book_title = re.sub('(?u)\W|[_]', '', book_title)
|
||||
book.in_library = False
|
||||
book.in_library = None
|
||||
d = self.db_book_title_cache.get(book_title, None)
|
||||
if d is not None:
|
||||
if getattr(book, 'application_id', None) in d['db_ids']:
|
||||
|
@ -131,6 +131,9 @@ class ToolbarMixin(object): # {{{
|
||||
self.delete_all_but_selected_formats)
|
||||
self.delete_menu.addAction(
|
||||
_('Remove covers from selected books'), self.delete_covers)
|
||||
self.delete_menu.addAction(
|
||||
_('Mark matching books on device for removal'),
|
||||
self.mark_matching_for_removal)
|
||||
self.action_del.setMenu(self.delete_menu)
|
||||
|
||||
self.action_open_containing_folder.setShortcut(Qt.Key_O)
|
||||
|
@ -769,6 +769,7 @@ class OnDeviceSearch(SearchQueryParser): # {{{
|
||||
'format',
|
||||
'formats',
|
||||
'title',
|
||||
'inlibrary'
|
||||
]
|
||||
|
||||
|
||||
@ -807,12 +808,21 @@ class OnDeviceSearch(SearchQueryParser): # {{{
|
||||
'author': lambda x: ' & '.join(getattr(x, 'authors')).lower(),
|
||||
'collections':lambda x: ','.join(getattr(x, 'device_collections')).lower(),
|
||||
'format':lambda x: os.path.splitext(x.path)[1].lower(),
|
||||
'inlibrary':lambda x : getattr(x, 'in_library')
|
||||
}
|
||||
for x in ('author', 'format'):
|
||||
q[x+'s'] = q[x]
|
||||
for index, row in enumerate(self.model.db):
|
||||
for locvalue in locations:
|
||||
accessor = q[locvalue]
|
||||
if query == 'true':
|
||||
if accessor(row) is not None:
|
||||
matches.add(index)
|
||||
continue
|
||||
if query == 'false':
|
||||
if accessor(row) is None:
|
||||
matches.add(index)
|
||||
continue
|
||||
try:
|
||||
### Can't separate authors because comma is used for name sep and author sep
|
||||
### Exact match might not get what you want. For that reason, turn author
|
||||
@ -888,13 +898,13 @@ class DeviceBooksModel(BooksModel): # {{{
|
||||
ans.extend(v)
|
||||
return ans
|
||||
|
||||
def clear_ondevice(self, db_ids):
|
||||
def clear_ondevice(self, db_ids, to_what=None):
|
||||
for data in self.db:
|
||||
if data is None:
|
||||
continue
|
||||
app_id = getattr(data, 'application_id', None)
|
||||
if app_id is not None and app_id in db_ids:
|
||||
data.in_library = False
|
||||
data.in_library = to_what
|
||||
self.reset()
|
||||
|
||||
def flags(self, index):
|
||||
@ -1089,6 +1099,8 @@ class DeviceBooksModel(BooksModel): # {{{
|
||||
elif role == Qt.DecorationRole and cname == 'inlibrary':
|
||||
if self.db[self.map[row]].in_library:
|
||||
return QVariant(self.bool_yes_icon)
|
||||
elif self.db[self.map[row]].in_library is not None:
|
||||
return QVariant(self.bool_no_icon)
|
||||
elif role == Qt.TextAlignmentRole:
|
||||
cname = self.column_map[index.column()]
|
||||
ans = Qt.AlignVCenter | ALIGNMENT_MAP[self.alignment_map.get(cname,
|
||||
|
Loading…
x
Reference in New Issue
Block a user