mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-07 10:14:46 -04:00
Merge branch 'master' of https://github.com/cbhaley/calibre
This commit is contained in:
commit
c04b7dd482
@ -574,3 +574,17 @@ allow_template_database_functions_in_composites = False
|
||||
# for https://whatever URLs. %u is replaced by the URL to be opened. The scheme
|
||||
# takes a glob pattern allowing a single entry to match multiple URL types.
|
||||
openers_by_scheme = {}
|
||||
|
||||
#: Change standard column heading text to some value
|
||||
# Use the dictionary below to change a column heading. The format of the
|
||||
# dictionary is
|
||||
# {lookup_name: new_heading, ...}
|
||||
# The new_heading must be unique: no two columns can have the same heading.
|
||||
# This tweak works only with standard columns: it cannot be used to change
|
||||
# the heading for a custom column. If a custom column has the same heading as
|
||||
# one provided here then a number will appended to the custom column's heading
|
||||
# to make it unique.
|
||||
#
|
||||
# Example:
|
||||
# alternate_column_headings = {'authors':'Writers', 'size':'MBytes'}
|
||||
alternate_column_headings = {}
|
||||
|
@ -38,7 +38,7 @@ from calibre.utils.date import (
|
||||
UNDEFINED_DATE, as_local_time, dt_factory, is_date_undefined, qt_to_dt,
|
||||
)
|
||||
from calibre.utils.icu import sort_key
|
||||
from calibre.utils.localization import calibre_langcode_to_name, ngettext
|
||||
from calibre.utils.localization import calibre_langcode_to_name
|
||||
from calibre.utils.resources import get_path as P
|
||||
from calibre.utils.search_query_parser import ParseException, SearchQueryParser
|
||||
from polyglot.builtins import iteritems, itervalues, string_or_bytes
|
||||
@ -192,20 +192,12 @@ class BooksModel(QAbstractTableModel): # {{{
|
||||
self.bi_font = QFont(self.bold_font)
|
||||
self.bi_font.setItalic(True)
|
||||
self.styled_columns = {}
|
||||
self.orig_headers = {
|
||||
'title' : _("Title"),
|
||||
'ondevice' : _("On Device"),
|
||||
'authors' : _("Author(s)"),
|
||||
'size' : _("Size (MB)"),
|
||||
'timestamp' : _("Date"),
|
||||
'pubdate' : _('Published'),
|
||||
'rating' : _('Rating'),
|
||||
'publisher' : _("Publisher"),
|
||||
'tags' : _("Tags"),
|
||||
'series' : ngettext("Series", 'Series', 1),
|
||||
'last_modified' : _('Modified'),
|
||||
'languages' : _('Languages'),
|
||||
}
|
||||
possible_columns = ('title', 'ondevice', 'authors', 'size', 'timestamp',
|
||||
'pubdate', 'rating', 'publisher', 'tags', 'series',
|
||||
'last_modified', 'languages', 'formats', 'id', 'path')
|
||||
from calibre.library.field_metadata import FieldMetadata
|
||||
fm = FieldMetadata()
|
||||
self.orig_headers = {k: fm[k]['name'] for k in possible_columns}
|
||||
|
||||
self.db = None
|
||||
|
||||
@ -829,6 +821,10 @@ class BooksModel(QAbstractTableModel): # {{{
|
||||
|
||||
def renderer(field, decorator=False):
|
||||
idfunc = self.db.id
|
||||
if field == 'id':
|
||||
def func(idx):
|
||||
return idfunc(idx)
|
||||
return func
|
||||
fffunc = self.db.new_api.fast_field_for
|
||||
field_obj = self.db.new_api.fields[field]
|
||||
m = field_obj.metadata.copy()
|
||||
@ -953,7 +949,7 @@ class BooksModel(QAbstractTableModel): # {{{
|
||||
|
||||
return func
|
||||
|
||||
self.dc = {f:renderer(f) for f in 'title authors size timestamp pubdate last_modified rating publisher tags series ondevice languages'.split()}
|
||||
self.dc = {f:renderer(f) for f in self.orig_headers.keys()}
|
||||
self.dc_decorator = {f:renderer(f, True) for f in ('ondevice',)}
|
||||
|
||||
for col in self.custom_columns:
|
||||
|
@ -808,8 +808,8 @@ class BooksView(QTableView): # {{{
|
||||
state = {}
|
||||
state['hidden_columns'] = [cm[i] for i in range(h.count())
|
||||
if h.isSectionHidden(i) and cm[i] != 'ondevice']
|
||||
state['last_modified_injected'] = True
|
||||
state['languages_injected'] = True
|
||||
for f in ('last_modified', 'languages', 'formats', 'id', 'path'):
|
||||
state[f+'_injected'] = True
|
||||
state['sort_history'] = \
|
||||
self.cleanup_sort_history(self.model().sort_history, ignore_column_map=self.is_library_view)
|
||||
state['column_positions'] = {}
|
||||
@ -923,7 +923,7 @@ class BooksView(QTableView): # {{{
|
||||
|
||||
def get_default_state(self):
|
||||
old_state = {
|
||||
'hidden_columns': ['last_modified', 'languages'],
|
||||
'hidden_columns': ['last_modified', 'languages', 'formats', 'id', 'path'],
|
||||
'sort_history':[DEFAULT_SORT],
|
||||
'column_positions': {},
|
||||
'column_sizes': {},
|
||||
@ -931,9 +931,9 @@ class BooksView(QTableView): # {{{
|
||||
'size':'center',
|
||||
'timestamp':'center',
|
||||
'pubdate':'center'},
|
||||
'last_modified_injected': True,
|
||||
'languages_injected': True,
|
||||
}
|
||||
for f in ('last_modified', 'languages', 'formats', 'id', 'path'):
|
||||
old_state[f+'_injected'] = True
|
||||
h = self.column_header
|
||||
cm = self.column_map
|
||||
for i in range(h.count()):
|
||||
@ -965,18 +965,14 @@ class BooksView(QTableView): # {{{
|
||||
db.new_api.set_pref(name, ans)
|
||||
else:
|
||||
injected = False
|
||||
if not ans.get('last_modified_injected', False):
|
||||
for f in ('last_modified', 'languages', 'formats', 'id', 'path'):
|
||||
if not ans.get(f+'_injected', False):
|
||||
print('injecting', f)
|
||||
injected = True
|
||||
ans['last_modified_injected'] = True
|
||||
ans[f+'_injected'] = True
|
||||
hc = ans.get('hidden_columns', [])
|
||||
if 'last_modified' not in hc:
|
||||
hc.append('last_modified')
|
||||
if not ans.get('languages_injected', False):
|
||||
injected = True
|
||||
ans['languages_injected'] = True
|
||||
hc = ans.get('hidden_columns', [])
|
||||
if 'languages' not in hc:
|
||||
hc.append('languages')
|
||||
if f not in hc:
|
||||
hc.append(f)
|
||||
if injected:
|
||||
db.new_api.set_pref(name, ans)
|
||||
return ans
|
||||
|
@ -5,6 +5,7 @@ Created on 25 May 2010
|
||||
'''
|
||||
|
||||
import traceback
|
||||
import sys
|
||||
from collections import OrderedDict
|
||||
|
||||
from calibre.utils.config_base import tweaks
|
||||
@ -197,7 +198,7 @@ def _builtin_field_metadata():
|
||||
'datatype':'int',
|
||||
'is_multiple':{},
|
||||
'kind':'field',
|
||||
'name':None,
|
||||
'name': _('Id'),
|
||||
'search_terms':['id'],
|
||||
'is_custom':False,
|
||||
'is_category':False,
|
||||
@ -411,6 +412,15 @@ class FieldMetadata:
|
||||
self._tb_cats[k]['display'] = {}
|
||||
self._tb_cats[k]['is_editable'] = True
|
||||
self._add_search_terms_to_map(k, v['search_terms'])
|
||||
alternate_headings = tweaks.get('alternate_column_headings', {})
|
||||
if alternate_headings:
|
||||
existing_headings = {k['name'] for k in self._tb_cats.values() if k['name']}
|
||||
for k,v in alternate_headings.items():
|
||||
if k in self._tb_cats.keys():
|
||||
v = self.get_unique_field_heading(v)
|
||||
existing_headings.discard(self._tb_cats[k]['name'])
|
||||
existing_headings.add(v)
|
||||
self._tb_cats[k]['name'] = v
|
||||
self._tb_cats['timestamp']['display'] = {
|
||||
'date_format': tweaks['gui_timestamp_display_format']}
|
||||
self._tb_cats['pubdate']['display'] = {
|
||||
@ -454,6 +464,10 @@ class FieldMetadata:
|
||||
def __ne__(self, other):
|
||||
return not self.__eq__(other)
|
||||
|
||||
def set_field_heading(self, key, heading):
|
||||
if key in self._tb_cats.keys():
|
||||
self._tb_cats[key]['name'] = heading
|
||||
|
||||
def sortable_field_keys(self):
|
||||
return [k for k in self._tb_cats.keys()
|
||||
if self._tb_cats[k]['kind']=='field' and
|
||||
@ -560,6 +574,18 @@ class FieldMetadata:
|
||||
l[k] = self._tb_cats[k]
|
||||
return l
|
||||
|
||||
def get_unique_field_heading(self, name):
|
||||
# Verify column heading is unique. Can only happen if the tweak is set
|
||||
if tweaks.get('alternate_column_headings', {}):
|
||||
existing_names = {icu_lower(c['name']) for c in self._tb_cats.values() if c['name'] is not None}
|
||||
t = icu_lower(name)
|
||||
if t in existing_names:
|
||||
for i in range(1, sys.maxsize):
|
||||
if (t + '_' + str(i)) not in existing_names:
|
||||
name = name + '_' + str(i)
|
||||
break
|
||||
return name
|
||||
|
||||
def add_custom_field(self, label, table, column, datatype, colnum, name,
|
||||
display, is_editable, is_multiple, is_category,
|
||||
is_csp=False):
|
||||
@ -568,6 +594,7 @@ class FieldMetadata:
|
||||
raise ValueError('Duplicate custom field [%s]'%(label))
|
||||
if datatype not in self.VALID_DATA_TYPES:
|
||||
raise ValueError('Unknown datatype %s for field %s'%(datatype, key))
|
||||
name = self.get_unique_field_heading(name)
|
||||
self._tb_cats[key] = {'table':table, 'column':column,
|
||||
'datatype':datatype, 'is_multiple':is_multiple,
|
||||
'kind':'field', 'name':name,
|
||||
|
Loading…
x
Reference in New Issue
Block a user