diff --git a/src/calibre/ebooks/metadata/__init__.py b/src/calibre/ebooks/metadata/__init__.py index fe8ad7fbb5..8a08817450 100644 --- a/src/calibre/ebooks/metadata/__init__.py +++ b/src/calibre/ebooks/metadata/__init__.py @@ -394,9 +394,9 @@ def check_doi(doi): return doi_check.group() return None -def rating_to_stars(value, allow_half_star=False, star=u'★', half=u'½'): +def rating_to_stars(value, allow_half_stars=False, star=u'★', half=u'½'): r = max(0, min(int(value), 10)) - if allow_half_star: + if allow_half_stars: ans = u'★' * (r // 2) if r % 2: ans += u'½' diff --git a/src/calibre/gui2/custom_column_widgets.py b/src/calibre/gui2/custom_column_widgets.py index 951c00694c..b334c72db9 100644 --- a/src/calibre/gui2/custom_column_widgets.py +++ b/src/calibre/gui2/custom_column_widgets.py @@ -824,25 +824,16 @@ class BulkFloat(BulkInt): 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(_('Not rated')) - self.main_widget.setSingleStep(1) + allow_half_stars = self.col_metadata['display'].get('allow_half_stars', False) + self.make_widgets(parent, partial(RatingEditor, is_half_star=allow_half_stars)) def setter(self, val): - if val is None: - val = 0 - self.main_widget.setValue(int(round(val/2.))) + val = max(0, min(int(val or 0), 10)) + self.main_widget.rating_value = val self.ignore_change_signals = False def getter(self): - val = self.main_widget.value() - if val == 0: - val = None - else: - val *= 2 - return val + return self.main_widget.rating_value or None class BulkDateTime(BulkBase): diff --git a/src/calibre/gui2/dialogs/metadata_bulk.py b/src/calibre/gui2/dialogs/metadata_bulk.py index 52ee3a5e5b..cc09b80a06 100644 --- a/src/calibre/gui2/dialogs/metadata_bulk.py +++ b/src/calibre/gui2/dialogs/metadata_bulk.py @@ -231,7 +231,7 @@ class MyBlockingBusy(QDialog): # {{{ # Various fields if args.rating != -1: - cache.set_field('rating', {bid:args.rating*2 for bid in self.ids}) + cache.set_field('rating', {bid:args.rating for bid in self.ids}) if args.clear_pub: cache.set_field('publisher', {bid:'' for bid in self.ids}) @@ -341,6 +341,7 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog): self.remove_format.setCurrentIndex(-1) self.series.currentIndexChanged[int].connect(self.series_changed) + self.rating.currentIndexChanged.connect(lambda:self.apply_rating.setChecked(True)) self.series.editTextChanged.connect(self.series_changed) self.tag_editor_button.clicked.connect(self.tag_editor) self.autonumber_series.stateChanged[int].connect(self.auto_number_changed) @@ -981,7 +982,9 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog): au = unicode(self.authors.text()) aus = unicode(self.author_sort.text()) do_aus = self.author_sort.isEnabled() - rating = self.rating.value() + rating = self.rating.rating_value + if not self.apply_rating.isChecked(): + rating = -1 pub = unicode(self.publisher.text()) do_series = self.write_series clear_series = self.clear_series.isChecked() diff --git a/src/calibre/gui2/dialogs/metadata_bulk.ui b/src/calibre/gui2/dialogs/metadata_bulk.ui index 8bc0ac79cb..555e092e31 100644 --- a/src/calibre/gui2/dialogs/metadata_bulk.ui +++ b/src/calibre/gui2/dialogs/metadata_bulk.ui @@ -61,6 +61,13 @@ &Basic metadata + + + + &Apply date + + + @@ -74,14 +81,14 @@ - + true - + @@ -118,7 +125,7 @@ - + Specify how the author(s) of this book should be sorted. For example Charles Dickens should be sorted as Dickens, Charles. @@ -138,34 +145,6 @@ - - - - Rating of this book. 0-5 stars - - - Rating of this book. 0-5 stars - - - QAbstractSpinBox::PlusMinus - - - No change - - - stars - - - -1 - - - 5 - - - -1 - - - @@ -179,14 +158,14 @@ - + true - + If checked, the publisher will be cleared @@ -209,14 +188,14 @@ - + Tags categorize the book. This is particularly useful while searching. <br><br>They can be any words or phrases, separated by commas. - + Open Tag Editor @@ -243,14 +222,14 @@ - + Comma separated list of tags to remove from the books. - + Check this box to remove all tags from the books. @@ -276,7 +255,7 @@ - + @@ -304,7 +283,7 @@ - + If checked, the series will be cleared @@ -314,7 +293,7 @@ - + @@ -397,7 +376,47 @@ from the value in the box - + + + + + + Control how the default generated covers are created + + + Configure co&ver generation + + + + + + + + 0 + 0 + + + + Set the co&mments for all selected books + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + @@ -422,7 +441,7 @@ from the value in the box - + &Apply date @@ -442,7 +461,7 @@ from the value in the box - + @@ -470,13 +489,6 @@ from the value in the box - - - - &Apply date - - - @@ -490,10 +502,10 @@ from the value in the box - + - + Remove &all @@ -510,7 +522,7 @@ from the value in the box - + @@ -567,7 +579,7 @@ for e.g., EPUB to EPUB, calibre saves the original EPUB - + @@ -617,7 +629,7 @@ Future conversion of these books will use the default settings. - + Change &cover @@ -670,46 +682,6 @@ as that of the first selected book. - - - - - - Control how the default generated covers are created - - - Configure co&ver generation - - - - - - - - 0 - 0 - - - - Set the co&mments for all selected books - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - @@ -723,6 +695,16 @@ as that of the first selected book. + + + + + + + &Apply rating + + + @@ -1209,8 +1191,8 @@ not multiple and the destination field is multiple 0 0 - 922 - 268 + 210 + 66 @@ -1325,6 +1307,11 @@ is completed. This can be slow on large libraries. QComboBox
calibre/gui2/languages.h
+ + RatingEditor + QComboBox +
calibre/gui2/widgets2.h
+
authors diff --git a/src/calibre/gui2/widgets2.py b/src/calibre/gui2/widgets2.py index c3ad2c01cc..e168388199 100644 --- a/src/calibre/gui2/widgets2.py +++ b/src/calibre/gui2/widgets2.py @@ -192,6 +192,7 @@ class RatingModel(QAbstractListModel): QAbstractListModel.__init__(self, parent) self.is_half_star = is_half_star self.rating_font = QFont(rating_font()) + self.null_text = _('Not rated') def rowCount(self, parent=QModelIndex()): return 11 if self.is_half_star else 6 @@ -199,7 +200,7 @@ class RatingModel(QAbstractListModel): def data(self, index, role=Qt.DisplayRole): if role == Qt.DisplayRole: val = index.row() * (1 if self.is_half_star else 2) - return rating_to_stars(val, self.is_half_star) or _('Not rated') + return rating_to_stars(val, self.is_half_star) or self.null_text if role == Qt.FontRole: return QApplication.instance().font() if index.row() == 0 else self.rating_font @@ -235,6 +236,15 @@ class RatingEditor(QComboBox): self.setMaxVisibleItems(self.count()) self.currentIndexChanged.connect(self.update_font) + @property + def null_text(self): + return self._model.null_text + + @null_text.setter + def null_text(self, val): + self._model.null_text = val + self._model.dataChanged.emit(self._model.index(0, 0), self._model.index(0, 0)) + def update_font(self): if self.currentIndex() == 0: self.setFont(QApplication.instance().font())