mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
...
This commit is contained in:
commit
8a7877fb73
@ -62,7 +62,7 @@ class Bool(Base):
|
|||||||
w = self.widgets[1]
|
w = self.widgets[1]
|
||||||
items = [_('Yes'), _('No'), _('Undefined')]
|
items = [_('Yes'), _('No'), _('Undefined')]
|
||||||
icons = [I('ok.png'), I('list_remove.png'), I('blank.png')]
|
icons = [I('ok.png'), I('list_remove.png'), I('blank.png')]
|
||||||
if tweaks['bool_custom_columns_are_tristate'] == 'no':
|
if not self.db.prefs.get('bools_are_tristate'):
|
||||||
items = items[:-1]
|
items = items[:-1]
|
||||||
icons = icons[:-1]
|
icons = icons[:-1]
|
||||||
for icon, text in zip(icons, items):
|
for icon, text in zip(icons, items):
|
||||||
@ -70,7 +70,7 @@ class Bool(Base):
|
|||||||
|
|
||||||
def setter(self, val):
|
def setter(self, val):
|
||||||
val = {None: 2, False: 1, True: 0}[val]
|
val = {None: 2, False: 1, True: 0}[val]
|
||||||
if tweaks['bool_custom_columns_are_tristate'] == 'no' and val == 2:
|
if not self.db.prefs.get('bools_are_tristate') and val == 2:
|
||||||
val = 1
|
val = 1
|
||||||
self.widgets[1].setCurrentIndex(val)
|
self.widgets[1].setCurrentIndex(val)
|
||||||
|
|
||||||
@ -549,7 +549,7 @@ class BulkBool(BulkBase, Bool):
|
|||||||
value = None
|
value = None
|
||||||
for book_id in book_ids:
|
for book_id in book_ids:
|
||||||
val = self.db.get_custom(book_id, num=self.col_id, index_is_id=True)
|
val = self.db.get_custom(book_id, num=self.col_id, index_is_id=True)
|
||||||
if tweaks['bool_custom_columns_are_tristate'] == 'no' and val is None:
|
if not self.db.prefs.get('bools_are_tristate') and val is None:
|
||||||
val = False
|
val = False
|
||||||
if value is not None and value != val:
|
if value is not None and value != val:
|
||||||
return None
|
return None
|
||||||
@ -559,7 +559,7 @@ class BulkBool(BulkBase, Bool):
|
|||||||
def setup_ui(self, parent):
|
def setup_ui(self, parent):
|
||||||
self.make_widgets(parent, QComboBox)
|
self.make_widgets(parent, QComboBox)
|
||||||
items = [_('Yes'), _('No')]
|
items = [_('Yes'), _('No')]
|
||||||
if tweaks['bool_custom_columns_are_tristate'] == 'no':
|
if not self.db.prefs.get('bools_are_tristate'):
|
||||||
items.append('')
|
items.append('')
|
||||||
else:
|
else:
|
||||||
items.append(_('Undefined'))
|
items.append(_('Undefined'))
|
||||||
@ -571,7 +571,7 @@ class BulkBool(BulkBase, Bool):
|
|||||||
|
|
||||||
def getter(self):
|
def getter(self):
|
||||||
val = self.main_widget.currentIndex()
|
val = self.main_widget.currentIndex()
|
||||||
if tweaks['bool_custom_columns_are_tristate'] == 'no':
|
if not self.db.prefs.get('bools_are_tristate'):
|
||||||
return {2: False, 1: False, 0: True}[val]
|
return {2: False, 1: False, 0: True}[val]
|
||||||
else:
|
else:
|
||||||
return {2: None, 1: False, 0: True}[val]
|
return {2: None, 1: False, 0: True}[val]
|
||||||
@ -586,13 +586,13 @@ class BulkBool(BulkBase, Bool):
|
|||||||
return
|
return
|
||||||
val = self.gui_val
|
val = self.gui_val
|
||||||
val = self.normalize_ui_val(val)
|
val = self.normalize_ui_val(val)
|
||||||
if tweaks['bool_custom_columns_are_tristate'] == 'no' and val is None:
|
if not self.db.prefs.get('bools_are_tristate') and val is None:
|
||||||
val = False
|
val = False
|
||||||
self.db.set_custom_bulk(book_ids, val, num=self.col_id, notify=notify)
|
self.db.set_custom_bulk(book_ids, val, num=self.col_id, notify=notify)
|
||||||
|
|
||||||
def a_c_checkbox_changed(self):
|
def a_c_checkbox_changed(self):
|
||||||
if not self.ignore_change_signals:
|
if not self.ignore_change_signals:
|
||||||
if tweaks['bool_custom_columns_are_tristate'] == 'no' and \
|
if not self.db.prefs.get('bools_are_tristate') and \
|
||||||
self.main_widget.currentIndex() == 2:
|
self.main_widget.currentIndex() == 2:
|
||||||
self.a_c_checkbox.setChecked(False)
|
self.a_c_checkbox.setChecked(False)
|
||||||
else:
|
else:
|
||||||
|
@ -353,7 +353,7 @@ class CcBoolDelegate(QStyledItemDelegate): # {{{
|
|||||||
editor = DelegateCB(parent)
|
editor = DelegateCB(parent)
|
||||||
items = [_('Y'), _('N'), ' ']
|
items = [_('Y'), _('N'), ' ']
|
||||||
icons = [I('ok.png'), I('list_remove.png'), I('blank.png')]
|
icons = [I('ok.png'), I('list_remove.png'), I('blank.png')]
|
||||||
if tweaks['bool_custom_columns_are_tristate'] == 'no':
|
if not index.model().db.prefs.get('bools_are_tristate'):
|
||||||
items = items[:-1]
|
items = items[:-1]
|
||||||
icons = icons[:-1]
|
icons = icons[:-1]
|
||||||
for icon, text in zip(icons, items):
|
for icon, text in zip(icons, items):
|
||||||
@ -367,7 +367,7 @@ class CcBoolDelegate(QStyledItemDelegate): # {{{
|
|||||||
def setEditorData(self, editor, index):
|
def setEditorData(self, editor, index):
|
||||||
m = index.model()
|
m = index.model()
|
||||||
val = m.db.data[index.row()][m.custom_columns[m.column_map[index.column()]]['rec_index']]
|
val = m.db.data[index.row()][m.custom_columns[m.column_map[index.column()]]['rec_index']]
|
||||||
if tweaks['bool_custom_columns_are_tristate'] == 'no':
|
if not m.db.prefs.get('bools_are_tristate'):
|
||||||
val = 1 if not val else 0
|
val = 1 if not val else 0
|
||||||
else:
|
else:
|
||||||
val = 2 if val is None else 1 if not val else 0
|
val = 2 if val is None else 1 if not val else 0
|
||||||
|
@ -700,7 +700,7 @@ class BooksModel(QAbstractTableModel): # {{{
|
|||||||
self.dc_decorator[col] = functools.partial(
|
self.dc_decorator[col] = functools.partial(
|
||||||
bool_type_decorator, idx=idx,
|
bool_type_decorator, idx=idx,
|
||||||
bool_cols_are_tristate=
|
bool_cols_are_tristate=
|
||||||
tweaks['bool_custom_columns_are_tristate'] != 'no')
|
self.db.prefs.get('bools_are_tristate'))
|
||||||
elif datatype in ('int', 'float'):
|
elif datatype in ('int', 'float'):
|
||||||
self.dc[col] = functools.partial(number_type, idx=idx)
|
self.dc[col] = functools.partial(number_type, idx=idx)
|
||||||
elif datatype == 'datetime':
|
elif datatype == 'datetime':
|
||||||
@ -710,7 +710,7 @@ class BooksModel(QAbstractTableModel): # {{{
|
|||||||
self.dc_decorator[col] = functools.partial(
|
self.dc_decorator[col] = functools.partial(
|
||||||
bool_type_decorator, idx=idx,
|
bool_type_decorator, idx=idx,
|
||||||
bool_cols_are_tristate=
|
bool_cols_are_tristate=
|
||||||
tweaks['bool_custom_columns_are_tristate'] != 'no')
|
self.db.prefs.get('bools_are_tristate'))
|
||||||
elif datatype == 'rating':
|
elif datatype == 'rating':
|
||||||
self.dc[col] = functools.partial(rating_type, idx=idx)
|
self.dc[col] = functools.partial(rating_type, idx=idx)
|
||||||
elif datatype == 'series':
|
elif datatype == 'series':
|
||||||
|
@ -521,7 +521,7 @@ class MetadataSingleDialog(MetadataSingleDialogBase): # {{{
|
|||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
class MetadataSingleDialogAlt(MetadataSingleDialogBase): # {{{
|
class MetadataSingleDialogAlt1(MetadataSingleDialogBase): # {{{
|
||||||
|
|
||||||
cc_two_column = False
|
cc_two_column = False
|
||||||
one_line_comments_toolbar = True
|
one_line_comments_toolbar = True
|
||||||
@ -654,10 +654,14 @@ class MetadataSingleDialogAlt(MetadataSingleDialogBase): # {{{
|
|||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
editors = {'default': MetadataSingleDialog, 'alt1': MetadataSingleDialogAlt1}
|
||||||
|
|
||||||
def edit_metadata(db, row_list, current_row, parent=None, view_slot=None,
|
def edit_metadata(db, row_list, current_row, parent=None, view_slot=None,
|
||||||
set_current_callback=None):
|
set_current_callback=None):
|
||||||
d = MetadataSingleDialog(db, parent)
|
cls = db.prefs.get('edit_metadata_single_layout', '')
|
||||||
|
if cls not in editors:
|
||||||
|
cls = 'default'
|
||||||
|
d = editors[cls](db, parent)
|
||||||
d.start(row_list, current_row, view_slot=view_slot,
|
d.start(row_list, current_row, view_slot=view_slot,
|
||||||
set_current_callback=set_current_callback)
|
set_current_callback=set_current_callback)
|
||||||
return d.changed, d.rows_to_refresh
|
return d.changed, d.rows_to_refresh
|
||||||
|
@ -13,6 +13,7 @@ from calibre.gui2.preferences import ConfigWidgetBase, test_widget
|
|||||||
from calibre.gui2.preferences.columns_ui import Ui_Form
|
from calibre.gui2.preferences.columns_ui import Ui_Form
|
||||||
from calibre.gui2.preferences.create_custom_column import CreateCustomColumn
|
from calibre.gui2.preferences.create_custom_column import CreateCustomColumn
|
||||||
from calibre.gui2 import error_dialog, question_dialog, ALL_COLUMNS
|
from calibre.gui2 import error_dialog, question_dialog, ALL_COLUMNS
|
||||||
|
from calibre.utils.config import test_eight_code
|
||||||
|
|
||||||
class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
||||||
|
|
||||||
@ -33,6 +34,14 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
|||||||
signal = getattr(self.opt_columns, 'item'+signal)
|
signal = getattr(self.opt_columns, 'item'+signal)
|
||||||
signal.connect(self.columns_changed)
|
signal.connect(self.columns_changed)
|
||||||
|
|
||||||
|
if test_eight_code:
|
||||||
|
r = self.register
|
||||||
|
choices = [(_('Default'), 'default'), (_('Compact Metadata'), 'alt1')]
|
||||||
|
r('edit_metadata_single_layout', db.prefs, choices=choices)
|
||||||
|
r('bools_are_tristate', db.prefs, restart_required=True)
|
||||||
|
else:
|
||||||
|
self.items_in_v_eight.setVisible(False)
|
||||||
|
|
||||||
def initialize(self):
|
def initialize(self):
|
||||||
ConfigWidgetBase.initialize(self)
|
ConfigWidgetBase.initialize(self)
|
||||||
self.init_columns()
|
self.init_columns()
|
||||||
@ -169,6 +178,10 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
|||||||
must_restart = True
|
must_restart = True
|
||||||
return must_restart
|
return must_restart
|
||||||
|
|
||||||
|
def refresh_gui(self, gui):
|
||||||
|
gui.library_view.reset()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
from PyQt4.Qt import QApplication
|
from PyQt4.Qt import QApplication
|
||||||
|
@ -197,6 +197,67 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="1" column="2">
|
||||||
|
<layout class="QVBoxLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="items_in_v_eight">
|
||||||
|
<property name="title">
|
||||||
|
<string>Related Options</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Edit metadata layout:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>opt_edit_metadata_single_layout</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QComboBox" name="opt_edit_metadata_single_layout">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Choose a different layout for the Edit Metadata dialog. Alternate layouts make it easier to edit custom columns.</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Boolean columns are tristate:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>opt_bools_are_tristate</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QCheckBox" name="opt_bools_are_tristate">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>If checked, boolean columns values can be Yes, No, and Unknown.
|
||||||
|
If not checked, the values can be Yes and No.</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_5">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<resources>
|
<resources>
|
||||||
|
@ -547,7 +547,7 @@ class ResultCache(SearchQueryParser): # {{{
|
|||||||
return matchkind, query
|
return matchkind, query
|
||||||
|
|
||||||
def get_bool_matches(self, location, query, candidates):
|
def get_bool_matches(self, location, query, candidates):
|
||||||
bools_are_tristate = tweaks['bool_custom_columns_are_tristate'] != 'no'
|
bools_are_tristate = not self.db_prefs.get('bools_are_tristate')
|
||||||
loc = self.field_metadata[location]['rec_index']
|
loc = self.field_metadata[location]['rec_index']
|
||||||
matches = set()
|
matches = set()
|
||||||
query = icu_lower(query)
|
query = icu_lower(query)
|
||||||
@ -947,7 +947,7 @@ class ResultCache(SearchQueryParser): # {{{
|
|||||||
if not fields:
|
if not fields:
|
||||||
fields = [('timestamp', False)]
|
fields = [('timestamp', False)]
|
||||||
|
|
||||||
keyg = SortKeyGenerator(fields, self.field_metadata, self._data)
|
keyg = SortKeyGenerator(fields, self.field_metadata, self._data, self.db_prefs)
|
||||||
self._map.sort(key=keyg)
|
self._map.sort(key=keyg)
|
||||||
|
|
||||||
tmap = list(itertools.repeat(False, len(self._data)))
|
tmap = list(itertools.repeat(False, len(self._data)))
|
||||||
@ -970,9 +970,10 @@ class SortKey(object):
|
|||||||
|
|
||||||
class SortKeyGenerator(object):
|
class SortKeyGenerator(object):
|
||||||
|
|
||||||
def __init__(self, fields, field_metadata, data):
|
def __init__(self, fields, field_metadata, data, db_prefs):
|
||||||
from calibre.utils.icu import sort_key
|
from calibre.utils.icu import sort_key
|
||||||
self.field_metadata = field_metadata
|
self.field_metadata = field_metadata
|
||||||
|
self.db_prefs = db_prefs
|
||||||
self.orders = [1 if x[1] else -1 for x in fields]
|
self.orders = [1 if x[1] else -1 for x in fields]
|
||||||
self.entries = [(x[0], field_metadata[x[0]]) for x in fields]
|
self.entries = [(x[0], field_metadata[x[0]]) for x in fields]
|
||||||
self.library_order = tweaks['title_series_sorting'] == 'library_order'
|
self.library_order = tweaks['title_series_sorting'] == 'library_order'
|
||||||
@ -1032,7 +1033,7 @@ class SortKeyGenerator(object):
|
|||||||
val = self.string_sort_key(val)
|
val = self.string_sort_key(val)
|
||||||
|
|
||||||
elif dt == 'bool':
|
elif dt == 'bool':
|
||||||
if tweaks['bool_custom_columns_are_tristate'] == 'no':
|
if not self.db_prefs.get('bools_are_tristate'):
|
||||||
val = {True: 1, False: 2, None: 2}.get(val, 2)
|
val = {True: 1, False: 2, None: 2}.get(val, 2)
|
||||||
else:
|
else:
|
||||||
val = {True: 1, False: 2, None: 3}.get(val, 3)
|
val = {True: 1, False: 2, None: 3}.get(val, 3)
|
||||||
|
@ -40,7 +40,7 @@ from calibre.ebooks import BOOK_EXTENSIONS, check_ebook_format
|
|||||||
from calibre.utils.magick.draw import save_cover_data_to
|
from calibre.utils.magick.draw import save_cover_data_to
|
||||||
from calibre.utils.recycle_bin import delete_file, delete_tree
|
from calibre.utils.recycle_bin import delete_file, delete_tree
|
||||||
from calibre.utils.formatter_functions import load_user_template_functions
|
from calibre.utils.formatter_functions import load_user_template_functions
|
||||||
|
from calibre.utils.config import test_eight_code
|
||||||
|
|
||||||
copyfile = os.link if hasattr(os, 'link') else shutil.copyfile
|
copyfile = os.link if hasattr(os, 'link') else shutil.copyfile
|
||||||
|
|
||||||
@ -213,6 +213,12 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
defs = self.prefs.defaults
|
defs = self.prefs.defaults
|
||||||
defs['gui_restriction'] = defs['cs_restriction'] = ''
|
defs['gui_restriction'] = defs['cs_restriction'] = ''
|
||||||
defs['categories_using_hierarchy'] = []
|
defs['categories_using_hierarchy'] = []
|
||||||
|
defs['edit_metadata_single_layout'] = 'default'
|
||||||
|
|
||||||
|
defs['bools_are_tristate'] = \
|
||||||
|
tweaks.get('bool_custom_columns_are_tristate', 'yes') == 'yes'
|
||||||
|
if self.prefs.get('bools_are_tristate') is None or not test_eight_code:
|
||||||
|
self.prefs.set('bools_are_tristate', defs['bools_are_tristate'])
|
||||||
|
|
||||||
# Migrate saved search and user categories to db preference scheme
|
# Migrate saved search and user categories to db preference scheme
|
||||||
def migrate_preference(key, default):
|
def migrate_preference(key, default):
|
||||||
|
@ -17,8 +17,8 @@ from calibre.utils.magick.draw import save_cover_data_to, Image, \
|
|||||||
|
|
||||||
class CSSortKeyGenerator(SortKeyGenerator):
|
class CSSortKeyGenerator(SortKeyGenerator):
|
||||||
|
|
||||||
def __init__(self, fields, fm):
|
def __init__(self, fields, fm, db_prefs):
|
||||||
SortKeyGenerator.__init__(self, fields, fm, None)
|
SortKeyGenerator.__init__(self, fields, fm, None, db_prefs)
|
||||||
|
|
||||||
def __call__(self, record):
|
def __call__(self, record):
|
||||||
return self.itervals(record).next()
|
return self.itervals(record).next()
|
||||||
@ -56,7 +56,8 @@ class ContentServer(object):
|
|||||||
field = self.db.data.sanitize_sort_field_name(field)
|
field = self.db.data.sanitize_sort_field_name(field)
|
||||||
if field not in self.db.field_metadata.sortable_field_keys():
|
if field not in self.db.field_metadata.sortable_field_keys():
|
||||||
raise cherrypy.HTTPError(400, '%s is not a valid sort field'%field)
|
raise cherrypy.HTTPError(400, '%s is not a valid sort field'%field)
|
||||||
keyg = CSSortKeyGenerator([(field, order)], self.db.field_metadata)
|
keyg = CSSortKeyGenerator([(field, order)], self.db.field_metadata,
|
||||||
|
self.db.prefs)
|
||||||
items.sort(key=keyg, reverse=not order)
|
items.sort(key=keyg, reverse=not order)
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
@ -785,6 +785,9 @@ def write_tweaks(raw):
|
|||||||
|
|
||||||
tweaks = read_tweaks()
|
tweaks = read_tweaks()
|
||||||
test_eight_code = tweaks.get('test_eight_code', False)
|
test_eight_code = tweaks.get('test_eight_code', False)
|
||||||
|
# test_eight_code notes
|
||||||
|
# Change documentation of bool columns are tristate to indicate that it can be
|
||||||
|
# overridden on a per library basis via Preferences->Custom columns
|
||||||
|
|
||||||
def migrate():
|
def migrate():
|
||||||
if hasattr(os, 'geteuid') and os.geteuid() == 0:
|
if hasattr(os, 'geteuid') and os.geteuid() == 0:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user