From 4a4f6990773f988892ea9a112b62731a5b39fca7 Mon Sep 17 00:00:00 2001 From: Philipp Wolfer Date: Sat, 22 Feb 2020 19:13:26 +0000 Subject: [PATCH] PICARD-1760: Prevent duplicates in top tags editor --- picard/ui/ui_widget_taglisteditor.py | 4 +-- picard/ui/widgets/editablelistview.py | 45 +++++++++++++++++++++++++-- ui/widget_taglisteditor.ui | 4 +-- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/picard/ui/ui_widget_taglisteditor.py b/picard/ui/ui_widget_taglisteditor.py index b4c38e6fd..03aa58eff 100644 --- a/picard/ui/ui_widget_taglisteditor.py +++ b/picard/ui/ui_widget_taglisteditor.py @@ -17,7 +17,7 @@ class Ui_TagListEditor(object): self.horizontalLayout.setObjectName("horizontalLayout") self.verticalLayout = QtWidgets.QVBoxLayout() self.verticalLayout.setObjectName("verticalLayout") - self.tag_list_view = EditableListView(TagListEditor) + self.tag_list_view = UniqueEditableListView(TagListEditor) self.tag_list_view.setDragDropMode(QtWidgets.QAbstractItemView.InternalMove) self.tag_list_view.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) self.tag_list_view.setObjectName("tag_list_view") @@ -74,4 +74,4 @@ class Ui_TagListEditor(object): self.tags_remove_btn.setToolTip(_("Remove selected tags")) self.tags_remove_btn.setAccessibleName(_("Remove selected tags")) self.tags_remove_btn.setText(_("Remove tags")) -from picard.ui.widgets.editablelistview import EditableListView +from picard.ui.widgets.editablelistview import UniqueEditableListView diff --git a/picard/ui/widgets/editablelistview.py b/picard/ui/widgets/editablelistview.py index 4726f5fb4..2b4dd5d16 100644 --- a/picard/ui/widgets/editablelistview.py +++ b/picard/ui/widgets/editablelistview.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # # Picard, the next-generation MusicBrainz tagger -# Copyright (C) 2019 Philipp Wolfer +# Copyright (C) 2019-2020 Philipp Wolfer # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -113,7 +113,7 @@ class EditableListView(QtWidgets.QListView): def select_key(self, value): model = self.model() - for row in range(0, model.rowCount() - 1): + for row in range(0, model.rowCount()): index = model.createIndex(row, 0) if value == index.data(QtCore.Qt.EditRole): self.setCurrentIndex(index) @@ -134,6 +134,46 @@ class EditableListView(QtWidgets.QListView): selection.setCurrentIndex(new_index, QtCore.QItemSelectionModel.Current) +class UniqueEditableListView(EditableListView): + def __init__(self, parent=None): + super().__init__(parent) + self._is_drag_drop = False + + def setModel(self, model): + current_model = self.model() + if current_model: + current_model.dataChanged.disconnect(self.on_data_changed) + super().setModel(model) + model.dataChanged.connect(self.on_data_changed) + + def dropEvent(self, event): + self._is_drag_drop = True + super().dropEvent(event) + self._is_drag_drop = False + + def on_data_changed(self, top_left, bottom_right, roles): + # Do not drop duplicates during drag and drop as there is always + # a duplicate in the list for a short time in this case. + if self._is_drag_drop: + return + model = self.model() + if QtCore.Qt.EditRole in roles: + value = model.data(top_left, QtCore.Qt.EditRole) + if not value: + return + # Remove duplicate entries from the model + changed_row = top_left.row() + row = 0 + for item in model.items: + if item == value and row != changed_row: + model.removeRow(row) + row -= 1 + if changed_row > row: + changed_row -= 1 + row += 1 + self.select_row(changed_row) + + class EditableListModel(QtCore.QAbstractListModel): user_sortable_changed = QtCore.pyqtSignal(bool) @@ -184,6 +224,7 @@ class EditableListModel(QtCore.QAbstractListModel): elif role == QtCore.Qt.DisplayRole: current = self._items[i] self._items[i] = (current[0], value) + self.dataChanged.emit(index, index, [role]) return True except IndexError: return False diff --git a/ui/widget_taglisteditor.ui b/ui/widget_taglisteditor.ui index 02aff2baa..877b174ba 100644 --- a/ui/widget_taglisteditor.ui +++ b/ui/widget_taglisteditor.ui @@ -32,7 +32,7 @@ - + QAbstractItemView::InternalMove @@ -150,7 +150,7 @@ - EditableListView + UniqueEditableListView QListView
picard.ui.widgets.editablelistview