Rationalize collections column in device view

This commit is contained in:
Kovid Goyal 2010-05-20 10:28:41 -06:00
parent a28c63dc1f
commit 036c2fe68c
5 changed files with 47 additions and 20 deletions

View File

@ -391,8 +391,8 @@ class BookList(list):
def __init__(self, oncard, prefix, settings): def __init__(self, oncard, prefix, settings):
pass pass
def supports_tags(self): def supports_collections(self):
''' Return True if the the device supports tags (collections) for this book list. ''' ''' Return True if the the device supports collections for this book list. '''
raise NotImplementedError() raise NotImplementedError()
def add_book(self, book, replace_metadata): def add_book(self, book, replace_metadata):

View File

@ -14,6 +14,7 @@ from calibre.devices.prs505 import MEDIA_XML
from calibre.devices.prs505 import CACHE_XML from calibre.devices.prs505 import CACHE_XML
from calibre.devices.prs505.sony_cache import XMLCache from calibre.devices.prs505.sony_cache import XMLCache
from calibre import __appname__ from calibre import __appname__
from calibre.devices.usbms.books import CollectionsBookList
class PRS505(USBMS): class PRS505(USBMS):
@ -23,6 +24,8 @@ class PRS505(USBMS):
author = 'Kovid Goyal' author = 'Kovid Goyal'
supported_platforms = ['windows', 'osx', 'linux'] supported_platforms = ['windows', 'osx', 'linux']
path_sep = '/' path_sep = '/'
booklist_class = CollectionsBookList
FORMATS = ['epub', 'lrf', 'lrx', 'rtf', 'pdf', 'txt'] FORMATS = ['epub', 'lrf', 'lrx', 'rtf', 'pdf', 'txt']

View File

@ -97,8 +97,8 @@ class Book(MetaInformation):
class BookList(_BookList): class BookList(_BookList):
def supports_tags(self): def supports_collections(self):
return True return False
def add_book(self, book, replace_metadata): def add_book(self, book, replace_metadata):
if book not in self: if book not in self:
@ -109,6 +109,15 @@ class BookList(_BookList):
def remove_book(self, book): def remove_book(self, book):
self.remove(book) self.remove(book)
def get_collections(self):
return {}
class CollectionsBookList(BookList):
def supports_collections(self):
return True
def get_collections(self, collection_attributes): def get_collections(self, collection_attributes):
collections = {} collections = {}
series_categories = set([]) series_categories = set([])

View File

@ -729,6 +729,17 @@ class BooksModel(QAbstractTableModel): # {{{
class OnDeviceSearch(SearchQueryParser): # {{{ class OnDeviceSearch(SearchQueryParser): # {{{
DEFAULT_LOCATIONS = [
'collections',
'title',
'author',
'format',
'search',
'date',
'all',
]
def __init__(self, model): def __init__(self, model):
SearchQueryParser.__init__(self) SearchQueryParser.__init__(self)
self.model = model self.model = model
@ -738,6 +749,8 @@ class OnDeviceSearch(SearchQueryParser): # {{{
def get_matches(self, location, query): def get_matches(self, location, query):
location = location.lower().strip() location = location.lower().strip()
if location == 'authors':
location = 'author'
matchkind = CONTAINS_MATCH matchkind = CONTAINS_MATCH
if len(query) > 1: if len(query) > 1:
@ -752,14 +765,15 @@ class OnDeviceSearch(SearchQueryParser): # {{{
if matchkind != REGEXP_MATCH: ### leave case in regexps because it can be significant e.g. \S \W \D if matchkind != REGEXP_MATCH: ### leave case in regexps because it can be significant e.g. \S \W \D
query = query.lower() query = query.lower()
if location not in ('title', 'author', 'tag', 'all', 'format'): if location not in self.DEFAULT_LOCATIONS:
return set([]) return set([])
matches = set([]) matches = set([])
locations = ['title', 'author', 'tag', 'format'] if location == 'all' else [location] all_locs = set(self.DEFAULT_LOCATIONS) - set(['all'])
locations = all_locs if location == 'all' else [location]
q = { q = {
'title' : lambda x : getattr(x, 'title').lower(), 'title' : lambda x : getattr(x, 'title').lower(),
'author': lambda x: ' & '.join(getattr(x, 'authors')).lower(), 'author': lambda x: ' & '.join(getattr(x, 'authors')).lower(),
'tag':lambda x: ','.join(getattr(x, 'tags')).lower(), 'collections':lambda x: ','.join(getattr(x, 'device_collections')).lower(),
'format':lambda x: os.path.splitext(x.path)[1].lower() 'format':lambda x: os.path.splitext(x.path)[1].lower()
} }
for index, row in enumerate(self.model.db): for index, row in enumerate(self.model.db):
@ -774,7 +788,7 @@ class OnDeviceSearch(SearchQueryParser): # {{{
else: else:
m = matchkind m = matchkind
if locvalue == 'tag': if locvalue == 'collections':
vals = accessor(row).split(',') vals = accessor(row).split(',')
else: else:
vals = [accessor(row)] vals = [accessor(row)]
@ -800,14 +814,14 @@ class DeviceBooksModel(BooksModel): # {{{
self.sort_history = [self.sorted_on] self.sort_history = [self.sorted_on]
self.unknown = _('Unknown') self.unknown = _('Unknown')
self.column_map = ['inlibrary', 'title', 'authors', 'timestamp', 'size', self.column_map = ['inlibrary', 'title', 'authors', 'timestamp', 'size',
'tags'] 'collections']
self.headers = { self.headers = {
'inlibrary' : _('In Library'), 'inlibrary' : _('In Library'),
'title' : _('Title'), 'title' : _('Title'),
'authors' : _('Author(s)'), 'authors' : _('Author(s)'),
'timestamp' : _('Date'), 'timestamp' : _('Date'),
'size' : _('Size'), 'size' : _('Size'),
'tags' : _('Collections') 'collections' : _('Collections')
} }
self.marked_for_deletion = {} self.marked_for_deletion = {}
self.search_engine = OnDeviceSearch(self) self.search_engine = OnDeviceSearch(self)
@ -846,7 +860,8 @@ class DeviceBooksModel(BooksModel): # {{{
flags = QAbstractTableModel.flags(self, index) flags = QAbstractTableModel.flags(self, index)
if index.isValid() and self.editable: if index.isValid() and self.editable:
cname = self.column_map[index.column()] cname = self.column_map[index.column()]
if cname in ('title', 'authors') or (cname == 'tags' and self.db.supports_tags()): if cname in ('title', 'authors') or (cname == 'collection' and \
self.db.supports_collections()):
flags |= Qt.ItemIsEditable flags |= Qt.ItemIsEditable
return flags return flags
@ -918,7 +933,7 @@ class DeviceBooksModel(BooksModel): # {{{
'authors' : authorcmp, 'authors' : authorcmp,
'size' : sizecmp, 'size' : sizecmp,
'timestamp': datecmp, 'timestamp': datecmp,
'tags': tagscmp, 'collections': tagscmp,
'inlibrary': libcmp, 'inlibrary': libcmp,
}[cname] }[cname]
self.map.sort(cmp=fcmp, reverse=descending) self.map.sort(cmp=fcmp, reverse=descending)
@ -1000,14 +1015,15 @@ class DeviceBooksModel(BooksModel): # {{{
dt = self.db[self.map[row]].datetime dt = self.db[self.map[row]].datetime
dt = dt_factory(dt, assume_utc=True, as_utc=False) dt = dt_factory(dt, assume_utc=True, as_utc=False)
return QVariant(strftime(TIME_FMT, dt.timetuple())) return QVariant(strftime(TIME_FMT, dt.timetuple()))
elif cname == 'tags': elif cname == 'collections':
tags = self.db[self.map[row]].device_collections tags = self.db[self.map[row]].device_collections
if tags: if tags:
return QVariant(', '.join(tags)) return QVariant(', '.join(tags))
elif role == Qt.ToolTipRole and index.isValid(): elif role == Qt.ToolTipRole and index.isValid():
if self.map[row] in self.indices_to_be_deleted(): if self.map[row] in self.indices_to_be_deleted():
return QVariant(_('Marked for deletion')) return QVariant(_('Marked for deletion'))
if cname in ['title', 'authors'] or (cname == 'tags' and self.db.supports_tags()): if cname in ['title', 'authors'] or (cname == 'collections' and \
self.db.supports_collections()):
return QVariant(_("Double click to <b>edit</b> me<br><br>")) return QVariant(_("Double click to <b>edit</b> me<br><br>"))
elif role == Qt.DecorationRole and cname == 'inlibrary': elif role == Qt.DecorationRole and cname == 'inlibrary':
if self.db[self.map[row]].in_library: if self.db[self.map[row]].in_library:

View File

@ -222,7 +222,6 @@ class BooksView(QTableView): # {{{
return return
for col, order in reversed(self.cleanup_sort_history(saved_history)[:3]): for col, order in reversed(self.cleanup_sort_history(saved_history)[:3]):
self.sortByColumn(self.column_map.index(col), order) self.sortByColumn(self.column_map.index(col), order)
#self.model().sort_history = saved_history
def apply_state(self, state): def apply_state(self, state):
h = self.column_header h = self.column_header