Tag mapper: Add a button to edit the list of tags in a tag mapper rule using the tag editor dialog. Fixes #1568376 [[Enhancement] An easy way to add an unwanted multitued of tags to a Remove rule](https://bugs.launchpad.net/calibre/+bug/1568376)

This commit is contained in:
Kovid Goyal 2016-04-10 09:51:09 +05:30
parent 37b7ab4a13
commit 52a24def08
2 changed files with 40 additions and 9 deletions

View File

@ -12,7 +12,7 @@ from calibre.utils.icu import sort_key, primary_contains
class TagEditor(QDialog, Ui_TagEditor):
def __init__(self, window, db, id_=None, key=None):
def __init__(self, window, db, id_=None, key=None, current_tags=None):
QDialog.__init__(self, window)
Ui_TagEditor.__init__(self)
self.setupUi(self)
@ -40,6 +40,8 @@ class TagEditor(QDialog, Ui_TagEditor):
tags = self.db.get_custom(self.index, label=key)
else:
tags = []
if current_tags is not None:
tags = sorted(set(current_tags), key=sort_key)
if tags:
if not self.is_names:
tags.sort(key=sort_key)
@ -56,10 +58,10 @@ class TagEditor(QDialog, Ui_TagEditor):
all_tags = [tag for tag in self.db.all_custom(label=key)]
else:
all_tags = [tag for tag in self.db.all_tags()]
all_tags = list(set(all_tags))
all_tags.sort(key=sort_key)
all_tags = sorted(set(all_tags), key=sort_key)
q = set(tags)
for tag in all_tags:
if tag not in tags:
if tag not in q:
self.available_tags.addItem(tag)
self.apply_button.clicked.connect(lambda: self.apply_tags())
@ -93,7 +95,6 @@ class TagEditor(QDialog, Ui_TagEditor):
def edit_box_changed(self, which):
gprefs['tag_editor_last_filter'] = which
def delete_tags(self, item=None):
confirms, deletes = [], []
items = self.available_tags.selectedItems() if item is None else [item]
@ -230,5 +231,6 @@ if __name__ == '__main__':
from calibre.library import db
db = db()
app = Application([])
d = TagEditor(None, db, key='#authors', id_=tuple(db.new_api.all_book_ids())[0])
d.exec_()
d = TagEditor(None, db, current_tags='a b c'.split())
if d.exec_() == d.Accepted:
print(d.tags)

View File

@ -16,11 +16,19 @@ from PyQt5.Qt import (
from calibre.ebooks.metadata.tag_mapper import map_tags, compile_pat
from calibre.gui2 import error_dialog, elided_text, Application, question_dialog
from calibre.gui2.ui import get_gui
from calibre.gui2.widgets2 import Dialog
from calibre.utils.config import JSONConfig
tag_maps = JSONConfig('tag-map-rules')
class QueryEdit(QLineEdit):
def contextMenuEvent(self, ev):
menu = self.createStandardContextMenu()
self.parent().specialise_context_menu(menu)
menu.exec_(ev.globalPos())
class RuleEdit(QWidget):
ACTION_MAP = OrderedDict((
@ -66,8 +74,13 @@ class RuleEdit(QWidget):
q.currentIndexChanged.connect(self.update_state)
self.la2 = la = QLabel(':\xa0')
h.addWidget(la)
self.query = q = QLineEdit(self)
self.query = q = QueryEdit(self)
h.addWidget(q)
self.tag_editor_button = b = QToolButton(self)
b.setIcon(QIcon(I('chapters.png')))
b.setToolTip(_('Edit the list of tags with the tag editor'))
h.addWidget(b), b.clicked.connect(self.edit_tags)
b.setVisible(self.can_use_tag_editor)
self.h2 = h = QHBoxLayout()
l.addLayout(h)
self.la3 = la = QLabel(_('with the tag:') + '\xa0')
@ -84,14 +97,30 @@ class RuleEdit(QWidget):
a.setWidth(a.width() + 100)
return a
@property
def can_use_tag_editor(self):
return self.SUBJECT is RuleEdit.SUBJECT and 'matches' not in self.match_type.currentData() and get_gui() is not None
def update_state(self):
replace = self.action.currentData() == 'replace'
self.la3.setVisible(replace), self.replace.setVisible(replace)
tt = _('A comma separated list of tags')
if 'matches' in self.match_type.currentData():
is_match = 'matches' in self.match_type.currentData()
self.tag_editor_button.setVisible(self.can_use_tag_editor)
if is_match:
tt = _('A regular expression')
self.query.setToolTip(tt)
def specialise_context_menu(self, menu):
if self.can_use_tag_editor:
menu.addAction(_('Use the tag editor to edit the list of tags'), self.edit_tags)
def edit_tags(self):
from calibre.gui2.dialogs.tag_editor import TagEditor
d = TagEditor(self, get_gui().current_db, current_tags=filter(None, [x.strip() for x in self.query.text().split(',')]))
if d.exec_() == d.Accepted:
self.query.setText(', '.join(d.tags))
@property
def rule(self):
return {