Row resizing WIP
Resizing works, code is clean, rows not too tall, IntegerDelegate to be provided still.
This commit is contained in:
parent
07d8ce9c41
commit
0b30a02dde
@ -394,7 +394,7 @@ class PlaylistModel(QAbstractTableModel):
|
|||||||
if rat.intro:
|
if rat.intro:
|
||||||
return QVariant(f"{rat.intro / 1000:{Config.INTRO_SECONDS_FORMAT}}")
|
return QVariant(f"{rat.intro / 1000:{Config.INTRO_SECONDS_FORMAT}}")
|
||||||
else:
|
else:
|
||||||
return QVariant()
|
return QVariant("")
|
||||||
|
|
||||||
dispatch_table = {
|
dispatch_table = {
|
||||||
Col.ARTIST.value: QVariant(rat.artist),
|
Col.ARTIST.value: QVariant(rat.artist),
|
||||||
|
|||||||
346
app/playlists.py
346
app/playlists.py
@ -1,5 +1,5 @@
|
|||||||
# Standard library imports
|
# Standard library imports
|
||||||
from typing import Callable, cast, List, Optional, TYPE_CHECKING
|
from typing import Any, Callable, cast, List, Optional, TYPE_CHECKING
|
||||||
|
|
||||||
# PyQt imports
|
# PyQt imports
|
||||||
from PyQt6.QtCore import (
|
from PyQt6.QtCore import (
|
||||||
@ -12,17 +12,15 @@ from PyQt6.QtCore import (
|
|||||||
Qt,
|
Qt,
|
||||||
QTimer,
|
QTimer,
|
||||||
)
|
)
|
||||||
from PyQt6.QtGui import QAction, QKeyEvent, QTextDocument
|
from PyQt6.QtGui import QAction, QDropEvent, QKeyEvent, QTextDocument
|
||||||
from PyQt6.QtWidgets import (
|
from PyQt6.QtWidgets import (
|
||||||
QAbstractItemDelegate,
|
QAbstractItemDelegate,
|
||||||
QAbstractItemView,
|
QAbstractItemView,
|
||||||
QApplication,
|
QApplication,
|
||||||
QDoubleSpinBox,
|
QDoubleSpinBox,
|
||||||
QFrame,
|
QFrame,
|
||||||
QHeaderView,
|
|
||||||
QMenu,
|
QMenu,
|
||||||
QMessageBox,
|
QMessageBox,
|
||||||
QPlainTextEdit,
|
|
||||||
QProxyStyle,
|
QProxyStyle,
|
||||||
QStyle,
|
QStyle,
|
||||||
QStyledItemDelegate,
|
QStyledItemDelegate,
|
||||||
@ -55,12 +53,12 @@ if TYPE_CHECKING:
|
|||||||
from musicmuster import Window
|
from musicmuster import Window
|
||||||
|
|
||||||
|
|
||||||
class EscapeDelegate(QStyledItemDelegate):
|
class TextDelegate(QStyledItemDelegate):
|
||||||
"""
|
"""
|
||||||
- increases the height of a row when editing to make editing easier
|
|
||||||
- closes the edit on control-return
|
- closes the edit on control-return
|
||||||
- checks with user before abandoning edit on Escape
|
- checks with user before abandoning edit on Escape
|
||||||
- positions cursor where double-click occurs
|
- positions cursor where double-click occurs
|
||||||
|
- expands edit box and parent table row as text is added
|
||||||
|
|
||||||
Parts inspired by https://stackoverflow.com/questions/69113867/
|
Parts inspired by https://stackoverflow.com/questions/69113867/
|
||||||
make-row-of-qtableview-expand-as-editor-grows-in-height
|
make-row-of-qtableview-expand-as-editor-grows-in-height
|
||||||
@ -86,85 +84,38 @@ class EscapeDelegate(QStyledItemDelegate):
|
|||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self.source_model = source_model
|
self.source_model = source_model
|
||||||
self.signals = MusicMusterSignals()
|
self.signals = MusicMusterSignals()
|
||||||
self.click_position = None # Store the mouse click position
|
self.click_position = None
|
||||||
self.current_editor = None
|
self.current_editor: Optional[Any] = None
|
||||||
|
|
||||||
def createEditor(
|
def createEditor(
|
||||||
self,
|
self,
|
||||||
parent: Optional[QWidget],
|
parent: Optional[QWidget],
|
||||||
option: QStyleOptionViewItem,
|
option: QStyleOptionViewItem,
|
||||||
index: QModelIndex,
|
index: QModelIndex,
|
||||||
) -> Optional[QDoubleSpinBox | QTextEdit]:
|
) -> Optional[QTextEdit]:
|
||||||
"""
|
"""
|
||||||
Intercept createEditor call and make row just a little bit taller
|
Intercept createEditor call and make row just a little bit taller
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# editor: QDoubleSpinBox | QTextEdit
|
|
||||||
|
|
||||||
class Editor(QTextEdit):
|
class Editor(QTextEdit):
|
||||||
def resizeEvent(self, event):
|
def resizeEvent(self, event):
|
||||||
super().resizeEvent(event)
|
super().resizeEvent(event)
|
||||||
parent.parent().resizeRowToContents(index.row())
|
parent.parent().resizeRowToContents(index.row())
|
||||||
|
|
||||||
def keyPressEvent(self, event):
|
|
||||||
if event.modifiers() == Qt.KeyboardModifier.ControlModifier:
|
|
||||||
if event.key() == Qt.Key.Key_Return:
|
|
||||||
self.commitData.emit(editor)
|
|
||||||
# self.closeEditor.emit(editor)
|
|
||||||
return
|
|
||||||
# elif event.key() == Qt.Key.Key_Escape:
|
|
||||||
# # Close editor if no changes have been made
|
|
||||||
# data_modified = False
|
|
||||||
# if isinstance(editor, QPlainTextEdit):
|
|
||||||
# data_modified = self.original_model_data != editor.toPlainText()
|
|
||||||
# elif isinstance(editor, QDoubleSpinBox):
|
|
||||||
# data_modified = (
|
|
||||||
# self.original_model_data != int(editor.value()) * 1000
|
|
||||||
# )
|
|
||||||
# if not data_modified:
|
|
||||||
# self.closeEditor.emit(editor)
|
|
||||||
# return True
|
|
||||||
|
|
||||||
# discard_edits = QMessageBox.question(
|
|
||||||
# cast(QWidget, self.parent()), "Abandon edit", "Discard changes?"
|
|
||||||
# )
|
|
||||||
# if discard_edits == QMessageBox.StandardButton.Yes:
|
|
||||||
# self.closeEditor.emit(editor)
|
|
||||||
# return True
|
|
||||||
|
|
||||||
super().keyPressEvent(event)
|
|
||||||
|
|
||||||
self.signals = MusicMusterSignals()
|
self.signals = MusicMusterSignals()
|
||||||
self.signals.enable_escape_signal.emit(False)
|
self.signals.enable_escape_signal.emit(False)
|
||||||
|
|
||||||
# if isinstance(self.parent(), PlaylistTab):
|
|
||||||
# p = cast(PlaylistTab, self.parent())
|
|
||||||
|
|
||||||
# if index.column() == Col.INTRO.value:
|
|
||||||
# editor = QDoubleSpinBox(parent)
|
|
||||||
# editor.setDecimals(1)
|
|
||||||
# editor.setSingleStep(0.1)
|
|
||||||
# return editor
|
|
||||||
# elif isinstance(index.data(), str):
|
|
||||||
if self.current_editor:
|
if self.current_editor:
|
||||||
editor = self.current_editor
|
editor = self.current_editor
|
||||||
else:
|
else:
|
||||||
editor = Editor(parent)
|
editor = Editor(parent)
|
||||||
editor.setVerticalScrollBarPolicy(
|
editor.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
|
||||||
Qt.ScrollBarPolicy.ScrollBarAlwaysOff
|
|
||||||
)
|
|
||||||
editor.setFrameShape(QFrame.Shape.NoFrame)
|
editor.setFrameShape(QFrame.Shape.NoFrame)
|
||||||
self.current_editor = editor
|
self.current_editor = editor
|
||||||
# # editor.setGeometry(option.rect) # Match the cell geometry
|
|
||||||
# row = index.row()
|
|
||||||
# row_height = p.rowHeight(row)
|
|
||||||
# p.setRowHeight(row, row_height + Config.MINIMUM_ROW_HEIGHT)
|
|
||||||
|
|
||||||
EscapeDelegate.EditorDocument(editor)
|
TextDelegate.EditorDocument(editor)
|
||||||
return editor
|
return editor
|
||||||
|
|
||||||
# return super().createEditor(parent, option, index)
|
|
||||||
|
|
||||||
def destroyEditor(self, editor: Optional[QWidget], index: QModelIndex) -> None:
|
def destroyEditor(self, editor: Optional[QWidget], index: QModelIndex) -> None:
|
||||||
"""
|
"""
|
||||||
Intercept editor destroyment
|
Intercept editor destroyment
|
||||||
@ -172,23 +123,31 @@ class EscapeDelegate(QStyledItemDelegate):
|
|||||||
|
|
||||||
super().destroyEditor(editor, index)
|
super().destroyEditor(editor, index)
|
||||||
self.current_editor = None
|
self.current_editor = None
|
||||||
self.parent().resizeRowToContents(index.row())
|
# Funky mypy dancing:
|
||||||
|
parent = self.parent()
|
||||||
|
if parent and hasattr(parent, "resizeRowToContents"):
|
||||||
|
parent.resizeRowToContents(index.row())
|
||||||
self.signals.enable_escape_signal.emit(True)
|
self.signals.enable_escape_signal.emit(True)
|
||||||
|
|
||||||
def editorEvent(
|
def editorEvent(
|
||||||
self, event: QEvent, model: QAbstractItemModel, option, index: QModelIndex
|
self,
|
||||||
|
event: Optional[QEvent],
|
||||||
|
model: Optional[QAbstractItemModel],
|
||||||
|
option: QStyleOptionViewItem,
|
||||||
|
index: QModelIndex,
|
||||||
) -> bool:
|
) -> bool:
|
||||||
"""Capture mouse click position."""
|
"""Capture mouse click position."""
|
||||||
|
|
||||||
if event.type() == QEvent.Type.MouseButtonPress:
|
if event and event.type() == QEvent.Type.MouseButtonPress:
|
||||||
self.click_position = event.pos()
|
if hasattr(event, "pos"):
|
||||||
|
self.click_position = event.pos()
|
||||||
return super().editorEvent(event, model, option, index)
|
return super().editorEvent(event, model, option, index)
|
||||||
|
|
||||||
def eventFilter(self, editor: Optional[QObject], event: Optional[QEvent]) -> bool:
|
def eventFilter(self, editor: Optional[QObject], event: Optional[QEvent]) -> bool:
|
||||||
"""By default, QPlainTextEdit doesn't handle enter or return"""
|
"""By default, QPlainTextEdit doesn't handle enter or return"""
|
||||||
|
|
||||||
if editor is None or event is None:
|
if editor is None or event is None:
|
||||||
return super().eventFilter(editor, event)
|
return False
|
||||||
|
|
||||||
if event.type() == QEvent.Type.Show:
|
if event.type() == QEvent.Type.Show:
|
||||||
if self.click_position and isinstance(editor, QTextEdit):
|
if self.click_position and isinstance(editor, QTextEdit):
|
||||||
@ -202,7 +161,33 @@ class EscapeDelegate(QStyledItemDelegate):
|
|||||||
# Reset click position
|
# Reset click position
|
||||||
self.click_position = None
|
self.click_position = None
|
||||||
|
|
||||||
return super().eventFilter(editor, event)
|
return False
|
||||||
|
|
||||||
|
elif event.type() == QEvent.Type.KeyPress:
|
||||||
|
key_event = cast(QKeyEvent, event)
|
||||||
|
key = key_event.key()
|
||||||
|
if key == Qt.Key.Key_Return:
|
||||||
|
if key_event.modifiers() == (Qt.KeyboardModifier.ControlModifier):
|
||||||
|
self.commitData.emit(editor)
|
||||||
|
self.closeEditor.emit(editor)
|
||||||
|
return True
|
||||||
|
|
||||||
|
elif key == Qt.Key.Key_Escape:
|
||||||
|
# Close editor if no changes have been made
|
||||||
|
if hasattr(editor, "toPlainText"):
|
||||||
|
data_modified = (
|
||||||
|
self.original_model_data.value() != editor.toPlainText()
|
||||||
|
)
|
||||||
|
if not data_modified:
|
||||||
|
self.closeEditor.emit(editor)
|
||||||
|
return True
|
||||||
|
|
||||||
|
discard_edits = QMessageBox.question(
|
||||||
|
cast(QWidget, self.parent()), "Abandon edit", "Discard changes?"
|
||||||
|
)
|
||||||
|
if discard_edits == QMessageBox.StandardButton.Yes:
|
||||||
|
self.closeEditor.emit(editor)
|
||||||
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -244,6 +229,229 @@ class EscapeDelegate(QStyledItemDelegate):
|
|||||||
editor.setGeometry(option.rect)
|
editor.setGeometry(option.rect)
|
||||||
|
|
||||||
|
|
||||||
|
# Will be int delegate
|
||||||
|
# class EscapeDelegate(QStyledItemDelegate):
|
||||||
|
# """
|
||||||
|
# - increases the height of a row when editing to make editing easier
|
||||||
|
# - closes the edit on control-return
|
||||||
|
# - checks with user before abandoning edit on Escape
|
||||||
|
# - positions cursor where double-click occurs
|
||||||
|
|
||||||
|
# Parts inspired by https://stackoverflow.com/questions/69113867/
|
||||||
|
# make-row-of-qtableview-expand-as-editor-grows-in-height
|
||||||
|
# """
|
||||||
|
|
||||||
|
# class EditorDocument(QTextDocument):
|
||||||
|
# def __init__(self, parent):
|
||||||
|
# super().__init__(parent)
|
||||||
|
# self.setDocumentMargin(0)
|
||||||
|
# self.contentsChange.connect(self.contents_change)
|
||||||
|
# self.height = None
|
||||||
|
# parent.setDocument(self)
|
||||||
|
|
||||||
|
# def contents_change(self, position, chars_removed, chars_added):
|
||||||
|
# def resize_func():
|
||||||
|
# if self.size().height() != self.height:
|
||||||
|
# doc_size = self.size()
|
||||||
|
# self.parent().resize(int(doc_size.width()), int(doc_size.height()))
|
||||||
|
|
||||||
|
# QTimer.singleShot(0, resize_func)
|
||||||
|
|
||||||
|
# def __init__(self, parent: QWidget, source_model: PlaylistModel) -> None:
|
||||||
|
# super().__init__(parent)
|
||||||
|
# self.source_model = source_model
|
||||||
|
# self.signals = MusicMusterSignals()
|
||||||
|
# self.click_position = None # Store the mouse click position
|
||||||
|
# self.current_editor = None
|
||||||
|
|
||||||
|
# def createEditor(
|
||||||
|
# self,
|
||||||
|
# parent: Optional[QWidget],
|
||||||
|
# option: QStyleOptionViewItem,
|
||||||
|
# index: QModelIndex,
|
||||||
|
# ) -> Optional[QDoubleSpinBox | QTextEdit]:
|
||||||
|
# """
|
||||||
|
# Intercept createEditor call and make row just a little bit taller
|
||||||
|
# """
|
||||||
|
|
||||||
|
# # editor: QDoubleSpinBox | QTextEdit
|
||||||
|
|
||||||
|
# class Editor(QTextEdit):
|
||||||
|
# def resizeEvent(self, event):
|
||||||
|
# super().resizeEvent(event)
|
||||||
|
# parent.parent().resizeRowToContents(index.row())
|
||||||
|
|
||||||
|
# def keyPressEvent(self, event):
|
||||||
|
# if event.modifiers() == Qt.KeyboardModifier.ControlModifier:
|
||||||
|
# if event.key() == Qt.Key.Key_Return:
|
||||||
|
# print("control-return")
|
||||||
|
# import pdb; pdb.set_trace()
|
||||||
|
# self.commit.emit(self)
|
||||||
|
# # self.closeEditor.emit(editor)
|
||||||
|
# return
|
||||||
|
# elif event.key() == Qt.Key.Key_Escape:
|
||||||
|
# # Close editor if no changes have been made
|
||||||
|
# print("escape")
|
||||||
|
# data_modified = False
|
||||||
|
# if isinstance(editor, QPlainTextEdit):
|
||||||
|
# data_modified = self.original_model_data != editor.toPlainText()
|
||||||
|
# elif isinstance(editor, QDoubleSpinBox):
|
||||||
|
# data_modified = (
|
||||||
|
# self.original_model_data != int(editor.value()) * 1000
|
||||||
|
# )
|
||||||
|
# if not data_modified:
|
||||||
|
# self.closeEditor.emit(editor)
|
||||||
|
# return True
|
||||||
|
|
||||||
|
# discard_edits = QMessageBox.question(
|
||||||
|
# cast(QWidget, self.parent()), "Abandon edit", "Discard changes?"
|
||||||
|
# )
|
||||||
|
# if discard_edits == QMessageBox.StandardButton.Yes:
|
||||||
|
# self.closeEditor.emit(editor)
|
||||||
|
# return True
|
||||||
|
|
||||||
|
# super().keyPressEvent(event)
|
||||||
|
|
||||||
|
# self.signals = MusicMusterSignals()
|
||||||
|
# self.signals.enable_escape_signal.emit(False)
|
||||||
|
|
||||||
|
# # if isinstance(self.parent(), PlaylistTab):
|
||||||
|
# # p = cast(PlaylistTab, self.parent())
|
||||||
|
|
||||||
|
# # if index.column() == Col.INTRO.value:
|
||||||
|
# # editor = QDoubleSpinBox(parent)
|
||||||
|
# # editor.setDecimals(1)
|
||||||
|
# # editor.setSingleStep(0.1)
|
||||||
|
# # return editor
|
||||||
|
# # elif isinstance(index.data(), str):
|
||||||
|
# if self.current_editor:
|
||||||
|
# editor = self.current_editor
|
||||||
|
# else:
|
||||||
|
# editor = Editor(parent)
|
||||||
|
# editor.setVerticalScrollBarPolicy(
|
||||||
|
# Qt.ScrollBarPolicy.ScrollBarAlwaysOff
|
||||||
|
# )
|
||||||
|
# editor.setFrameShape(QFrame.Shape.NoFrame)
|
||||||
|
# self.current_editor = editor
|
||||||
|
# # # editor.setGeometry(option.rect) # Match the cell geometry
|
||||||
|
# # row = index.row()
|
||||||
|
# # row_height = p.rowHeight(row)
|
||||||
|
# # p.setRowHeight(row, row_height + Config.MINIMUM_ROW_HEIGHT)
|
||||||
|
|
||||||
|
# EscapeDelegate.EditorDocument(editor)
|
||||||
|
# return editor
|
||||||
|
|
||||||
|
# # return super().createEditor(parent, option, index)
|
||||||
|
|
||||||
|
# def destroyEditor(self, editor: Optional[QWidget], index: QModelIndex) -> None:
|
||||||
|
# """
|
||||||
|
# Intercept editor destroyment
|
||||||
|
# """
|
||||||
|
|
||||||
|
# super().destroyEditor(editor, index)
|
||||||
|
# self.current_editor = None
|
||||||
|
# self.parent().resizeRowToContents(index.row())
|
||||||
|
# self.signals.enable_escape_signal.emit(True)
|
||||||
|
|
||||||
|
# def editorEvent(
|
||||||
|
# self, event: QEvent, model: QAbstractItemModel, option, index: QModelIndex
|
||||||
|
# ) -> bool:
|
||||||
|
# """Capture mouse click position."""
|
||||||
|
|
||||||
|
# if event.type() == QEvent.Type.MouseButtonPress:
|
||||||
|
# self.click_position = event.pos()
|
||||||
|
# return super().editorEvent(event, model, option, index)
|
||||||
|
|
||||||
|
# def eventFilter(self, editor: Optional[QObject], event: Optional[QEvent]) -> bool:
|
||||||
|
# """By default, QPlainTextEdit doesn't handle enter or return"""
|
||||||
|
|
||||||
|
# if editor is None or event is None:
|
||||||
|
# return False
|
||||||
|
|
||||||
|
# if event.type() == QEvent.Type.Show:
|
||||||
|
# if self.click_position and isinstance(editor, QTextEdit):
|
||||||
|
# # Map click position to editor's local space
|
||||||
|
# local_click_position = editor.mapFromParent(self.click_position)
|
||||||
|
|
||||||
|
# # Move cursor to the calculated position
|
||||||
|
# cursor = editor.cursorForPosition(local_click_position)
|
||||||
|
# editor.setTextCursor(cursor)
|
||||||
|
|
||||||
|
# # Reset click position
|
||||||
|
# self.click_position = None
|
||||||
|
|
||||||
|
# return False
|
||||||
|
|
||||||
|
# elif event.type() == QEvent.Type.KeyPress:
|
||||||
|
# key_event = cast(QKeyEvent, event)
|
||||||
|
# key = key_event.key()
|
||||||
|
# if key == Qt.Key.Key_Return:
|
||||||
|
# if key_event.modifiers() == (Qt.KeyboardModifier.ControlModifier):
|
||||||
|
# self.commitData.emit(editor)
|
||||||
|
# self.closeEditor.emit(editor)
|
||||||
|
# return True
|
||||||
|
|
||||||
|
# elif key == Qt.Key.Key_Escape:
|
||||||
|
# # Close editor if no changes have been made
|
||||||
|
# if hasattr(editor, "toPlainText"):
|
||||||
|
# data_modified = self.original_model_data.value() != editor.toPlainText()
|
||||||
|
# # if isinstance(editor, QPlainTextEdit):
|
||||||
|
# # data_modified = self.original_model_data.value() != editor.toPlainText()
|
||||||
|
# # elif isinstance(editor, QDoubleSpinBox):
|
||||||
|
# # data_modified = (
|
||||||
|
# # self.original_model_data != int(editor.value()) * 1000
|
||||||
|
# # )
|
||||||
|
# if not data_modified:
|
||||||
|
# self.closeEditor.emit(editor)
|
||||||
|
# return True
|
||||||
|
|
||||||
|
# discard_edits = QMessageBox.question(
|
||||||
|
# cast(QWidget, self.parent()), "Abandon edit", "Discard changes?"
|
||||||
|
# )
|
||||||
|
# if discard_edits == QMessageBox.StandardButton.Yes:
|
||||||
|
# self.closeEditor.emit(editor)
|
||||||
|
# return True
|
||||||
|
|
||||||
|
# return False
|
||||||
|
|
||||||
|
# def sizeHint(self, option, index):
|
||||||
|
# self.initStyleOption(option, index)
|
||||||
|
# if self.current_editor:
|
||||||
|
# doc = self.current_editor.document()
|
||||||
|
# else:
|
||||||
|
# doc = QTextDocument()
|
||||||
|
# doc.setTextWidth(option.rect.width())
|
||||||
|
# doc.setDefaultFont(option.font)
|
||||||
|
# doc.setDocumentMargin(0)
|
||||||
|
# doc.setHtml(option.text)
|
||||||
|
# return QSize(int(doc.idealWidth()), int(doc.size().height()))
|
||||||
|
|
||||||
|
# def setEditorData(self, editor, index):
|
||||||
|
# proxy_model = index.model()
|
||||||
|
# edit_index = proxy_model.mapToSource(index)
|
||||||
|
|
||||||
|
# self.original_model_data = self.source_model.data(
|
||||||
|
# edit_index, Qt.ItemDataRole.EditRole
|
||||||
|
# )
|
||||||
|
# if index.column() == Col.INTRO.value:
|
||||||
|
# editor.setValue(self.original_model_data.value() / 1000)
|
||||||
|
# else:
|
||||||
|
# editor.setPlainText(self.original_model_data.value())
|
||||||
|
|
||||||
|
# def setModelData(self, editor, model, index):
|
||||||
|
# proxy_model = index.model()
|
||||||
|
# edit_index = proxy_model.mapToSource(index)
|
||||||
|
|
||||||
|
# if isinstance(editor, QTextEdit):
|
||||||
|
# value = editor.toPlainText().strip()
|
||||||
|
# elif isinstance(editor, QDoubleSpinBox):
|
||||||
|
# value = editor.value()
|
||||||
|
# self.source_model.setData(edit_index, value, Qt.ItemDataRole.EditRole)
|
||||||
|
|
||||||
|
# def updateEditorGeometry(self, editor, option, index):
|
||||||
|
# editor.setGeometry(option.rect)
|
||||||
|
|
||||||
|
|
||||||
class PlaylistStyle(QProxyStyle):
|
class PlaylistStyle(QProxyStyle):
|
||||||
def drawPrimitive(self, element, option, painter, widget=None):
|
def drawPrimitive(self, element, option, painter, widget=None):
|
||||||
"""
|
"""
|
||||||
@ -282,7 +490,7 @@ class PlaylistTab(QTableView):
|
|||||||
# Set up widget
|
# Set up widget
|
||||||
self.source_model = PlaylistModel(playlist_id)
|
self.source_model = PlaylistModel(playlist_id)
|
||||||
self.proxy_model = PlaylistProxyModel(self.source_model)
|
self.proxy_model = PlaylistProxyModel(self.source_model)
|
||||||
self.setItemDelegate(EscapeDelegate(self, self.source_model))
|
self.setItemDelegate(TextDelegate(self, self.source_model))
|
||||||
self.setAlternatingRowColors(True)
|
self.setAlternatingRowColors(True)
|
||||||
self.setVerticalScrollMode(QAbstractItemView.ScrollMode.ScrollPerPixel)
|
self.setVerticalScrollMode(QAbstractItemView.ScrollMode.ScrollPerPixel)
|
||||||
self.setDragDropMode(QAbstractItemView.DragDropMode.InternalMove)
|
self.setDragDropMode(QAbstractItemView.DragDropMode.InternalMove)
|
||||||
@ -360,10 +568,12 @@ class PlaylistTab(QTableView):
|
|||||||
# Deselect edited line
|
# Deselect edited line
|
||||||
self.clear_selection()
|
self.clear_selection()
|
||||||
|
|
||||||
def dropEvent(self, event):
|
def dropEvent(self, event: Optional[QDropEvent]) -> None:
|
||||||
|
if not event:
|
||||||
|
return
|
||||||
if event.source() is not self or (
|
if event.source() is not self or (
|
||||||
event.dropAction() != Qt.DropAction.MoveAction
|
event.dropAction() != Qt.DropAction.MoveAction
|
||||||
and self.dragDropMode() != QAbstractItemView.InternalMove
|
and self.dragDropMode() != QAbstractItemView.DragDropMode.InternalMove
|
||||||
):
|
):
|
||||||
super().dropEvent(event)
|
super().dropEvent(event)
|
||||||
|
|
||||||
@ -776,6 +986,8 @@ class PlaylistTab(QTableView):
|
|||||||
Import current Audacity track to passed row
|
Import current Audacity track to passed row
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if not self.ac:
|
||||||
|
return
|
||||||
try:
|
try:
|
||||||
self.ac.export()
|
self.ac.export()
|
||||||
self._rescan(row_number)
|
self._rescan(row_number)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user