diff --git a/src/calibre/ebooks/metadata/book/base.py b/src/calibre/ebooks/metadata/book/base.py index 3f5507d676..caaaccb3d0 100644 --- a/src/calibre/ebooks/metadata/book/base.py +++ b/src/calibre/ebooks/metadata/book/base.py @@ -12,7 +12,8 @@ from calibre import prints from calibre.ebooks.metadata.book import COPYABLE_METADATA_FIELDS from calibre.ebooks.metadata.book import STANDARD_METADATA_FIELDS from calibre.ebooks.metadata.book import TOP_LEVEL_CLASSIFIERS -from calibre.utils.date import isoformat +from calibre.utils.date import isoformat, format_date + NULL_VALUES = { @@ -94,6 +95,13 @@ class Metadata(object): return default return self.__getattribute__(field) + def get_extra(self, field): + _data = object.__getattribute__(self, '_data') + if field in _data['user_metadata'].iterkeys(): + return _data['user_metadata'][field]['#extra#'] + raise AttributeError( + 'Metadata object has no attribute named: '+ repr(field)) + def set(self, field, val, extra=None): self.__setattr__(field, val, extra) @@ -131,14 +139,6 @@ class Metadata(object): return _data[field] return None - @classmethod - def get_user_metadata_value(user_mi): - return user_mi['#value#'] - - @classmethod - def get_user_metadata_extra(user_mi): - return user_mi['#extra#'] - def set_all_user_metadata(self, metadata): ''' store custom field metadata into the object. Field is the key name @@ -284,6 +284,25 @@ class Metadata(object): def format_rating(self): return unicode(self.rating) + def format_custom_field(self, key): + ''' + returns the tuple (field_name, formatted_value) + ''' + cmeta = self.get_user_metadata(key, make_copy=False) + name = unicode(cmeta['name']) + res = self.get(key, None) + if res is not None: + datatype = cmeta['datatype'] + if datatype == 'text' and cmeta['is_multiple']: + res = u', '.join(res) + elif datatype == 'series': + res = res + ' [%s]'%self.format_series_index(self.get_extra(key)) + elif datatype == 'datetime': + res = format_date(res, cmeta['display'].get('date_format','dd MMM yyyy')) + elif datatype == 'bool': + res = _('Yes') if res else _('No') + return (name, unicode(res)) + def __unicode__(self): from calibre.ebooks.metadata import authors_to_string ans = [] @@ -339,9 +358,13 @@ class Metadata(object): ans += [(_('Published'), unicode(self.pubdate.isoformat(' ')))] if self.rights is not None: ans += [(_('Rights'), unicode(self.rights))] + for key in self.user_metadata_keys: + val = self.get(key, None) + if val is not None: + (name, val) = self.format_custom_field(key) + ans += [(name, val)] for i, x in enumerate(ans): ans[i] = u'%s%s'%x - # TODO: NEWMETA: What to do about custom fields return u'%s
'%u'\n'.join(ans) def __str__(self): diff --git a/src/calibre/gui2/book_details.py b/src/calibre/gui2/book_details.py index f08dd09429..4e11e0c84f 100644 --- a/src/calibre/gui2/book_details.py +++ b/src/calibre/gui2/book_details.py @@ -28,6 +28,8 @@ WEIGHTS[_('Tags')] = 4 def render_rows(data): keys = data.keys() + # First sort by name. The WEIGHTS sort will preserve this sub-order + keys.sort(cmp=lambda x, y: cmp(x.lower(), y.lower())) keys.sort(cmp=lambda x, y: cmp(WEIGHTS[x], WEIGHTS[y])) rows = [] for key in keys: diff --git a/src/calibre/gui2/library/models.py b/src/calibre/gui2/library/models.py index fdf21ecc23..2711756856 100644 --- a/src/calibre/gui2/library/models.py +++ b/src/calibre/gui2/library/models.py @@ -323,7 +323,11 @@ class BooksModel(QAbstractTableModel): # {{{ data[_('Series')] = \ _('Book %s of %s.')%\ (sidx, prepare_string_for_xml(series)) - + mi = self.db.get_metadata(idx) + for key in mi.user_metadata_keys: + name, val = mi.format_custom_field(key) + if val is not None: + data[name] = val return data def set_cache(self, idx): diff --git a/src/calibre/library/database2.py b/src/calibre/library/database2.py index 6457e12905..bb6d72bcff 100644 --- a/src/calibre/library/database2.py +++ b/src/calibre/library/database2.py @@ -1052,8 +1052,8 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): if key in self.field_metadata and \ user_mi[key]['datatype'] == self.field_metadata[key]['datatype']: doit(self.set_custom, id, - val=Metadata.get_user_metadata_value(user_mi[key]), - extra=Metadata.get_user_metadata_extra(user_mi[key]), + val=mi.get(key), + extra=mi.get_extra(key), label=user_mi[key]['label']) self.notify('metadata', [id])