diff --git a/src/calibre/gui2/custom_column_widgets.py b/src/calibre/gui2/custom_column_widgets.py index 671ffedb57..248c759a17 100644 --- a/src/calibre/gui2/custom_column_widgets.py +++ b/src/calibre/gui2/custom_column_widgets.py @@ -317,9 +317,7 @@ class Text(Base): if self.sep['ui_to_list'] == '&': w.set_space_before_sep(True) w.set_add_separator(tweaks['authors_completer_append_separator']) - w.get_editor_button().setVisible(False) - else: - w.get_editor_button().clicked.connect(self.edit) + w.get_editor_button().clicked.connect(self.edit) w.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred) else: w = EditWithComplete(parent) diff --git a/src/calibre/gui2/dialogs/tag_editor.py b/src/calibre/gui2/dialogs/tag_editor.py index eb68cf978f..3481782b2e 100644 --- a/src/calibre/gui2/dialogs/tag_editor.py +++ b/src/calibre/gui2/dialogs/tag_editor.py @@ -3,7 +3,7 @@ __copyright__ = '2008, Kovid Goyal ' from functools import partial -from PyQt5.Qt import Qt, QDialog +from PyQt5.Qt import Qt, QDialog, QAbstractItemView from calibre.gui2.dialogs.tag_editor_ui import Ui_TagEditor from calibre.gui2 import question_dialog, error_dialog, gprefs @@ -18,7 +18,15 @@ class TagEditor(QDialog, Ui_TagEditor): self.setupUi(self) self.db = db + self.sep = ',' + self.is_names = False if key: + # Assume that if given a key then it is a custom column + try: + self.is_names = db.field_metadata[key]['display'].get('is_names', False) + self.sep = '&' + except Exception: + pass key = db.field_metadata.key_to_label(key) self.key = key self.index = db.row(id_) if id_ is not None else None @@ -32,13 +40,16 @@ class TagEditor(QDialog, Ui_TagEditor): else: tags = [] if tags: - tags.sort(key=sort_key) + if not self.is_names: + tags.sort(key=sort_key) for tag in tags: self.applied_tags.addItem(tag) else: tags = [] - self.tags = tags + if self.is_names: + self.applied_tags.setDragDropMode(QAbstractItemView.InternalMove) + self.applied_tags.setSelectionMode(QAbstractItemView.ExtendedSelection) if key: all_tags = [tag for tag in self.db.all_custom(label=key)] @@ -108,14 +119,16 @@ class TagEditor(QDialog, Ui_TagEditor): items = self.available_tags.selectedItems() if item is None else [item] rows = [self.available_tags.row(i) for i in items] row = max(rows) + tags = self._get_applied_tags_box_contents() for item in items: tag = unicode(item.text()) - self.tags.append(tag) + tags.append(tag) self.available_tags.takeItem(self.available_tags.row(item)) - self.tags.sort(key=sort_key) + if not self.is_names: + tags.sort(key=sort_key) self.applied_tags.clear() - for tag in self.tags: + for tag in tags: self.applied_tags.addItem(tag) if row >= self.available_tags.count(): @@ -128,16 +141,24 @@ class TagEditor(QDialog, Ui_TagEditor): # use the filter again when the applied tags were changed self.filter_tags(self.applied_filter_input.text(), which='applied_tags') + def _get_applied_tags_box_contents(self): + tags = [] + for i in range(0, self.applied_tags.count()): + tags.append(unicode(self.applied_tags.item(i).text())) + return tags + def unapply_tags(self, item=None): + tags = self._get_applied_tags_box_contents() items = self.applied_tags.selectedItems() if item is None else [item] for item in items: tag = unicode(item.text()) - self.tags.remove(tag) + tags.remove(tag) self.available_tags.addItem(tag) - self.tags.sort(key=sort_key) + if not self.is_names: + tags.sort(key=sort_key) self.applied_tags.clear() - for tag in self.tags: + for tag in tags: self.applied_tags.addItem(tag) items = [unicode(self.available_tags.item(x).text()) for x in @@ -152,19 +173,21 @@ class TagEditor(QDialog, Ui_TagEditor): self.filter_tags(self.available_filter_input.text()) def add_tag(self): - tags = unicode(self.add_tag_input.text()).split(',') + tags = unicode(self.add_tag_input.text()).split(self.sep) + tags_in_box = self._get_applied_tags_box_contents() for tag in tags: tag = tag.strip() if not tag: continue for item in self.available_tags.findItems(tag, Qt.MatchFixedString): self.available_tags.takeItem(self.available_tags.row(item)) - if tag not in self.tags: - self.tags.append(tag) + if tag not in tags_in_box: + tags_in_box.append(tag) - self.tags.sort(key=sort_key) + if not self.is_names: + tags_in_box.sort(key=sort_key) self.applied_tags.clear() - for tag in self.tags: + for tag in tags_in_box: self.applied_tags.addItem(tag) self.add_tag_input.setText('') @@ -180,6 +203,7 @@ class TagEditor(QDialog, Ui_TagEditor): item.setHidden(bool(q and not primary_contains(q, unicode(item.text())))) def accept(self): + self.tags = self._get_applied_tags_box_contents() self.save_state() return QDialog.accept(self) @@ -189,3 +213,11 @@ class TagEditor(QDialog, Ui_TagEditor): def save_state(self): gprefs['tag_editor_geometry'] = bytearray(self.saveGeometry()) + +if __name__ == '__main__': + from calibre.gui2 import Application + 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_() diff --git a/src/calibre/gui2/dialogs/tag_list_editor.py b/src/calibre/gui2/dialogs/tag_list_editor.py index db51815584..f9c527b1cf 100644 --- a/src/calibre/gui2/dialogs/tag_list_editor.py +++ b/src/calibre/gui2/dialogs/tag_list_editor.py @@ -2,8 +2,7 @@ __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' from PyQt5.Qt import (Qt, QDialog, QTableWidgetItem, QIcon, QByteArray, QSize, - QDialogButtonBox, QTableWidget, QObject, pyqtSignal, - QEvent, QItemDelegate) + QDialogButtonBox, QTableWidget, QItemDelegate) from calibre.gui2.dialogs.tag_list_editor_ui import Ui_TagListEditor from calibre.gui2.dialogs.confirm_delete import confirm @@ -89,7 +88,7 @@ class EditColumnDelegate(QItemDelegate): return QItemDelegate.createEditor(self, parent, option, index) if not confirm( _('Do you want to undo your changes?'), - 'tag_list_editor_undo'): + 'tag_list_editor_undo'): return item.setText(item.initial_text()) self.table.blockSignals(True) @@ -274,7 +273,7 @@ class TagListEditor(QDialog, Ui_TagListEditor): error_dialog(self, _('No item selected'), _('You must select one item from the list of Available items.')).exec_() return - col_zero_item = self.table.item(item.row(), 0); + col_zero_item = self.table.item(item.row(), 0) if col_zero_item.is_deleted: if not question_dialog(self, _('Undelete item?'), '

'+_('That item is deleted. Do you want to undelete it?')+'
'): @@ -306,13 +305,13 @@ class TagListEditor(QDialog, Ui_TagListEditor): ct = ', '.join([unicode(item.text()) for item in to_del]) if not confirm( '

'+_('Are you sure you want to delete the following items?')+'
'+ct, - 'tag_list_editor_delete'): + 'tag_list_editor_delete'): return if to_undel: ct = ', '.join([unicode(item.text()) for item in to_undel]) if not confirm( '

'+_('Are you sure you want to undelete the following items?')+'
'+ct, - 'tag_list_editor_undelete'): + 'tag_list_editor_undelete'): return row = self.table.row(deletes[0]) for item in deletes: diff --git a/src/calibre/gui2/library/delegates.py b/src/calibre/gui2/library/delegates.py index c4cdc49e59..eed3ed8a8c 100644 --- a/src/calibre/gui2/library/delegates.py +++ b/src/calibre/gui2/library/delegates.py @@ -311,8 +311,7 @@ class CompleteDelegate(QStyledItemDelegate, UpdateEditorGeometry): # {{{ m = index.model() col = m.column_map[index.column()] # If shifted, bring up the tag editor instead of the line editor. - # Don't do this for people-name columns because order will be lost - if QApplication.keyboardModifiers() == Qt.ShiftModifier and self.sep == ',': + if QApplication.keyboardModifiers() == Qt.ShiftModifier and col != 'authors': key = col if m.is_custom_column(col) else None d = TagEditor(parent, self.db, m.id(index.row()), key=key) if d.exec_() == TagEditor.Accepted: