From 52a24def0848ee3875f7156060cdce29ff4745f8 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 10 Apr 2016 09:51:09 +0530 Subject: [PATCH] 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) --- src/calibre/gui2/dialogs/tag_editor.py | 16 +++++++------ src/calibre/gui2/tag_mapper.py | 33 ++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/calibre/gui2/dialogs/tag_editor.py b/src/calibre/gui2/dialogs/tag_editor.py index d49b480e3b..0153ffb10c 100644 --- a/src/calibre/gui2/dialogs/tag_editor.py +++ b/src/calibre/gui2/dialogs/tag_editor.py @@ -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) diff --git a/src/calibre/gui2/tag_mapper.py b/src/calibre/gui2/tag_mapper.py index 8449c150bb..e9da3db7a8 100644 --- a/src/calibre/gui2/tag_mapper.py +++ b/src/calibre/gui2/tag_mapper.py @@ -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 {