diff --git a/src/calibre/gui2/dialogs/metadata_bulk.py b/src/calibre/gui2/dialogs/metadata_bulk.py index 7122fe14fa..18d00191cc 100644 --- a/src/calibre/gui2/dialogs/metadata_bulk.py +++ b/src/calibre/gui2/dialogs/metadata_bulk.py @@ -31,7 +31,8 @@ class Worker(Thread): def doit(self): remove, add, au, aus, do_aus, rating, pub, do_series, \ do_autonumber, do_remove_format, remove_format, do_swap_ta, \ - do_remove_conv, do_auto_author, series = self.args + do_remove_conv, do_auto_author, series, do_series_restart, \ + series_start_value = self.args # first loop: do author and title. These will commit at the end of each # operation, because each operation modifies the file system. We want to @@ -69,7 +70,11 @@ class Worker(Thread): self.db.set_publisher(id, pub, notify=False, commit=False) if do_series: - next = self.db.get_next_series_num_for(series) + if do_series_restart: + next = series_start_value + series_start_value += 1 + else: + next = self.db.get_next_series_num_for(series) self.db.set_series(id, series, notify=False, commit=False) num = next if do_autonumber and series else 1.0 self.db.set_series_index(id, num, notify=False, commit=False) @@ -163,6 +168,7 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog): self.series.currentIndexChanged[int].connect(self.series_changed) 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) if len(db.custom_column_label_map) == 0: self.central_widget.removeTab(1) @@ -478,7 +484,10 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog): setter = self.db.set_comment else: setter = getattr(self.db, 'set_'+dest) - setter(id, val, notify=False, commit=False) + if dest in ['title', 'authors']: + setter(id, val, notify=False) + else: + setter(id, val, notify=False, commit=False) self.db.commit() dynamic['s_r_search_mode'] = self.search_mode.currentIndex() @@ -538,6 +547,16 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog): self.tags.update_tags_cache(self.db.all_tags()) self.remove_tags.update_tags_cache(self.db.all_tags()) + def auto_number_changed(self, state): + if state: + self.series_numbering_restarts.setEnabled(True) + self.series_start_number.setEnabled(True) + else: + self.series_numbering_restarts.setEnabled(False) + self.series_numbering_restarts.setChecked(False) + self.series_start_number.setEnabled(False) + self.series_start_number.setValue(1) + def accept(self): if len(self.ids) < 1: return QDialog.accept(self) @@ -566,6 +585,8 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog): do_series = self.write_series series = unicode(self.series.currentText()).strip() do_autonumber = self.autonumber_series.isChecked() + do_series_restart = self.series_numbering_restarts.isChecked() + series_start_value = self.series_start_number.value() do_remove_format = self.remove_format.currentIndex() > -1 remove_format = unicode(self.remove_format.currentText()) do_swap_ta = self.swap_title_and_author.isChecked() @@ -574,7 +595,8 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog): args = (remove, add, au, aus, do_aus, rating, pub, do_series, do_autonumber, do_remove_format, remove_format, do_swap_ta, - do_remove_conv, do_auto_author, series) + do_remove_conv, do_auto_author, series, do_series_restart, + series_start_value) bb = BlockingBusy(_('Applying changes to %d books. This may take a while.') %len(self.ids), parent=self) diff --git a/src/calibre/gui2/dialogs/metadata_bulk.ui b/src/calibre/gui2/dialogs/metadata_bulk.ui index f28f3fb57c..10e22c5df9 100644 --- a/src/calibre/gui2/dialogs/metadata_bulk.ui +++ b/src/calibre/gui2/dialogs/metadata_bulk.ui @@ -270,18 +270,63 @@ - - - - Selected books will be automatically numbered, -in the order you selected them. -So if you selected Book A and then Book B, + + + + + + If not checked, the series number for the books will be set to 1. +If checked, selected books will be automatically numbered, in the order +you selected them. So if you selected Book A and then Book B, Book A will have series number 1 and Book B series number 2. - - - Automatically number books in this series - - + + + Automatically number books in this series + + + + + + + false + + + Series will normally be renumbered from the highest number in the database +for that series. Checking this box will tell calibre to start numbering +from the value in the box + + + Force numbers to start with + + + + + + + false + + + 1 + + + 1 + + + + + + + Qt::Horizontal + + + + 20 + 10 + + + + + @@ -599,7 +644,7 @@ nothing should be put between the original text and the inserted text 20 - 40 + 0 diff --git a/src/calibre/library/caches.py b/src/calibre/library/caches.py index 0b1fabfff9..42feb6f8fa 100644 --- a/src/calibre/library/caches.py +++ b/src/calibre/library/caches.py @@ -333,7 +333,7 @@ class ResultCache(SearchQueryParser): if query and query.strip(): # get metadata key associated with the search term. Eliminates # dealing with plurals and other aliases - location = self.field_metadata.search_term_to_key(location.lower().strip()) + location = self.field_metadata.search_term_to_field_key(location.lower().strip()) if isinstance(location, list): if allow_recursion: for loc in location: @@ -609,12 +609,9 @@ class ResultCache(SearchQueryParser): # Sorting functions {{{ def sanitize_sort_field_name(self, field): - field = field.lower().strip() - if field not in self.field_metadata.iterkeys(): - if field in ('author', 'tag', 'comment'): - field += 's' - if field == 'date': field = 'timestamp' - elif field == 'title': field = 'sort' + field = self.field_metadata.search_term_to_field_key(field.lower().strip()) + # translate some fields to their hidden equivalent + if field == 'title': field = 'sort' elif field == 'authors': field = 'author_sort' return field diff --git a/src/calibre/library/field_metadata.py b/src/calibre/library/field_metadata.py index a8031e5172..bac423f46d 100644 --- a/src/calibre/library/field_metadata.py +++ b/src/calibre/library/field_metadata.py @@ -501,12 +501,12 @@ class FieldMetadata(dict): raise ValueError('Attempt to add duplicate search term "%s"'%t) self._search_term_map[t] = key - def search_term_to_key(self, term): + def search_term_to_field_key(self, term): if term in self._search_term_map: return self._search_term_map[term] return term - def searchable_field_keys(self): + def searchable_fields(self): return [k for k in self._tb_cats.keys() if self._tb_cats[k]['kind']=='field' and len(self._tb_cats[k]['search_terms']) > 0]