Add option to bulk metadata edit dialog to force series renumbering starting at a given number

This commit is contained in:
Kovid Goyal 2010-09-21 13:34:23 -06:00
commit 822a83b434
4 changed files with 89 additions and 25 deletions

View File

@ -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)

View File

@ -270,18 +270,63 @@
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QCheckBox" name="autonumber_series">
<property name="toolTip">
<string>Selected books will be automatically numbered,
in the order you selected them.
So if you selected Book A and then Book B,
<item row="8" column="1" colspan="2">
<layout class="QHBoxLayout" name="HLayout_3">
<item>
<widget class="QCheckBox" name="autonumber_series">
<property name="toolTip">
<string>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.</string>
</property>
<property name="text">
<string>Automatically number books in this series</string>
</property>
</widget>
</property>
<property name="text">
<string>Automatically number books in this series</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="series_numbering_restarts">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>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</string>
</property>
<property name="text">
<string>Force numbers to start with </string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="series_start_number">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="value">
<number>1</number>
</property>
</widget>
</item>
<item>
<spacer name="HSpacer_34">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>10</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="10" column="0" colspan="2">
<widget class="QCheckBox" name="remove_conversion_settings">
@ -599,7 +644,7 @@ nothing should be put between the original text and the inserted text</string>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
<height>0</height>
</size>
</property>
</spacer>

View File

@ -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

View File

@ -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]