parent
8c33db170d
commit
ecd5c65695
@ -1,9 +1,9 @@
|
||||
# Standard library imports
|
||||
from typing import Callable, cast, List, Optional, TYPE_CHECKING
|
||||
import time
|
||||
|
||||
# PyQt imports
|
||||
from PyQt6.QtCore import (
|
||||
QAbstractItemModel,
|
||||
QEvent,
|
||||
QModelIndex,
|
||||
QObject,
|
||||
@ -57,40 +57,46 @@ 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
|
||||
"""
|
||||
|
||||
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
|
||||
|
||||
def createEditor(
|
||||
self,
|
||||
parent: Optional[QWidget],
|
||||
option: QStyleOptionViewItem,
|
||||
index: QModelIndex,
|
||||
) -> Optional[QWidget]:
|
||||
) -> Optional[QDoubleSpinBox | QPlainTextEdit]:
|
||||
"""
|
||||
Intercept createEditor call and make row just a little bit taller
|
||||
"""
|
||||
|
||||
self.editor: QDoubleSpinBox | QPlainTextEdit
|
||||
editor: QDoubleSpinBox | QPlainTextEdit
|
||||
|
||||
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:
|
||||
self.editor = QDoubleSpinBox(parent)
|
||||
self.editor.setDecimals(1)
|
||||
self.editor.setSingleStep(0.1)
|
||||
return self.editor
|
||||
editor = QDoubleSpinBox(parent)
|
||||
editor.setDecimals(1)
|
||||
editor.setSingleStep(0.1)
|
||||
return editor
|
||||
elif isinstance(index.data(), str):
|
||||
self.editor = QPlainTextEdit(parent)
|
||||
editor = QPlainTextEdit(parent)
|
||||
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)
|
||||
return self.editor
|
||||
return editor
|
||||
|
||||
return super().createEditor(parent, option, index)
|
||||
|
||||
def destroyEditor(self, editor: Optional[QWidget], index: QModelIndex) -> None:
|
||||
@ -101,31 +107,53 @@ class EscapeDelegate(QStyledItemDelegate):
|
||||
self.signals.enable_escape_signal.emit(True)
|
||||
return super().destroyEditor(editor, index)
|
||||
|
||||
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
|
||||
return super().eventFilter(editor, event)
|
||||
|
||||
if event.type() == QEvent.Type.KeyPress:
|
||||
if event.type() == QEvent.Type.Show:
|
||||
if self.click_position and isinstance(editor, QPlainTextEdit):
|
||||
# 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 super().eventFilter(editor, event)
|
||||
|
||||
elif event.type() == QEvent.Type.KeyPress:
|
||||
key_event = cast(QKeyEvent, event)
|
||||
if key_event.key() == Qt.Key.Key_Return:
|
||||
if key_event.modifiers() == (Qt.KeyboardModifier.ControlModifier):
|
||||
self.commitData.emit(editor)
|
||||
self.closeEditor.emit(editor)
|
||||
return True
|
||||
|
||||
elif key_event.key() == Qt.Key.Key_Escape:
|
||||
# Close editor if no changes have been made
|
||||
data_modified = False
|
||||
if isinstance(self.editor, QPlainTextEdit):
|
||||
if isinstance(editor, QPlainTextEdit):
|
||||
data_modified = self.original_model_data != editor.toPlainText()
|
||||
elif isinstance(editor, QDoubleSpinBox):
|
||||
data_modified = (
|
||||
self.original_model_data == self.editor.toPlainText()
|
||||
self.original_model_data != int(editor.value()) * 1000
|
||||
)
|
||||
elif isinstance(self.editor, QDoubleSpinBox):
|
||||
data_modified = (
|
||||
self.original_model_data == int(self.editor.value()) * 1000
|
||||
)
|
||||
if data_modified:
|
||||
if not data_modified:
|
||||
self.closeEditor.emit(editor)
|
||||
return True
|
||||
|
||||
@ -135,6 +163,7 @@ class EscapeDelegate(QStyledItemDelegate):
|
||||
if discard_edits == QMessageBox.StandardButton.Yes:
|
||||
self.closeEditor.emit(editor)
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def setEditorData(self, editor, index):
|
||||
@ -153,9 +182,9 @@ class EscapeDelegate(QStyledItemDelegate):
|
||||
proxy_model = index.model()
|
||||
edit_index = proxy_model.mapToSource(index)
|
||||
|
||||
if isinstance(self.editor, QPlainTextEdit):
|
||||
if isinstance(editor, QPlainTextEdit):
|
||||
value = editor.toPlainText().strip()
|
||||
elif isinstance(self.editor, QDoubleSpinBox):
|
||||
elif isinstance(editor, QDoubleSpinBox):
|
||||
value = editor.value()
|
||||
self.source_model.setData(edit_index, value, Qt.ItemDataRole.EditRole)
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user