diff --git a/picard/ui/options/interface_top_tags.py b/picard/ui/options/interface_top_tags.py index 870f3d777..fc7748430 100644 --- a/picard/ui/options/interface_top_tags.py +++ b/picard/ui/options/interface_top_tags.py @@ -51,9 +51,6 @@ class InterfaceTopTagsOptionsPage(OptionsPage): super().__init__(parent) self.ui = Ui_InterfaceTopTagsOptionsPage() self.ui.setupUi(self) - selection = self.ui.top_tags_list.selectionModel() - selection.selectionChanged.connect(self.on_selection_changed) - self.on_selection_changed([], []) def load(self): tags = config.setting["metadatabox_top_tags"] @@ -69,11 +66,5 @@ class InterfaceTopTagsOptionsPage(OptionsPage): self.ui.top_tags_list.clear() super().restore_defaults() - def on_selection_changed(self, selected, deselected): - buttons_enabled = len(self.ui.top_tags_list.selectedIndexes()) > 0 - self.ui.tags_remove_btn.setEnabled(buttons_enabled) - self.ui.tags_move_up_btn.setEnabled(buttons_enabled) - self.ui.tags_move_down_btn.setEnabled(buttons_enabled) - register_options_page(InterfaceTopTagsOptionsPage) diff --git a/picard/ui/ui_options_interface_top_tags.py b/picard/ui/ui_options_interface_top_tags.py index dccf49e13..438a2516c 100644 --- a/picard/ui/ui_options_interface_top_tags.py +++ b/picard/ui/ui_options_interface_top_tags.py @@ -10,7 +10,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets class Ui_InterfaceTopTagsOptionsPage(object): def setupUi(self, InterfaceTopTagsOptionsPage): InterfaceTopTagsOptionsPage.setObjectName("InterfaceTopTagsOptionsPage") - InterfaceTopTagsOptionsPage.resize(893, 698) + InterfaceTopTagsOptionsPage.resize(418, 310) self.vboxlayout = QtWidgets.QVBoxLayout(InterfaceTopTagsOptionsPage) self.vboxlayout.setContentsMargins(9, 9, 9, 9) self.vboxlayout.setSpacing(6) @@ -18,65 +18,19 @@ class Ui_InterfaceTopTagsOptionsPage(object): self.label = QtWidgets.QLabel(InterfaceTopTagsOptionsPage) self.label.setObjectName("label") self.vboxlayout.addWidget(self.label) - self.horizontalLayout = QtWidgets.QHBoxLayout() - self.horizontalLayout.setObjectName("horizontalLayout") - self.verticalLayout_2 = QtWidgets.QVBoxLayout() - self.verticalLayout_2.setObjectName("verticalLayout_2") - self.top_tags_list = EditableTagListView(InterfaceTopTagsOptionsPage) - self.top_tags_list.setDragEnabled(True) - self.top_tags_list.setDragDropMode(QtWidgets.QAbstractItemView.InternalMove) + self.top_tags_list = TagListEditor(InterfaceTopTagsOptionsPage) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.top_tags_list.sizePolicy().hasHeightForWidth()) + self.top_tags_list.setSizePolicy(sizePolicy) self.top_tags_list.setObjectName("top_tags_list") - self.verticalLayout_2.addWidget(self.top_tags_list) - self.horizontalLayout_2 = QtWidgets.QHBoxLayout() - self.horizontalLayout_2.setObjectName("horizontalLayout_2") - spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.horizontalLayout_2.addItem(spacerItem) - self.tags_remove_btn = QtWidgets.QPushButton(InterfaceTopTagsOptionsPage) - self.tags_remove_btn.setObjectName("tags_remove_btn") - self.horizontalLayout_2.addWidget(self.tags_remove_btn) - self.tags_add_btn = QtWidgets.QPushButton(InterfaceTopTagsOptionsPage) - self.tags_add_btn.setAccessibleName("") - self.tags_add_btn.setObjectName("tags_add_btn") - self.horizontalLayout_2.addWidget(self.tags_add_btn) - self.verticalLayout_2.addLayout(self.horizontalLayout_2) - self.horizontalLayout.addLayout(self.verticalLayout_2) - self.verticalLayout = QtWidgets.QVBoxLayout() - self.verticalLayout.setObjectName("verticalLayout") - spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.verticalLayout.addItem(spacerItem1) - self.tags_move_up_btn = QtWidgets.QPushButton(InterfaceTopTagsOptionsPage) - self.tags_move_up_btn.setText("") - icon = QtGui.QIcon.fromTheme("go-up") - self.tags_move_up_btn.setIcon(icon) - self.tags_move_up_btn.setObjectName("tags_move_up_btn") - self.verticalLayout.addWidget(self.tags_move_up_btn) - self.tags_move_down_btn = QtWidgets.QPushButton(InterfaceTopTagsOptionsPage) - self.tags_move_down_btn.setText("") - icon = QtGui.QIcon.fromTheme("go-down") - self.tags_move_down_btn.setIcon(icon) - self.tags_move_down_btn.setObjectName("tags_move_down_btn") - self.verticalLayout.addWidget(self.tags_move_down_btn) - spacerItem2 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.verticalLayout.addItem(spacerItem2) - self.horizontalLayout.addLayout(self.verticalLayout) - self.vboxlayout.addLayout(self.horizontalLayout) + self.vboxlayout.addWidget(self.top_tags_list) self.retranslateUi(InterfaceTopTagsOptionsPage) - self.tags_add_btn.clicked.connect(self.top_tags_list.add_empty_row) - self.tags_remove_btn.clicked.connect(self.top_tags_list.remove_selected_rows) - self.tags_move_up_btn.clicked.connect(self.top_tags_list.move_selected_rows_up) - self.tags_move_down_btn.clicked.connect(self.top_tags_list.move_selected_rows_down) QtCore.QMetaObject.connectSlotsByName(InterfaceTopTagsOptionsPage) def retranslateUi(self, InterfaceTopTagsOptionsPage): _translate = QtCore.QCoreApplication.translate self.label.setText(_("Show the below tags above all other tags in the metadata view")) - self.tags_remove_btn.setToolTip(_("Remove selected tags")) - self.tags_remove_btn.setAccessibleName(_("Remove selected tags")) - self.tags_remove_btn.setText(_("Remove tags")) - self.tags_add_btn.setText(_("Add new tag")) - self.tags_move_up_btn.setToolTip(_("Move tag up")) - self.tags_move_up_btn.setAccessibleName(_("Move tag up")) - self.tags_move_down_btn.setToolTip(_("Move tag down")) - self.tags_move_down_btn.setAccessibleName(_("Move tag down")) -from picard.ui.taglistview import EditableTagListView +from picard.ui.widgets.taglisteditor import TagListEditor diff --git a/picard/ui/ui_widget_taglisteditor.py b/picard/ui/ui_widget_taglisteditor.py new file mode 100644 index 000000000..818f5377d --- /dev/null +++ b/picard/ui/ui_widget_taglisteditor.py @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- + +# Automatically generated - don't edit. +# Use `python setup.py build_ui` to update it. + + +from PyQt5 import QtCore, QtGui, QtWidgets + + +class Ui_TagListEditor(object): + def setupUi(self, TagListEditor): + TagListEditor.setObjectName("TagListEditor") + TagListEditor.resize(400, 300) + self.horizontalLayout = QtWidgets.QHBoxLayout(TagListEditor) + self.horizontalLayout.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout.setSpacing(6) + self.horizontalLayout.setObjectName("horizontalLayout") + self.verticalLayout = QtWidgets.QVBoxLayout() + self.verticalLayout.setObjectName("verticalLayout") + self.tag_list_view = EditableListView(TagListEditor) + self.tag_list_view.setObjectName("tag_list_view") + self.verticalLayout.addWidget(self.tag_list_view) + self.horizontalLayout_2 = QtWidgets.QHBoxLayout() + self.horizontalLayout_2.setObjectName("horizontalLayout_2") + spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_2.addItem(spacerItem) + self.tags_remove_btn = QtWidgets.QPushButton(TagListEditor) + self.tags_remove_btn.setObjectName("tags_remove_btn") + self.horizontalLayout_2.addWidget(self.tags_remove_btn) + self.tags_add_btn = QtWidgets.QPushButton(TagListEditor) + self.tags_add_btn.setObjectName("tags_add_btn") + self.horizontalLayout_2.addWidget(self.tags_add_btn) + self.verticalLayout.addLayout(self.horizontalLayout_2) + self.horizontalLayout.addLayout(self.verticalLayout) + self.verticalLayout_2 = QtWidgets.QVBoxLayout() + self.verticalLayout_2.setObjectName("verticalLayout_2") + spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.verticalLayout_2.addItem(spacerItem1) + self.tags_move_up_btn = QtWidgets.QPushButton(TagListEditor) + self.tags_move_up_btn.setText("") + icon = QtGui.QIcon.fromTheme("go-up") + self.tags_move_up_btn.setIcon(icon) + self.tags_move_up_btn.setObjectName("tags_move_up_btn") + self.verticalLayout_2.addWidget(self.tags_move_up_btn) + self.tags_move_down_btn = QtWidgets.QPushButton(TagListEditor) + self.tags_move_down_btn.setText("") + icon = QtGui.QIcon.fromTheme("go-down") + self.tags_move_down_btn.setIcon(icon) + self.tags_move_down_btn.setObjectName("tags_move_down_btn") + self.verticalLayout_2.addWidget(self.tags_move_down_btn) + spacerItem2 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.verticalLayout_2.addItem(spacerItem2) + self.horizontalLayout.addLayout(self.verticalLayout_2) + + self.retranslateUi(TagListEditor) + self.tags_remove_btn.clicked.connect(self.tag_list_view.remove_selected_rows) + self.tags_add_btn.clicked.connect(self.tag_list_view.add_empty_row) + self.tags_move_up_btn.clicked.connect(self.tag_list_view.move_selected_rows_up) + self.tags_move_down_btn.clicked.connect(self.tag_list_view.move_selected_rows_down) + QtCore.QMetaObject.connectSlotsByName(TagListEditor) + + def retranslateUi(self, TagListEditor): + _translate = QtCore.QCoreApplication.translate + TagListEditor.setWindowTitle(_("Form")) + self.tags_remove_btn.setToolTip(_("Remove selected tags")) + self.tags_remove_btn.setAccessibleName(_("Remove selected tags")) + self.tags_remove_btn.setText(_("Remove tags")) + self.tags_add_btn.setText(_("Add new tag")) + self.tags_move_up_btn.setToolTip(_("Move tag up")) + self.tags_move_up_btn.setAccessibleName(_("Move tag up")) + self.tags_move_down_btn.setToolTip(_("Move tag down")) + self.tags_move_down_btn.setAccessibleName(_("Move tag down")) +from picard.ui.widgets.editablelistview import EditableListView diff --git a/picard/ui/taglistview.py b/picard/ui/widgets/editablelistview.py similarity index 78% rename from picard/ui/taglistview.py rename to picard/ui/widgets/editablelistview.py index 214cc0c50..342e04f62 100644 --- a/picard/ui/taglistview.py +++ b/picard/ui/widgets/editablelistview.py @@ -22,18 +22,10 @@ from PyQt5 import ( QtWidgets, ) -from picard.util.tags import ( - TAG_NAMES, - display_tag_name, -) - -class EditableTagListView(QtWidgets.QListView): +class EditableListView(QtWidgets.QListView): def __init__(self, parent=None): super().__init__(parent) - model = TagListModel() - self.setModel(model) - self.setItemDelegate(TagItemDelegate()) self.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) def keyPressEvent(self, event): @@ -60,26 +52,26 @@ class EditableTagListView(QtWidgets.QListView): else: super().closeEditor(editor, hint) - def add_tag(self, tag=""): + def add_item(self, value=""): model = self.model() row = model.rowCount() model.insertRow(row) index = model.createIndex(row, 0) - model.setData(index, tag) + model.setData(index, value) return index def clear(self): self.model().update([]) - def update(self, tags): - self.model().update(tags) + def update(self, values): + self.model().update(values) @property - def tags(self): - return self.model().tags + def items(self): + return self.model().items def add_empty_row(self): - index = self.add_tag() + index = self.add_item() self.setCurrentIndex(index) self.edit(index) @@ -128,20 +120,23 @@ class EditableTagListView(QtWidgets.QListView): selection.setCurrentIndex(new_index, QtCore.QItemSelectionModel.Current) -class TagListModel(QtCore.QAbstractListModel): - def __init__(self, tags=None, parent=None): +class EditableListModel(QtCore.QAbstractListModel): + def __init__(self, items=None, parent=None): super().__init__(parent) - self._tags = [(tag, display_tag_name(tag)) for tag in tags or []] + self._items = [(item, self.get_display_name(item)) for item in items or []] + + def get_display_name(self, item): # pylint: disable=no-self-use + return item def rowCount(self, parent=QtCore.QModelIndex()): - return len(self._tags) + return len(self._items) def data(self, index, role=QtCore.Qt.DisplayRole): if not index.isValid() or role not in (QtCore.Qt.DisplayRole, QtCore.Qt.EditRole): return None field = 1 if role == QtCore.Qt.DisplayRole else 0 try: - return self._tags[index.row()][field] + return self._items[index.row()][field] except IndexError: return None @@ -151,11 +146,11 @@ class TagListModel(QtCore.QAbstractListModel): i = index.row() try: if role == QtCore.Qt.EditRole: - display_name = display_tag_name(value) if value else value - self._tags[i] = (value, display_name) + display_name = self.get_display_name(value) if value else value + self._items[i] = (value, display_name) elif role == QtCore.Qt.DisplayRole: - current = self._tags[i] - self._tags[i] = (current[0], value) + current = self._items[i] + self._items[i] = (current[0], value) return True except IndexError: return False @@ -174,13 +169,13 @@ class TagListModel(QtCore.QAbstractListModel): def insertRows(self, row, count, parent=QtCore.QModelIndex()): super().beginInsertRows(parent, row, row + count - 1) for i in range(count): - self._tags.insert(row, ("", "")) + self._items.insert(row, ("", "")) super().endInsertRows() return True def removeRows(self, row, count, parent=QtCore.QModelIndex()): super().beginRemoveRows(parent, row, row + count - 1) - self._tags = self._tags[:row] + self._tags[row + count:] + self._items = self._items[:row] + self._items[row + count:] super().endRemoveRows() return True @@ -192,13 +187,13 @@ class TagListModel(QtCore.QAbstractListModel): def supportedDropActions(): return QtCore.Qt.MoveAction - def update(self, tags): + def update(self, items): self.beginResetModel() - self._tags = [(tag, display_tag_name(tag)) for tag in tags] + self._items = [(item, self.get_display_name(item)) for item in items] self.endResetModel() def move_row(self, row, new_row): - item = self._tags[row] + item = self._items[row] self.removeRow(row) self.insertRow(new_row) index = self.index(new_row, 0) @@ -206,19 +201,5 @@ class TagListModel(QtCore.QAbstractListModel): self.setData(index, item[1], QtCore.Qt.DisplayRole) @property - def tags(self): - return (t[0] for t in self._tags) - - -class TagItemDelegate(QtWidgets.QItemDelegate): - @staticmethod - def createEditor(parent, option, index): - editor = QtWidgets.QLineEdit(parent) - completer = QtWidgets.QCompleter(TAG_NAMES.keys(), parent) - - def complete(text): - parent.setFocus() - - completer.activated.connect(complete) - editor.setCompleter(completer) - return editor + def items(self): + return (t[0] for t in self._items) diff --git a/picard/ui/widgets/taglisteditor.py b/picard/ui/widgets/taglisteditor.py new file mode 100644 index 000000000..ac38870f3 --- /dev/null +++ b/picard/ui/widgets/taglisteditor.py @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- +# +# Picard, the next-generation MusicBrainz tagger +# Copyright (C) 2019 Philipp Wolfer +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +from PyQt5 import QtWidgets + +from picard.util.tags import ( + TAG_NAMES, + display_tag_name, +) + +from picard.ui.ui_widget_taglisteditor import Ui_TagListEditor +from picard.ui.widgets.editablelistview import EditableListModel + + +class TagListEditor(QtWidgets.QWidget): + def __init__(self, parent): + super().__init__(parent) + self.ui = Ui_TagListEditor() + self.ui.setupUi(self) + list_view = self.ui.tag_list_view + model = TagListModel() + list_view.setModel(model) + list_view.setItemDelegate(TagItemDelegate()) + + selection = list_view.selectionModel() + selection.selectionChanged.connect(self.on_selection_changed) + self.on_selection_changed([], []) + + def on_selection_changed(self, selected, deselected): + buttons_enabled = len(self.ui.tag_list_view.selectedIndexes()) > 0 + self.ui.tags_remove_btn.setEnabled(buttons_enabled) + self.ui.tags_move_up_btn.setEnabled(buttons_enabled) + self.ui.tags_move_down_btn.setEnabled(buttons_enabled) + + def clear(self): + self.ui.tag_list_view.update([]) + + def update(self, tags): + self.ui.tag_list_view.update(tags) + + @property + def tags(self): + return self.ui.tag_list_view.tags + + +class TagListModel(EditableListModel): + def get_display_name(self, item): + return display_tag_name(item) + + +class TagItemDelegate(QtWidgets.QItemDelegate): + @staticmethod + def createEditor(parent, option, index): + editor = QtWidgets.QLineEdit(parent) + completer = QtWidgets.QCompleter(TAG_NAMES.keys(), parent) + + def complete(text): + parent.setFocus() + + completer.activated.connect(complete) + editor.setCompleter(completer) + return editor diff --git a/ui/options_interface_top_tags.ui b/ui/options_interface_top_tags.ui index 324b08e15..2abfb5cc0 100644 --- a/ui/options_interface_top_tags.ui +++ b/ui/options_interface_top_tags.ui @@ -6,8 +6,8 @@ 0 0 - 893 - 698 + 418 + 310 @@ -34,207 +34,25 @@ - - - - - - - true - - - QAbstractItemView::InternalMove - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Remove selected tags - - - Remove selected tags - - - Remove tags - - - - - - - - - - Add new tag - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Move tag up - - - Move tag up - - - - - - - .. - - - - - - - Move tag down - - - Move tag down - - - - - - - .. - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - + + + + 0 + 0 + + + - EditableTagListView - QListView -
picard.ui.taglistview
- - add_empty_row() - remove_selected_rows() - move_selected_rows_up() - move_selected_rows_down() - + TagListEditor + QWidget +
picard.ui.widgets.taglisteditor
+ 1
- - - tags_add_btn - clicked() - top_tags_list - add_empty_row() - - - 804 - 673 - - - 428 - 343 - - - - - tags_remove_btn - clicked() - top_tags_list - remove_selected_rows() - - - 716 - 673 - - - 428 - 343 - - - - - tags_move_up_btn - clicked() - top_tags_list - move_selected_rows_up() - - - 867 - 344 - - - 428 - 343 - - - - - tags_move_down_btn - clicked() - top_tags_list - move_selected_rows_down() - - - 867 - 374 - - - 428 - 343 - - - - + diff --git a/ui/widget_taglisteditor.ui b/ui/widget_taglisteditor.ui new file mode 100644 index 000000000..41dc04bc4 --- /dev/null +++ b/ui/widget_taglisteditor.ui @@ -0,0 +1,220 @@ + + + TagListEditor + + + + 0 + 0 + 400 + 300 + + + + Form + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Remove selected tags + + + Remove selected tags + + + Remove tags + + + + + + + Add new tag + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Move tag up + + + Move tag up + + + + + + + + + + + + + Move tag down + + + Move tag down + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + EditableListView + QListView +
picard.ui.widgets.editablelistview
+ + add_empty_row() + remove_selected_rows() + move_selected_rows_up() + move_selected_rows_down() + +
+
+ + + + tags_remove_btn + clicked() + tag_list_view + remove_selected_rows() + + + 182 + 285 + + + 155 + 133 + + + + + tags_add_btn + clicked() + tag_list_view + add_empty_row() + + + 269 + 285 + + + 155 + 133 + + + + + tags_move_up_btn + clicked() + tag_list_view + move_selected_rows_up() + + + 384 + 134 + + + 181 + 133 + + + + + tags_move_down_btn + clicked() + tag_list_view + move_selected_rows_down() + + + 384 + 164 + + + 181 + 133 + + + + +