mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Merge branch 'master' of https://github.com/cbhaley/calibre
Fixes #1903348 [[Enhancement] Add a clear button to clear permitted values when editing a custom columns](https://bugs.launchpad.net/calibre/+bug/1903348)
This commit is contained in:
commit
aa9e76aa78
@ -70,6 +70,21 @@ class Base(object):
|
||||
except:
|
||||
pass
|
||||
|
||||
def finish_ui_setup(self, parent, edit_widget):
|
||||
self.was_none = False
|
||||
w = QWidget(parent)
|
||||
self.widgets.append(w)
|
||||
l = QHBoxLayout()
|
||||
l.setContentsMargins(0, 0, 0, 0)
|
||||
w.setLayout(l)
|
||||
self.editor = editor = edit_widget(parent)
|
||||
l.addWidget(editor)
|
||||
self.clear_button = QToolButton(parent)
|
||||
self.clear_button.setIcon(QIcon(I('trash.png')))
|
||||
self.clear_button.clicked.connect(self.set_to_undefined)
|
||||
self.clear_button.setToolTip(_('Clear {0}').format(self.col_metadata['name']))
|
||||
l.addWidget(self.clear_button)
|
||||
|
||||
def initialize(self, book_id):
|
||||
val = self.db.get_custom(book_id, num=self.col_id, index_is_id=True)
|
||||
val = self.normalize_db_val(val)
|
||||
@ -114,18 +129,20 @@ class Base(object):
|
||||
class SimpleText(Base):
|
||||
|
||||
def setup_ui(self, parent):
|
||||
self.editor = QLineEdit(parent)
|
||||
self.widgets = [QLabel(label_string(self.col_metadata['name']), parent),
|
||||
QLineEdit(parent)]
|
||||
self.editor]
|
||||
self.editor.setClearButtonEnabled(True)
|
||||
|
||||
def setter(self, val):
|
||||
self.widgets[1].setText(unicode_type(val or ''))
|
||||
self.editor.setText(unicode_type(val or ''))
|
||||
|
||||
def getter(self):
|
||||
return self.widgets[1].text().strip()
|
||||
return self.editor.text().strip()
|
||||
|
||||
def connect_data_changed(self, slot):
|
||||
self.widgets[1].textChanged.connect(slot)
|
||||
self.signals_to_disconnect.append(self.widgets[1].textChanged)
|
||||
self.editor.textChanged.connect(slot)
|
||||
self.signals_to_disconnect.append(self.editor.textChanged)
|
||||
|
||||
|
||||
class LongText(Base):
|
||||
@ -179,7 +196,7 @@ class Bool(Base):
|
||||
|
||||
if self.db.new_api.pref('bools_are_tristate'):
|
||||
c = QToolButton(parent)
|
||||
c.setText(_('Clear'))
|
||||
c.setIcon(QIcon(I('trash.png')))
|
||||
c.setToolTip(_('Clear {}').format(name))
|
||||
l.addWidget(c)
|
||||
c.clicked.connect(self.set_to_cleared)
|
||||
@ -225,23 +242,10 @@ class Int(Base):
|
||||
self.editor.setRange(-1000000, 100000000)
|
||||
|
||||
def finish_ui_setup(self, parent, edit_widget):
|
||||
self.was_none = False
|
||||
w = QWidget(parent)
|
||||
self.widgets.append(w)
|
||||
l = QHBoxLayout()
|
||||
l.setContentsMargins(0, 0, 0, 0)
|
||||
w.setLayout(l)
|
||||
self.editor = editor = edit_widget(parent)
|
||||
editor.setRange(-1000000, 100000000)
|
||||
editor.setSpecialValueText(_('Undefined'))
|
||||
editor.setSingleStep(1)
|
||||
editor.valueChanged.connect(self.valueChanged)
|
||||
l.addWidget(editor)
|
||||
self.clear_button = QToolButton(parent)
|
||||
self.clear_button.setIcon(QIcon(I('trash.png')))
|
||||
self.clear_button.clicked.connect(self.set_to_undefined)
|
||||
self.clear_button.setToolTip(_('Clear {0}').format(self.col_metadata['name']))
|
||||
l.addWidget(self.clear_button)
|
||||
Base.finish_ui_setup(self, parent, edit_widget)
|
||||
self.editor.setSpecialValueText(_('Undefined'))
|
||||
self.editor.setSingleStep(1)
|
||||
self.editor.valueChanged.connect(self.valueChanged)
|
||||
|
||||
def setter(self, val):
|
||||
if val is None:
|
||||
@ -276,24 +280,26 @@ class Float(Int):
|
||||
self.editor.setRange(-1000000., float(100000000))
|
||||
self.editor.setDecimals(2)
|
||||
|
||||
|
||||
class Rating(Base):
|
||||
|
||||
def setup_ui(self, parent):
|
||||
allow_half_stars = self.col_metadata['display'].get('allow_half_stars', False)
|
||||
self.widgets = [QLabel(label_string(self.col_metadata['name']), parent),
|
||||
RatingEditor(parent=parent, is_half_star=allow_half_stars)]
|
||||
self.widgets = [QLabel(label_string(self.col_metadata['name']), parent)]
|
||||
self.finish_ui_setup(parent, partial(RatingEditor, is_half_star=allow_half_stars))
|
||||
|
||||
def set_to_undefined(self):
|
||||
self.editor.setCurrentIndex(0)
|
||||
|
||||
def setter(self, val):
|
||||
val = max(0, min(int(val or 0), 10))
|
||||
self.widgets[1].rating_value = val
|
||||
self.editor.rating_value = val
|
||||
|
||||
def getter(self):
|
||||
return self.widgets[1].rating_value or None
|
||||
return self.editor.rating_value or None
|
||||
|
||||
def connect_data_changed(self, slot):
|
||||
self.widgets[1].currentTextChanged.connect(slot)
|
||||
self.signals_to_disconnect.append(self.widgets[1].currentTextChanged)
|
||||
self.editor.currentTextChanged.connect(slot)
|
||||
self.signals_to_disconnect.append(self.editor.currentTextChanged)
|
||||
|
||||
|
||||
class DateTimeEdit(DateTimeEditBase):
|
||||
@ -493,19 +499,22 @@ class Text(Base):
|
||||
w.set_add_separator(tweaks['authors_completer_append_separator'])
|
||||
w.get_editor_button().clicked.connect(self.edit)
|
||||
w.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
|
||||
self.set_to_undefined = w.clear
|
||||
else:
|
||||
w = EditWithComplete(parent)
|
||||
w.set_separator(None)
|
||||
w.setSizeAdjustPolicy(w.AdjustToMinimumContentsLengthWithIcon)
|
||||
w.setMinimumContentsLength(25)
|
||||
self.widgets = [QLabel(label_string(self.col_metadata['name']), parent), w]
|
||||
self.set_to_undefined = w.clearEditText
|
||||
self.widgets = [QLabel(label_string(self.col_metadata['name']), parent)]
|
||||
self.finish_ui_setup(parent, lambda parent: w)
|
||||
|
||||
def initialize(self, book_id):
|
||||
values = list(self.db.all_custom(num=self.col_id))
|
||||
values.sort(key=sort_key)
|
||||
self.book_id = book_id
|
||||
self.widgets[1].clear()
|
||||
self.widgets[1].update_items_cache(values)
|
||||
self.editor.clear()
|
||||
self.editor.update_items_cache(values)
|
||||
val = self.db.get_custom(book_id, num=self.col_id, index_is_id=True)
|
||||
if isinstance(val, list):
|
||||
if not self.col_metadata.get('display', {}).get('is_names', False):
|
||||
@ -515,23 +524,23 @@ class Text(Base):
|
||||
if self.col_metadata['is_multiple']:
|
||||
self.setter(val)
|
||||
else:
|
||||
self.widgets[1].setText(val)
|
||||
self.editor.setText(val)
|
||||
self.initial_val = self.current_val
|
||||
|
||||
def setter(self, val):
|
||||
if self.col_metadata['is_multiple']:
|
||||
if not val:
|
||||
val = []
|
||||
self.widgets[1].setText(self.sep['list_to_ui'].join(val))
|
||||
self.editor.setText(self.sep['list_to_ui'].join(val))
|
||||
|
||||
def getter(self):
|
||||
if self.col_metadata['is_multiple']:
|
||||
val = unicode_type(self.widgets[1].text()).strip()
|
||||
val = unicode_type(self.editor.text()).strip()
|
||||
ans = [x.strip() for x in val.split(self.sep['ui_to_list']) if x.strip()]
|
||||
if not ans:
|
||||
ans = None
|
||||
return ans
|
||||
val = unicode_type(self.widgets[1].currentText()).strip()
|
||||
val = unicode_type(self.editor.currentText()).strip()
|
||||
if not val:
|
||||
val = None
|
||||
return val
|
||||
@ -556,9 +565,9 @@ class Text(Base):
|
||||
|
||||
def connect_data_changed(self, slot):
|
||||
if self.col_metadata['is_multiple']:
|
||||
s = self.widgets[1].tags_box.currentTextChanged
|
||||
s = self.editor.tags_box.currentTextChanged
|
||||
else:
|
||||
s = self.widgets[1].currentTextChanged
|
||||
s = self.editor.currentTextChanged
|
||||
s.connect(slot)
|
||||
self.signals_to_disconnect.append(s)
|
||||
|
||||
@ -571,7 +580,8 @@ class Series(Base):
|
||||
w.setSizeAdjustPolicy(w.AdjustToMinimumContentsLengthWithIcon)
|
||||
w.setMinimumContentsLength(25)
|
||||
self.name_widget = w
|
||||
self.widgets = [QLabel(label_string(self.col_metadata['name']), parent), w]
|
||||
self.widgets = [QLabel(label_string(self.col_metadata['name']), parent)]
|
||||
self.finish_ui_setup(parent, lambda parent: w)
|
||||
w.editTextChanged.connect(self.series_changed)
|
||||
|
||||
w = QLabel(label_string(self.col_metadata['name'])+_(' index'), parent)
|
||||
@ -585,6 +595,10 @@ class Series(Base):
|
||||
w.setToolTip(get_tooltip(self.col_metadata, add_index=True))
|
||||
self.widgets.append(w)
|
||||
|
||||
def set_to_undefined(self):
|
||||
self.name_widget.clearEditText()
|
||||
self.idx_widget.setValue(1.0)
|
||||
|
||||
def initialize(self, book_id):
|
||||
values = list(self.db.all_custom(num=self.col_id))
|
||||
values.sort(key=sort_key)
|
||||
@ -639,7 +653,7 @@ class Series(Base):
|
||||
mi.set('#' + self.col_metadata['label'], val, extra=s_index)
|
||||
|
||||
def connect_data_changed(self, slot):
|
||||
for s in self.widgets[1].editTextChanged, self.widgets[3].valueChanged:
|
||||
for s in self.name_widget.editTextChanged, self.idx_widget.valueChanged:
|
||||
s.connect(slot)
|
||||
self.signals_to_disconnect.append(s)
|
||||
|
||||
@ -648,18 +662,17 @@ class Enumeration(Base):
|
||||
|
||||
def setup_ui(self, parent):
|
||||
self.parent = parent
|
||||
self.widgets = [QLabel(label_string(self.col_metadata['name']), parent),
|
||||
QComboBox(parent)]
|
||||
w = self.widgets[1]
|
||||
self.widgets = [QLabel(label_string(self.col_metadata['name']), parent)]
|
||||
self.finish_ui_setup(parent, QComboBox)
|
||||
vals = self.col_metadata['display']['enum_values']
|
||||
w.addItem('')
|
||||
self.editor.addItem('')
|
||||
for v in vals:
|
||||
w.addItem(v)
|
||||
self.editor.addItem(v)
|
||||
|
||||
def initialize(self, book_id):
|
||||
val = self.db.get_custom(book_id, num=self.col_id, index_is_id=True)
|
||||
val = self.normalize_db_val(val)
|
||||
idx = self.widgets[1].findText(val)
|
||||
idx = self.editor.findText(val)
|
||||
if idx < 0:
|
||||
error_dialog(self.parent, '',
|
||||
_('The enumeration "{0}" contains an invalid value '
|
||||
@ -668,14 +681,14 @@ class Enumeration(Base):
|
||||
show=True, show_copy_button=False)
|
||||
|
||||
idx = 0
|
||||
self.widgets[1].setCurrentIndex(idx)
|
||||
self.editor.setCurrentIndex(idx)
|
||||
self.initial_val = self.current_val
|
||||
|
||||
def setter(self, val):
|
||||
self.widgets[1].setCurrentIndex(self.widgets[1].findText(val))
|
||||
self.editor.setCurrentIndex(self.editor.findText(val))
|
||||
|
||||
def getter(self):
|
||||
return unicode_type(self.widgets[1].currentText())
|
||||
return unicode_type(self.editor.currentText())
|
||||
|
||||
def normalize_db_val(self, val):
|
||||
if val is None:
|
||||
@ -687,9 +700,12 @@ class Enumeration(Base):
|
||||
val = None
|
||||
return val
|
||||
|
||||
def set_to_undefined(self):
|
||||
self.editor.setCurrentIndex(0)
|
||||
|
||||
def connect_data_changed(self, slot):
|
||||
self.widgets[1].currentIndexChanged.connect(slot)
|
||||
self.signals_to_disconnect.append(self.widgets[1].currentIndexChanged)
|
||||
self.editor.currentIndexChanged.connect(slot)
|
||||
self.signals_to_disconnect.append(self.editor.currentIndexChanged)
|
||||
|
||||
|
||||
def comments_factory(db, key, parent):
|
||||
@ -879,6 +895,16 @@ class BulkBase(Base):
|
||||
ans = list(ans)
|
||||
return ans
|
||||
|
||||
def finish_ui_setup(self, parent):
|
||||
self.was_none = False
|
||||
l = self.widgets[1].layout()
|
||||
self.clear_button = QToolButton(parent)
|
||||
self.clear_button.setIcon(QIcon(I('trash.png')))
|
||||
self.clear_button.setToolTip(_('Clear {0}').format(self.col_metadata['name']))
|
||||
l.insertWidget(1, self.clear_button)
|
||||
l.insertStretch(2)
|
||||
self.clear_button.clicked.connect(self.set_to_undefined)
|
||||
|
||||
def initialize(self, book_ids):
|
||||
self.initial_val = val = self.get_initial_value(book_ids)
|
||||
val = self.normalize_db_val(val)
|
||||
@ -948,7 +974,8 @@ class BulkBool(BulkBase, Bool):
|
||||
def setup_ui(self, parent):
|
||||
self.make_widgets(parent, QComboBox)
|
||||
items = [_('Yes'), _('No')]
|
||||
if not self.db.new_api.pref('bools_are_tristate'):
|
||||
self.bools_are_tristate = self.db.new_api.pref('bools_are_tristate')
|
||||
if not self.bools_are_tristate:
|
||||
items.append('')
|
||||
else:
|
||||
items.append(_('Undefined'))
|
||||
@ -957,10 +984,17 @@ class BulkBool(BulkBase, Bool):
|
||||
for icon, text in zip(icons, items):
|
||||
self.main_widget.addItem(QIcon(icon), text)
|
||||
self.main_widget.blockSignals(False)
|
||||
if self.bools_are_tristate:
|
||||
# Add clear if bools are tristate
|
||||
self.finish_ui_setup(parent)
|
||||
|
||||
def set_to_undefined(self):
|
||||
# Only called if bools are tristate
|
||||
self.main_widget.setCurrentIndex(2)
|
||||
|
||||
def getter(self):
|
||||
val = self.main_widget.currentIndex()
|
||||
if not self.db.new_api.pref('bools_are_tristate'):
|
||||
if not self.bools_are_tristate:
|
||||
return {2: False, 1: False, 0: True}[val]
|
||||
else:
|
||||
return {2: None, 1: False, 0: True}[val]
|
||||
@ -975,14 +1009,13 @@ class BulkBool(BulkBase, Bool):
|
||||
return
|
||||
val = self.gui_val
|
||||
val = self.normalize_ui_val(val)
|
||||
if not self.db.new_api.pref('bools_are_tristate') and val is None:
|
||||
if not self.bools_are_tristate and val is None:
|
||||
val = False
|
||||
self.db.set_custom_bulk(book_ids, val, num=self.col_id, notify=notify)
|
||||
|
||||
def a_c_checkbox_changed(self):
|
||||
if not self.ignore_change_signals:
|
||||
if not self.db.new_api.pref('bools_are_tristate') and \
|
||||
self.main_widget.currentIndex() == 2:
|
||||
if not self.bools_are_tristate and self.main_widget.currentIndex() == 2:
|
||||
self.a_c_checkbox.setChecked(False)
|
||||
else:
|
||||
self.a_c_checkbox.setChecked(True)
|
||||
@ -996,17 +1029,10 @@ class BulkInt(BulkBase):
|
||||
self.finish_ui_setup(parent)
|
||||
|
||||
def finish_ui_setup(self, parent):
|
||||
self.was_none = False
|
||||
BulkBase.finish_ui_setup(self, parent)
|
||||
self.main_widget.setSpecialValueText(_('Undefined'))
|
||||
self.main_widget.setSingleStep(1)
|
||||
self.main_widget.valueChanged.connect(self.valueChanged)
|
||||
l = self.widgets[1].layout()
|
||||
self.clear_button = QToolButton(parent)
|
||||
self.clear_button.setIcon(QIcon(I('trash.png')))
|
||||
self.clear_button.setToolTip(_('Clear {0}').format(self.col_metadata['name']))
|
||||
l.insertWidget(1, self.clear_button)
|
||||
l.insertStretch(2)
|
||||
self.clear_button.clicked.connect(self.set_to_undefined)
|
||||
|
||||
def setter(self, val):
|
||||
if val is None:
|
||||
@ -1029,7 +1055,6 @@ class BulkInt(BulkBase):
|
||||
def set_to_undefined(self):
|
||||
self.main_widget.setValue(-1000000)
|
||||
|
||||
|
||||
class BulkFloat(BulkInt):
|
||||
|
||||
def setup_ui(self, parent):
|
||||
@ -1047,6 +1072,10 @@ class BulkRating(BulkBase):
|
||||
def setup_ui(self, parent):
|
||||
allow_half_stars = self.col_metadata['display'].get('allow_half_stars', False)
|
||||
self.make_widgets(parent, partial(RatingEditor, is_half_star=allow_half_stars))
|
||||
self.finish_ui_setup(parent)
|
||||
|
||||
def set_to_undefined(self):
|
||||
self.main_widget.setCurrentIndex(0)
|
||||
|
||||
def setter(self, val):
|
||||
val = max(0, min(int(val or 0), 10))
|
||||
@ -1274,12 +1303,16 @@ class BulkEnumeration(BulkBase, Enumeration):
|
||||
def setup_ui(self, parent):
|
||||
self.parent = parent
|
||||
self.make_widgets(parent, QComboBox)
|
||||
self.finish_ui_setup(parent)
|
||||
vals = self.col_metadata['display']['enum_values']
|
||||
self.main_widget.blockSignals(True)
|
||||
self.main_widget.addItem('')
|
||||
self.main_widget.addItems(vals)
|
||||
self.main_widget.blockSignals(False)
|
||||
|
||||
def set_to_undefined(self):
|
||||
self.main_widget.setCurrentIndex(0)
|
||||
|
||||
def getter(self):
|
||||
return unicode_type(self.main_widget.currentText())
|
||||
|
||||
@ -1359,6 +1392,10 @@ class BulkText(BulkBase):
|
||||
self.main_widget.setMinimumContentsLength(25)
|
||||
self.ignore_change_signals = False
|
||||
self.parent = parent
|
||||
self.finish_ui_setup(parent)
|
||||
|
||||
def set_to_undefined(self):
|
||||
self.main_widget.clearEditText()
|
||||
|
||||
def initialize(self, book_ids):
|
||||
self.main_widget.update_items_cache(self.all_values)
|
||||
|
Loading…
x
Reference in New Issue
Block a user