Refactor bulk custom widgets to add an 'apply changes' checkbox to each widget

This commit is contained in:
Charles Haley 2011-01-27 13:15:35 +00:00
parent ceea626264
commit ff2c0f0d2c

View File

@ -151,12 +151,27 @@ class DateEdit(QDateEdit):
def set_to_today(self):
self.setDate(now())
def set_to_clear(self):
self.setDate(UNDEFINED_QDATE)
class DateTime(Base):
def setup_ui(self, parent):
cm = self.col_metadata
self.widgets = [QLabel('&'+cm['name']+':', parent), DateEdit(parent),
QLabel(''), QPushButton(_('Set \'%s\' to today')%cm['name'], parent)]
self.widgets = [QLabel('&'+cm['name']+':', parent), DateEdit(parent)]
self.widgets.append(QLabel(''))
w = QWidget(parent)
self.widgets.append(w)
l = QHBoxLayout()
l.setContentsMargins(0, 0, 0, 0)
w.setLayout(l)
l.addStretch(1)
self.today_button = QPushButton(_('Set \'%s\' to today')%cm['name'], parent)
l.addWidget(self.today_button)
self.clear_button = QPushButton(_('Clear \'%s\'')%cm['name'], parent)
l.addWidget(self.clear_button)
l.addStretch(2)
w = self.widgets[1]
format = cm['display'].get('date_format','')
if not format:
@ -165,7 +180,8 @@ class DateTime(Base):
w.setCalendarPopup(True)
w.setMinimumDate(UNDEFINED_QDATE)
w.setSpecialValueText(_('Undefined'))
self.widgets[3].clicked.connect(w.set_to_today)
self.today_button.clicked.connect(w.set_to_today)
self.clear_button.clicked.connect(w.set_to_clear)
def setter(self, val):
if val is None:
@ -470,11 +486,48 @@ class BulkBase(Base):
self.setter(val)
def commit(self, book_ids, notify=False):
if not self.a_c_checkbox.isChecked():
return
val = self.gui_val
val = self.normalize_ui_val(val)
if val != self.initial_val:
self.db.set_custom_bulk(book_ids, val, num=self.col_id, notify=notify)
def make_widgets(self, parent, main_widget_class, extra_label_text=''):
w = QWidget(parent)
self.widgets = [QLabel('&'+self.col_metadata['name']+':', w), w]
l = QHBoxLayout()
l.setContentsMargins(0, 0, 0, 0)
w.setLayout(l)
self.main_widget = main_widget_class(w)
l.addWidget(self.main_widget)
l.setStretchFactor(self.main_widget, 10)
self.a_c_checkbox = QCheckBox( _('Apply changes'), w)
l.addWidget(self.a_c_checkbox)
self.ignore_change_signals = True
# connect to the various changed signals so we can auto-update the
# apply changes checkbox
if hasattr(self.main_widget, 'editTextChanged'):
# editable combobox widgets
self.main_widget.editTextChanged.connect(self.a_c_checkbox_changed)
if hasattr(self.main_widget, 'textChanged'):
# lineEdit widgets
self.main_widget.textChanged.connect(self.a_c_checkbox_changed)
if hasattr(self.main_widget, 'currentIndexChanged'):
# combobox widgets
self.main_widget.currentIndexChanged[int].connect(self.a_c_checkbox_changed)
if hasattr(self.main_widget, 'valueChanged'):
# spinbox widgets
self.main_widget.valueChanged.connect(self.a_c_checkbox_changed)
if hasattr(self.main_widget, 'dateChanged'):
# dateEdit widgets
self.main_widget.dateChanged.connect(self.a_c_checkbox_changed)
def a_c_checkbox_changed(self):
if not self.ignore_change_signals:
self.a_c_checkbox.setChecked(True)
class BulkBool(BulkBase, Bool):
def get_initial_value(self, book_ids):
@ -484,58 +537,144 @@ class BulkBool(BulkBase, Bool):
if tweaks['bool_custom_columns_are_tristate'] == 'no' and val is None:
val = False
if value is not None and value != val:
return 'nochange'
return None
value = val
return value
def setup_ui(self, parent):
self.widgets = [QLabel('&'+self.col_metadata['name']+':', parent),
QComboBox(parent)]
w = self.widgets[1]
items = [_('Yes'), _('No'), _('Undefined'), _('Do not change')]
icons = [I('ok.png'), I('list_remove.png'), I('blank.png'), I('blank.png')]
self.make_widgets(parent, QComboBox)
items = [_('Yes'), _('No'), _('Undefined')]
icons = [I('ok.png'), I('list_remove.png'), I('blank.png')]
self.main_widget.blockSignals(True)
for icon, text in zip(icons, items):
w.addItem(QIcon(icon), text)
self.main_widget.addItem(QIcon(icon), text)
self.main_widget.blockSignals(False)
def getter(self):
val = self.widgets[1].currentIndex()
return {3: 'nochange', 2: None, 1: False, 0: True}[val]
val = self.main_widget.currentIndex()
return {2: None, 1: False, 0: True}[val]
def setter(self, val):
val = {'nochange': 3, None: 2, False: 1, True: 0}[val]
self.widgets[1].setCurrentIndex(val)
val = {None: 2, False: 1, True: 0}[val]
self.main_widget.setCurrentIndex(val)
self.ignore_change_signals = False
def commit(self, book_ids, notify=False):
if not self.a_c_checkbox.isChecked():
return
val = self.gui_val
val = self.normalize_ui_val(val)
if val != self.initial_val and val != 'nochange':
if tweaks['bool_custom_columns_are_tristate'] == 'no' and val is None:
val = False
self.db.set_custom_bulk(book_ids, val, num=self.col_id, notify=notify)
class BulkInt(BulkBase, Int):
pass
class BulkInt(BulkBase):
class BulkFloat(BulkBase, Float):
pass
def setup_ui(self, parent):
self.make_widgets(parent, QSpinBox)
self.main_widget.setRange(-100, sys.maxint)
self.main_widget.setSpecialValueText(_('Undefined'))
self.main_widget.setSingleStep(1)
class BulkRating(BulkBase, Rating):
pass
def setter(self, val):
if val is None:
val = self.main_widget.minimum()
else:
val = int(val)
self.main_widget.setValue(val)
self.ignore_change_signals = False
class BulkDateTime(BulkBase, DateTime):
pass
def getter(self):
val = self.main_widget.value()
if val == self.main_widget.minimum():
val = None
return val
class BulkFloat(BulkInt):
def setup_ui(self, parent):
self.make_widgets(parent, QDoubleSpinBox)
self.main_widget.setRange(-100., float(sys.maxint))
self.main_widget.setDecimals(2)
self.main_widget.setSpecialValueText(_('Undefined'))
self.main_widget.setSingleStep(1)
class BulkRating(BulkBase):
def setup_ui(self, parent):
self.make_widgets(parent, QSpinBox)
self.main_widget.setRange(0, 5)
self.main_widget.setSuffix(' '+_('star(s)'))
self.main_widget.setSpecialValueText(_('Unrated'))
self.main_widget.setSingleStep(1)
def setter(self, val):
if val is None:
val = 0
self.main_widget.setValue(int(round(val/2.)))
self.ignore_change_signals = False
def getter(self):
val = self.main_widget.value()
if val == 0:
val = None
else:
val *= 2
return val
class BulkDateTime(BulkBase):
def setup_ui(self, parent):
cm = self.col_metadata
self.make_widgets(parent, DateEdit)
self.widgets.append(QLabel(''))
w = QWidget(parent)
self.widgets.append(w)
l = QHBoxLayout()
l.setContentsMargins(0, 0, 0, 0)
w.setLayout(l)
l.addStretch(1)
self.today_button = QPushButton(_('Set \'%s\' to today')%cm['name'], parent)
l.addWidget(self.today_button)
self.clear_button = QPushButton(_('Clear \'%s\'')%cm['name'], parent)
l.addWidget(self.clear_button)
l.addStretch(2)
w = self.main_widget
format = cm['display'].get('date_format','')
if not format:
format = 'dd MMM yyyy'
w.setDisplayFormat(format)
w.setCalendarPopup(True)
w.setMinimumDate(UNDEFINED_QDATE)
w.setSpecialValueText(_('Undefined'))
self.today_button.clicked.connect(w.set_to_today)
self.clear_button.clicked.connect(w.set_to_clear)
def setter(self, val):
if val is None:
val = self.main_widget.minimumDate()
else:
val = QDate(val.year, val.month, val.day)
self.main_widget.setDate(val)
self.ignore_change_signals = False
def getter(self):
val = self.main_widget.date()
if val == UNDEFINED_QDATE:
val = None
else:
val = qt_to_dt(val)
return val
class BulkSeries(BulkBase):
def setup_ui(self, parent):
self.make_widgets(parent, EnComboBox)
values = self.all_values = list(self.db.all_custom(num=self.col_id))
values.sort(key=sort_key)
w = EnComboBox(parent)
w.setSizeAdjustPolicy(w.AdjustToMinimumContentsLengthWithIcon)
w.setMinimumContentsLength(25)
self.name_widget = w
self.widgets = [QLabel('&'+self.col_metadata['name']+':', parent), w]
self.main_widget.setSizeAdjustPolicy(self.main_widget.AdjustToMinimumContentsLengthWithIcon)
self.main_widget.setMinimumContentsLength(25)
self.widgets.append(QLabel('', parent))
w = QWidget(parent)
layout = QHBoxLayout(w)
@ -555,15 +694,24 @@ class BulkSeries(BulkBase):
layout.addWidget(self.series_start_number)
layout.addItem(QSpacerItem(20, 10, QSizePolicy.Expanding, QSizePolicy.Minimum))
self.widgets.append(w)
self.idx_widget.stateChanged.connect(self.check_changed_checkbox)
self.force_number.stateChanged.connect(self.check_changed_checkbox)
self.series_start_number.valueChanged.connect(self.check_changed_checkbox)
self.remove_series.stateChanged.connect(self.check_changed_checkbox)
self.ignore_change_signals = False
def check_changed_checkbox(self):
self.a_c_checkbox.setChecked(True)
def initialize(self, book_id):
self.idx_widget.setChecked(False)
for c in self.all_values:
self.name_widget.addItem(c)
self.name_widget.setEditText('')
self.main_widget.addItem(c)
self.main_widget.setEditText('')
self.a_c_checkbox.setChecked(False)
def getter(self):
n = unicode(self.name_widget.currentText()).strip()
n = unicode(self.main_widget.currentText()).strip()
i = self.idx_widget.checkState()
f = self.force_number.checkState()
s = self.series_start_number.value()
@ -571,6 +719,8 @@ class BulkSeries(BulkBase):
return n, i, f, s, r
def commit(self, book_ids, notify=False):
if not self.a_c_checkbox.isChecked():
return
val, update_indices, force_start, at_value, clear = self.gui_val
val = None if clear else self.normalize_ui_val(val)
if clear or val != '':
@ -598,9 +748,9 @@ class BulkEnumeration(BulkBase, Enumeration):
def get_initial_value(self, book_ids):
value = None
ret_value = None
first = True
dialog_shown = False
for i,book_id in enumerate(book_ids):
for book_id in book_ids:
val = self.db.get_custom(book_id, num=self.col_id, index_is_id=True)
if val and val not in self.col_metadata['display']['enum_values']:
if not dialog_shown:
@ -610,44 +760,32 @@ class BulkEnumeration(BulkBase, Enumeration):
self.col_metadata['name']),
show=True, show_copy_button=False)
dialog_shown = True
ret_value = ' nochange '
elif (value is not None and value != val) or (val and i != 0):
ret_value = ' nochange '
if first:
value = val
if ret_value is None:
first = False
elif value != val:
value = None
if not value:
self.ignore_change_signals = False
return value
return ret_value
def setup_ui(self, parent):
self.parent = parent
self.widgets = [QLabel('&'+self.col_metadata['name']+':', parent),
QComboBox(parent)]
w = self.widgets[1]
self.make_widgets(parent, QComboBox)
vals = self.col_metadata['display']['enum_values']
w.addItem('Do Not Change')
w.addItem('')
for v in vals:
w.addItem(v)
self.main_widget.blockSignals(True)
self.main_widget.addItem('')
self.main_widget.addItems(vals)
self.main_widget.blockSignals(False)
def getter(self):
if self.widgets[1].currentIndex() == 0:
return ' nochange '
return unicode(self.widgets[1].currentText())
return unicode(self.main_widget.currentText())
def setter(self, val):
if val == ' nochange ':
self.widgets[1].setCurrentIndex(0)
else:
if val is None:
self.widgets[1].setCurrentIndex(1)
self.main_widget.setCurrentIndex(0)
else:
self.widgets[1].setCurrentIndex(self.widgets[1].findText(val))
def commit(self, book_ids, notify=False):
val = self.gui_val
val = self.normalize_ui_val(val)
if val != self.initial_val and val != ' nochange ':
self.db.set_custom_bulk(book_ids, val, num=self.col_id, notify=notify)
self.main_widget.setCurrentIndex(self.main_widget.findText(val))
self.ignore_change_signals = False
class RemoveTags(QWidget):
@ -658,11 +796,10 @@ class RemoveTags(QWidget):
layout.setContentsMargins(0, 0, 0, 0)
self.tags_box = CompleteLineEdit(parent, values)
layout.addWidget(self.tags_box, stretch = 1)
# self.tags_box.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
layout.addWidget(self.tags_box, stretch=3)
self.checkbox = QCheckBox(_('Remove all tags'), parent)
layout.addWidget(self.checkbox)
layout.addStretch(1)
self.setLayout(layout)
self.connect(self.checkbox, SIGNAL('stateChanged(int)'), self.box_touched)
@ -679,39 +816,45 @@ class BulkText(BulkBase):
values = self.all_values = list(self.db.all_custom(num=self.col_id))
values.sort(key=sort_key)
if self.col_metadata['is_multiple']:
w = CompleteLineEdit(parent, values)
w.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
self.widgets = [QLabel('&'+self.col_metadata['name']+': ' +
_('tags to add'), parent), w]
self.adding_widget = w
self.make_widgets(parent, CompleteLineEdit,
extra_label_text=_('tags to add'))
self.main_widget.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
self.adding_widget = self.main_widget
w = RemoveTags(parent, values)
self.widgets.append(QLabel('&'+self.col_metadata['name']+': ' +
_('tags to remove'), parent))
self.widgets.append(w)
self.removing_widget = w
w.tags_box.textChanged.connect(self.a_c_checkbox_changed)
w.checkbox.stateChanged.connect(self.a_c_checkbox_changed)
else:
w = EnComboBox(parent)
w.setSizeAdjustPolicy(w.AdjustToMinimumContentsLengthWithIcon)
w.setMinimumContentsLength(25)
self.widgets = [QLabel('&'+self.col_metadata['name']+':', parent), w]
self.make_widgets(parent, EnComboBox)
self.main_widget.setSizeAdjustPolicy(
self.main_widget.AdjustToMinimumContentsLengthWithIcon)
self.main_widget.setMinimumContentsLength(25)
self.ignore_change_signals = False
def initialize(self, book_ids):
if self.col_metadata['is_multiple']:
self.widgets[1].update_items_cache(self.all_values)
self.main_widget.update_items_cache(self.all_values)
else:
val = self.get_initial_value(book_ids)
self.initial_val = val = self.normalize_db_val(val)
idx = None
self.main_widget.blockSignals(True)
for i, c in enumerate(self.all_values):
if c == val:
idx = i
self.widgets[1].addItem(c)
self.widgets[1].setEditText('')
self.main_widget.addItem(c)
self.main_widget.setEditText('')
if idx is not None:
self.widgets[1].setCurrentIndex(idx)
self.main_widget.setCurrentIndex(idx)
self.main_widget.blockSignals(False)
def commit(self, book_ids, notify=False):
if not self.a_c_checkbox.isChecked():
return
if self.col_metadata['is_multiple']:
remove_all, adding, rtext = self.gui_val
remove = set()
@ -740,7 +883,7 @@ class BulkText(BulkBase):
unicode(self.adding_widget.text()), \
unicode(self.removing_widget.tags_box.text())
val = unicode(self.widgets[1].currentText()).strip()
val = unicode(self.main_widget.currentText()).strip()
if not val:
val = None
return val