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]