PICARD-1760: Prevent duplicates in top tags editor

This commit is contained in:
Philipp Wolfer
2020-02-22 19:13:26 +00:00
committed by GitHub
parent 51f81f1783
commit 4a4f699077
3 changed files with 47 additions and 6 deletions

View File

@@ -17,7 +17,7 @@ class Ui_TagListEditor(object):
self.horizontalLayout.setObjectName("horizontalLayout") self.horizontalLayout.setObjectName("horizontalLayout")
self.verticalLayout = QtWidgets.QVBoxLayout() self.verticalLayout = QtWidgets.QVBoxLayout()
self.verticalLayout.setObjectName("verticalLayout") 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.setDragDropMode(QtWidgets.QAbstractItemView.InternalMove)
self.tag_list_view.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) self.tag_list_view.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
self.tag_list_view.setObjectName("tag_list_view") 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.setToolTip(_("Remove selected tags"))
self.tags_remove_btn.setAccessibleName(_("Remove selected tags")) self.tags_remove_btn.setAccessibleName(_("Remove selected tags"))
self.tags_remove_btn.setText(_("Remove tags")) self.tags_remove_btn.setText(_("Remove tags"))
from picard.ui.widgets.editablelistview import EditableListView from picard.ui.widgets.editablelistview import UniqueEditableListView

View File

@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
# Picard, the next-generation MusicBrainz tagger # 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 # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License
@@ -113,7 +113,7 @@ class EditableListView(QtWidgets.QListView):
def select_key(self, value): def select_key(self, value):
model = self.model() model = self.model()
for row in range(0, model.rowCount() - 1): for row in range(0, model.rowCount()):
index = model.createIndex(row, 0) index = model.createIndex(row, 0)
if value == index.data(QtCore.Qt.EditRole): if value == index.data(QtCore.Qt.EditRole):
self.setCurrentIndex(index) self.setCurrentIndex(index)
@@ -134,6 +134,46 @@ class EditableListView(QtWidgets.QListView):
selection.setCurrentIndex(new_index, QtCore.QItemSelectionModel.Current) 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): class EditableListModel(QtCore.QAbstractListModel):
user_sortable_changed = QtCore.pyqtSignal(bool) user_sortable_changed = QtCore.pyqtSignal(bool)
@@ -184,6 +224,7 @@ class EditableListModel(QtCore.QAbstractListModel):
elif role == QtCore.Qt.DisplayRole: elif role == QtCore.Qt.DisplayRole:
current = self._items[i] current = self._items[i]
self._items[i] = (current[0], value) self._items[i] = (current[0], value)
self.dataChanged.emit(index, index, [role])
return True return True
except IndexError: except IndexError:
return False return False

View File

@@ -32,7 +32,7 @@
<item> <item>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item> <item>
<widget class="EditableListView" name="tag_list_view"> <widget class="UniqueEditableListView" name="tag_list_view">
<property name="dragDropMode"> <property name="dragDropMode">
<enum>QAbstractItemView::InternalMove</enum> <enum>QAbstractItemView::InternalMove</enum>
</property> </property>
@@ -150,7 +150,7 @@
</widget> </widget>
<customwidgets> <customwidgets>
<customwidget> <customwidget>
<class>EditableListView</class> <class>UniqueEditableListView</class>
<extends>QListView</extends> <extends>QListView</extends>
<header>picard.ui.widgets.editablelistview</header> <header>picard.ui.widgets.editablelistview</header>
<slots> <slots>