An attempt at S/R for identifiers.

This commit is contained in:
Charles Haley 2011-03-07 18:57:31 +00:00
parent c7720ffcb2
commit b3c42fc0af
3 changed files with 98 additions and 12 deletions

View File

@ -7,7 +7,7 @@ import re, os, inspect
from PyQt4.Qt import Qt, QDialog, QGridLayout, QVBoxLayout, QFont, QLabel, \ from PyQt4.Qt import Qt, QDialog, QGridLayout, QVBoxLayout, QFont, QLabel, \
pyqtSignal, QDialogButtonBox, QInputDialog, QLineEdit, \ pyqtSignal, QDialogButtonBox, QInputDialog, QLineEdit, \
QDate QDate, QCompleter
from calibre.gui2.dialogs.metadata_bulk_ui import Ui_MetadataBulkDialog from calibre.gui2.dialogs.metadata_bulk_ui import Ui_MetadataBulkDialog
from calibre.gui2.dialogs.tag_editor import TagEditor from calibre.gui2.dialogs.tag_editor import TagEditor
@ -363,7 +363,7 @@ class MetadataBulkDialog(ResizableDialog, Ui_MetadataBulkDialog):
if (f in ['author_sort'] or if (f in ['author_sort'] or
(fm[f]['datatype'] in ['text', 'series', 'enumeration'] (fm[f]['datatype'] in ['text', 'series', 'enumeration']
and fm[f].get('search_terms', None) and fm[f].get('search_terms', None)
and f not in ['formats', 'ondevice']) or and f not in ['formats', 'ondevice', 'id']) or
fm[f]['datatype'] in ['int', 'float', 'bool'] ): fm[f]['datatype'] in ['int', 'float', 'bool'] ):
self.all_fields.append(f) self.all_fields.append(f)
self.writable_fields.append(f) self.writable_fields.append(f)
@ -393,6 +393,11 @@ class MetadataBulkDialog(ResizableDialog, Ui_MetadataBulkDialog):
self.book_1_text.setObjectName(name) self.book_1_text.setObjectName(name)
self.testgrid.addWidget(w, i+offset, 2, 1, 1) self.testgrid.addWidget(w, i+offset, 2, 1, 1)
ident_types = sorted(self.db.get_all_identifier_types(), key=sort_key)
self.s_r_dst_ident.setCompleter(QCompleter(ident_types))
ident_types.insert(0, '')
self.s_r_src_ident.addItems(ident_types)
self.main_heading = _( self.main_heading = _(
'<b>You can destroy your library using this feature.</b> ' '<b>You can destroy your library using this feature.</b> '
'Changes are permanent. There is no undo function. ' 'Changes are permanent. There is no undo function. '
@ -449,6 +454,8 @@ class MetadataBulkDialog(ResizableDialog, Ui_MetadataBulkDialog):
self.test_text.editTextChanged[str].connect(self.s_r_paint_results) self.test_text.editTextChanged[str].connect(self.s_r_paint_results)
self.comma_separated.stateChanged.connect(self.s_r_paint_results) self.comma_separated.stateChanged.connect(self.s_r_paint_results)
self.case_sensitive.stateChanged.connect(self.s_r_paint_results) self.case_sensitive.stateChanged.connect(self.s_r_paint_results)
self.s_r_src_ident.currentIndexChanged[int].connect(self.s_r_paint_results)
self.s_r_dst_ident.textChanged.connect(self.s_r_paint_results)
self.s_r_template.lost_focus.connect(self.s_r_template_changed) self.s_r_template.lost_focus.connect(self.s_r_template_changed)
self.central_widget.setCurrentIndex(0) self.central_widget.setCurrentIndex(0)
@ -471,6 +478,8 @@ class MetadataBulkDialog(ResizableDialog, Ui_MetadataBulkDialog):
self.query_field.addItems(sorted([q for q in self.queries], key=sort_key)) self.query_field.addItems(sorted([q for q in self.queries], key=sort_key))
self.query_field.currentIndexChanged[str].connect(self.s_r_query_change) self.query_field.currentIndexChanged[str].connect(self.s_r_query_change)
self.query_field.setCurrentIndex(0) self.query_field.setCurrentIndex(0)
self.search_field.setCurrentIndex(0)
self.s_r_search_field_changed(0)
def s_r_sf_itemdata(self, idx): def s_r_sf_itemdata(self, idx):
if idx is None: if idx is None:
@ -497,6 +506,10 @@ class MetadataBulkDialog(ResizableDialog, Ui_MetadataBulkDialog):
val = str(val) val = str(val)
elif fm['is_csp']: elif fm['is_csp']:
# convert the csp dict into a list # convert the csp dict into a list
id_type = unicode(self.s_r_src_ident.currentText())
if id_type:
val = [val.get(id_type, '')]
else:
val = [u'%s:%s'%(t[0], t[1]) for t in val.iteritems()] val = [u'%s:%s'%(t[0], t[1]) for t in val.iteritems()]
if val is None: if val is None:
val = [] if fm['is_multiple'] else [''] val = [] if fm['is_multiple'] else ['']
@ -515,12 +528,17 @@ class MetadataBulkDialog(ResizableDialog, Ui_MetadataBulkDialog):
self.s_r_search_field_changed(self.search_field.currentIndex()) self.s_r_search_field_changed(self.search_field.currentIndex())
def s_r_search_field_changed(self, idx): def s_r_search_field_changed(self, idx):
if self.search_mode.currentIndex() != 0 and idx == 1: # Template
self.s_r_template.setVisible(True)
self.template_label.setVisible(True)
else:
self.s_r_template.setVisible(False) self.s_r_template.setVisible(False)
self.template_label.setVisible(False) self.template_label.setVisible(False)
self.s_r_src_ident_label.setVisible(False)
self.s_r_src_ident.setVisible(False)
if idx == 1: # Template
self.s_r_template.setVisible(True)
self.template_label.setVisible(True)
elif self.s_r_sf_itemdata(idx) == 'identifiers':
self.s_r_src_ident_label.setVisible(True)
self.s_r_src_ident.setVisible(True)
for i in range(0, self.s_r_number_of_books): for i in range(0, self.s_r_number_of_books):
w = getattr(self, 'book_%d_text'%(i+1)) w = getattr(self, 'book_%d_text'%(i+1))
mi = self.db.get_metadata(self.ids[i], index_is_id=True) mi = self.db.get_metadata(self.ids[i], index_is_id=True)
@ -538,10 +556,15 @@ class MetadataBulkDialog(ResizableDialog, Ui_MetadataBulkDialog):
self.s_r_paint_results(None) self.s_r_paint_results(None)
def s_r_destination_field_changed(self, idx): def s_r_destination_field_changed(self, idx):
self.s_r_dst_ident_label.setVisible(False)
self.s_r_dst_ident.setVisible(False)
txt = self.s_r_df_itemdata(idx) txt = self.s_r_df_itemdata(idx)
if not txt: if not txt:
txt = self.s_r_sf_itemdata(None) txt = self.s_r_sf_itemdata(None)
if txt and txt in self.writable_fields: if txt and txt in self.writable_fields:
if txt == 'identifiers':
self.s_r_dst_ident_label.setVisible(True)
self.s_r_dst_ident.setVisible(True)
self.destination_field_fm = self.db.metadata_for_field(txt) self.destination_field_fm = self.db.metadata_for_field(txt)
self.s_r_paint_results(None) self.s_r_paint_results(None)
@ -639,6 +662,10 @@ class MetadataBulkDialog(ResizableDialog, Ui_MetadataBulkDialog):
if dest_mode != 0: if dest_mode != 0:
dest_val = mi.get(dest, '') dest_val = mi.get(dest, '')
if self.db.metadata_for_field(dest)['is_csp']: if self.db.metadata_for_field(dest)['is_csp']:
dst_id_type = unicode(self.s_r_dst_ident.text())
if dst_id_type:
dest_val = [dest_val.get(dst_id_type, '')]
else:
# convert the csp dict into a list # convert the csp dict into a list
dest_val = [u'%s:%s'%(t[0], t[1]) for t in dest_val.iteritems()] dest_val = [u'%s:%s'%(t[0], t[1]) for t in dest_val.iteritems()]
if dest_val is None: if dest_val is None:
@ -726,6 +753,13 @@ class MetadataBulkDialog(ResizableDialog, Ui_MetadataBulkDialog):
# convert the colon-separated pair strings back into a dict, which # convert the colon-separated pair strings back into a dict, which
# is what set_identifiers wants # is what set_identifiers wants
if dfm['is_csp']: if dfm['is_csp']:
dst_id_type = unicode(self.s_r_dst_ident.text())
if dst_id_type:
v = ''.join(val)
ids = mi.get(dest)
ids[dst_id_type] = v
val = ids
else:
val = dict([(t.split(':')) for t in val]) val = dict([(t.split(':')) for t in val])
else: else:
val = self.s_r_replace_mode_separator().join(val) val = self.s_r_replace_mode_separator().join(val)

View File

@ -732,6 +732,29 @@ Future conversion of these books will use the default settings.</string>
</item> </item>
</layout> </layout>
</item> </item>
<item row="5" column="0">
<widget class="QLabel" name="s_r_src_ident_label">
<property name="text">
<string>Identifier:</string>
</property>
<property name="buddy">
<cstring>s_r_src_ident</cstring>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QComboBox" name="s_r_src_ident">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>100</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Choose which identifier to operate upon</string>
</property>
</widget>
</item>
<item row="5" column="0"> <item row="5" column="0">
<widget class="QLabel" name="template_label"> <widget class="QLabel" name="template_label">
<property name="text"> <property name="text">
@ -910,7 +933,30 @@ not multiple and the destination field is multiple</string>
</item> </item>
</layout> </layout>
</item> </item>
<item row="9" column="1" colspan="2"> <item row="9" column="0">
<widget class="QLabel" name="s_r_dst_ident_label">
<property name="text">
<string>Identifier:</string>
</property>
<property name="buddy">
<cstring>s_r_dst_ident</cstring>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QLineEdit" name="s_r_dst_ident">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>100</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Choose which identifier to operate upon</string>
</property>
</widget>
</item>
<item row="10" column="1" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_21"> <layout class="QHBoxLayout" name="horizontalLayout_21">
<item> <item>
<spacer name="HSpacer_347"> <spacer name="HSpacer_347">
@ -996,7 +1042,7 @@ not multiple and the destination field is multiple</string>
</item> </item>
</layout> </layout>
</item> </item>
<item row="10" column="0" colspan="4"> <item row="11" column="0" colspan="4">
<widget class="QScrollArea" name="scrollArea11"> <widget class="QScrollArea" name="scrollArea11">
<property name="frameShape"> <property name="frameShape">
<enum>QFrame::NoFrame</enum> <enum>QFrame::NoFrame</enum>
@ -1120,6 +1166,7 @@ not multiple and the destination field is multiple</string>
<tabstop>remove_button</tabstop> <tabstop>remove_button</tabstop>
<tabstop>search_field</tabstop> <tabstop>search_field</tabstop>
<tabstop>search_mode</tabstop> <tabstop>search_mode</tabstop>
<tabstop>s_r_src_ident</tabstop>
<tabstop>s_r_template</tabstop> <tabstop>s_r_template</tabstop>
<tabstop>search_for</tabstop> <tabstop>search_for</tabstop>
<tabstop>case_sensitive</tabstop> <tabstop>case_sensitive</tabstop>
@ -1128,6 +1175,7 @@ not multiple and the destination field is multiple</string>
<tabstop>destination_field</tabstop> <tabstop>destination_field</tabstop>
<tabstop>replace_mode</tabstop> <tabstop>replace_mode</tabstop>
<tabstop>comma_separated</tabstop> <tabstop>comma_separated</tabstop>
<tabstop>s_r_dst_ident</tabstop>
<tabstop>results_count</tabstop> <tabstop>results_count</tabstop>
<tabstop>starting_from</tabstop> <tabstop>starting_from</tabstop>
<tabstop>multiple_separator</tabstop> <tabstop>multiple_separator</tabstop>

View File

@ -2551,6 +2551,10 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
return ans return ans
def get_all_identifier_types(self):
idents = self.conn.get('SELECT DISTINCT type FROM identifiers')
return [ident[0] for ident in idents]
def _clean_identifier(self, typ, val): def _clean_identifier(self, typ, val):
typ = icu_lower(typ).strip().replace(':', '').replace(',', '') typ = icu_lower(typ).strip().replace(':', '').replace(',', '')
val = val.strip().replace(',', '|').replace(':', '|') val = val.strip().replace(',', '|').replace(':', '|')