mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
An attempt at S/R for identifiers.
This commit is contained in:
parent
c7720ffcb2
commit
b3c42fc0af
@ -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)
|
||||||
|
@ -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>
|
||||||
|
@ -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(':', '|')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user