Compare commits
6 Commits
60c085ad12
...
45243759b8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
45243759b8 | ||
|
|
d73bdb264d | ||
|
|
90f8e20843 | ||
|
|
184318078f | ||
|
|
c6befd219c | ||
|
|
2f0ad5cd52 |
@ -1022,18 +1022,21 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
if self.move_source_rows is None or self.move_source_model is None:
|
if self.move_source_rows is None or self.move_source_model is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
to_playlist_id = self.active_tab().playlist_id
|
to_playlist_model = self.active_tab().data_model
|
||||||
selected_rows = self.active_tab().get_selected_rows()
|
selected_rows = self.active_tab().get_selected_rows()
|
||||||
if selected_rows:
|
if selected_rows:
|
||||||
destination_row = selected_rows[0]
|
destination_row = selected_rows[0]
|
||||||
else:
|
else:
|
||||||
destination_row = self.active_model().rowCount()
|
destination_row = self.active_model().rowCount()
|
||||||
|
|
||||||
if to_playlist_id == self.move_source_model.data_model.playlist_id:
|
if (
|
||||||
|
to_playlist_model.playlist_id
|
||||||
|
== self.move_source_model.data_model.playlist_id
|
||||||
|
):
|
||||||
self.move_source_model.move_rows(self.move_source_rows, destination_row)
|
self.move_source_model.move_rows(self.move_source_rows, destination_row)
|
||||||
else:
|
else:
|
||||||
self.move_source_model.move_rows_between_playlists(
|
self.move_source_model.move_rows_between_playlists(
|
||||||
self.move_source_rows, destination_row, to_playlist_id
|
self.move_source_rows, destination_row, to_playlist_model
|
||||||
)
|
)
|
||||||
self.move_source_rows = self.move_source_model = None
|
self.move_source_rows = self.move_source_model = None
|
||||||
|
|
||||||
@ -1081,6 +1084,8 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
|
|
||||||
# Show closing volume graph
|
# Show closing volume graph
|
||||||
if track_sequence.now.fade_graph:
|
if track_sequence.now.fade_graph:
|
||||||
|
# TODO: remove if this is not a problem
|
||||||
|
stackprinter.format(show_vals="all")
|
||||||
track_sequence.now.fade_graph.plot()
|
track_sequence.now.fade_graph.plot()
|
||||||
|
|
||||||
# Play (new) current track
|
# Play (new) current track
|
||||||
@ -1325,7 +1330,10 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
self.tabPlaylist.setCurrentIndex(idx)
|
self.tabPlaylist.setCurrentIndex(idx)
|
||||||
break
|
break
|
||||||
|
|
||||||
self.tabPlaylist.currentWidget().scroll_to_top(plt.plr_rownum)
|
display_row = self.active_model().mapFromSource(
|
||||||
|
self.active_model().data_model.index(plt.plr_rownum, 0)
|
||||||
|
).row()
|
||||||
|
self.tabPlaylist.currentWidget().scroll_to_top(display_row)
|
||||||
|
|
||||||
def solicit_playlist_name(
|
def solicit_playlist_name(
|
||||||
self, session: scoped_session, default: str = ""
|
self, session: scoped_session, default: str = ""
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
# Allow forward reference to PlaylistModel
|
||||||
|
from __future__ import annotations
|
||||||
import obsws_python as obs # type: ignore
|
import obsws_python as obs # type: ignore
|
||||||
import re
|
import re
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
@ -173,10 +175,6 @@ class PlaylistModel(QAbstractTableModel):
|
|||||||
# Add any further note (header will already have a note)
|
# Add any further note (header will already have a note)
|
||||||
if note:
|
if note:
|
||||||
plr.note += "\n" + note
|
plr.note += "\n" + note
|
||||||
# Reset header row spanning
|
|
||||||
self.signals.span_cells_signal.emit(
|
|
||||||
self.playlist_id, row_number, HEADER_NOTES_COLUMN, 1, 1
|
|
||||||
)
|
|
||||||
# Update local copy
|
# Update local copy
|
||||||
self.refresh_row(session, row_number)
|
self.refresh_row(session, row_number)
|
||||||
# Repaint row
|
# Repaint row
|
||||||
@ -380,15 +378,14 @@ class PlaylistModel(QAbstractTableModel):
|
|||||||
Return text for display
|
Return text for display
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# Set / reset column span
|
||||||
|
column_span = 1
|
||||||
|
if self.is_header_row(row) and column == HEADER_NOTES_COLUMN:
|
||||||
|
column_span = self.columnCount() - 1
|
||||||
|
self.signals.span_cells_signal.emit(self.playlist_id, row, HEADER_NOTES_COLUMN, 1,
|
||||||
|
column_span)
|
||||||
if self.is_header_row(row):
|
if self.is_header_row(row):
|
||||||
if column == HEADER_NOTES_COLUMN:
|
if column == HEADER_NOTES_COLUMN:
|
||||||
self.signals.span_cells_signal.emit(
|
|
||||||
self.playlist_id,
|
|
||||||
row,
|
|
||||||
HEADER_NOTES_COLUMN,
|
|
||||||
1,
|
|
||||||
self.columnCount() - 1,
|
|
||||||
)
|
|
||||||
header_text = self.header_text(prd)
|
header_text = self.header_text(prd)
|
||||||
if not header_text:
|
if not header_text:
|
||||||
return QVariant(Config.TEXT_NO_TRACK_NO_NOTE)
|
return QVariant(Config.TEXT_NO_TRACK_NO_NOTE)
|
||||||
@ -779,6 +776,21 @@ class PlaylistModel(QAbstractTableModel):
|
|||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def mark_unplayed(self, row_numbers: List[int]) -> None:
|
||||||
|
"""
|
||||||
|
Mark row as unplayed
|
||||||
|
"""
|
||||||
|
|
||||||
|
with Session() as session:
|
||||||
|
for row_number in row_numbers:
|
||||||
|
plr = session.get(PlaylistRows, self.playlist_rows[row_number].plrid)
|
||||||
|
if not plr:
|
||||||
|
return
|
||||||
|
plr.played = False
|
||||||
|
self.refresh_row(session, row_number)
|
||||||
|
|
||||||
|
self.invalidate_rows(row_numbers)
|
||||||
|
|
||||||
def move_rows(self, from_rows: List[int], to_row_number: int) -> None:
|
def move_rows(self, from_rows: List[int], to_row_number: int) -> None:
|
||||||
"""
|
"""
|
||||||
Move the playlist rows given to to_row and below.
|
Move the playlist rows given to to_row and below.
|
||||||
@ -813,13 +825,6 @@ class PlaylistModel(QAbstractTableModel):
|
|||||||
if old_row != new_row:
|
if old_row != new_row:
|
||||||
row_map[old_row] = new_row
|
row_map[old_row] = new_row
|
||||||
|
|
||||||
# Reset any header rows that we're moving
|
|
||||||
for moving_row in row_map:
|
|
||||||
if self.is_header_row(moving_row):
|
|
||||||
# Reset column span
|
|
||||||
self.signals.span_cells_signal.emit(
|
|
||||||
self.playlist_id, moving_row, HEADER_NOTES_COLUMN, 1, 1
|
|
||||||
)
|
|
||||||
# Check to see whether any rows in track_sequence have moved
|
# Check to see whether any rows in track_sequence have moved
|
||||||
if track_sequence.previous.plr_rownum in row_map:
|
if track_sequence.previous.plr_rownum in row_map:
|
||||||
track_sequence.previous.plr_rownum = row_map[
|
track_sequence.previous.plr_rownum = row_map[
|
||||||
@ -846,28 +851,15 @@ class PlaylistModel(QAbstractTableModel):
|
|||||||
self.reset_track_sequence_row_numbers()
|
self.reset_track_sequence_row_numbers()
|
||||||
self.invalidate_rows(list(row_map.keys()))
|
self.invalidate_rows(list(row_map.keys()))
|
||||||
|
|
||||||
def mark_unplayed(self, row_numbers: List[int]) -> None:
|
|
||||||
"""
|
|
||||||
Mark row as unplayed
|
|
||||||
"""
|
|
||||||
|
|
||||||
with Session() as session:
|
|
||||||
for row_number in row_numbers:
|
|
||||||
plr = session.get(PlaylistRows, self.playlist_rows[row_number].plrid)
|
|
||||||
if not plr:
|
|
||||||
return
|
|
||||||
plr.played = False
|
|
||||||
self.refresh_row(session, row_number)
|
|
||||||
|
|
||||||
self.invalidate_rows(row_numbers)
|
|
||||||
|
|
||||||
def move_rows_between_playlists(
|
def move_rows_between_playlists(
|
||||||
self, from_rows: List[int], to_row_number: int, to_playlist_id: int
|
self, from_rows: List[int], to_row_number: int, to_playlist_model: PlaylistModel
|
||||||
) -> None:
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Move the playlist rows given to to_row and below of to_playlist.
|
Move the playlist rows given to to_row and below of to_playlist.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
to_playlist_id = to_playlist_model.playlist_id
|
||||||
|
|
||||||
# Row removal must be wrapped in beginRemoveRows ..
|
# Row removal must be wrapped in beginRemoveRows ..
|
||||||
# endRemoveRows and the row range must be contiguous. Process
|
# endRemoveRows and the row range must be contiguous. Process
|
||||||
# the highest rows first so the lower row numbers are unchanged
|
# the highest rows first so the lower row numbers are unchanged
|
||||||
@ -886,6 +878,7 @@ class PlaylistModel(QAbstractTableModel):
|
|||||||
max_destination_row_number
|
max_destination_row_number
|
||||||
and to_row_number <= max_destination_row_number
|
and to_row_number <= max_destination_row_number
|
||||||
):
|
):
|
||||||
|
# Move the destination playlist rows down to make room.
|
||||||
PlaylistRows.move_rows_down(
|
PlaylistRows.move_rows_down(
|
||||||
session, to_playlist_id, to_row_number, len(from_rows)
|
session, to_playlist_id, to_row_number, len(from_rows)
|
||||||
)
|
)
|
||||||
|
|||||||
@ -77,7 +77,8 @@ class EscapeDelegate(QStyledItemDelegate):
|
|||||||
row = index.row()
|
row = index.row()
|
||||||
row_height = p.rowHeight(row)
|
row_height = p.rowHeight(row)
|
||||||
p.setRowHeight(row, row_height + Config.MINIMUM_ROW_HEIGHT)
|
p.setRowHeight(row, row_height + Config.MINIMUM_ROW_HEIGHT)
|
||||||
return QPlainTextEdit(parent)
|
self.editor = QPlainTextEdit(parent)
|
||||||
|
return self.editor
|
||||||
return super().createEditor(parent, option, index)
|
return super().createEditor(parent, option, index)
|
||||||
|
|
||||||
def destroyEditor(self, editor: Optional[QWidget], index: QModelIndex) -> None:
|
def destroyEditor(self, editor: Optional[QWidget], index: QModelIndex) -> None:
|
||||||
@ -102,6 +103,10 @@ class EscapeDelegate(QStyledItemDelegate):
|
|||||||
self.closeEditor.emit(editor)
|
self.closeEditor.emit(editor)
|
||||||
return True
|
return True
|
||||||
elif key_event.key() == Qt.Key.Key_Escape:
|
elif key_event.key() == Qt.Key.Key_Escape:
|
||||||
|
if self.original_text == self.editor.toPlainText():
|
||||||
|
# No changes made
|
||||||
|
self.closeEditor.emit(editor)
|
||||||
|
return True
|
||||||
discard_edits = QMessageBox.question(
|
discard_edits = QMessageBox.question(
|
||||||
cast(QWidget, self.parent()), "Abandon edit", "Discard changes?"
|
cast(QWidget, self.parent()), "Abandon edit", "Discard changes?"
|
||||||
)
|
)
|
||||||
@ -117,8 +122,8 @@ class EscapeDelegate(QStyledItemDelegate):
|
|||||||
else:
|
else:
|
||||||
edit_index = index
|
edit_index = index
|
||||||
|
|
||||||
value = self.data_model.data(edit_index, Qt.ItemDataRole.EditRole)
|
self.original_text = self.data_model.data(edit_index, Qt.ItemDataRole.EditRole)
|
||||||
editor.setPlainText(value.value())
|
editor.setPlainText(self.original_text.value())
|
||||||
|
|
||||||
def setModelData(self, editor, model, index):
|
def setModelData(self, editor, model, index):
|
||||||
model = index.model()
|
model = index.model()
|
||||||
@ -188,12 +193,6 @@ class PlaylistTab(QTableView):
|
|||||||
self.customContextMenuRequested.connect(self._context_menu)
|
self.customContextMenuRequested.connect(self._context_menu)
|
||||||
|
|
||||||
# Connect signals
|
# Connect signals
|
||||||
# This dancing is to satisfy mypy
|
|
||||||
h_header = self.horizontalHeader()
|
|
||||||
if isinstance(h_header, QHeaderView):
|
|
||||||
h_header.sectionResized.connect(self._column_resize)
|
|
||||||
h_header.setStretchLastSection(True)
|
|
||||||
# self.signals.set_next_track_signal.connect(self._reset_next)
|
|
||||||
self.signals = MusicMusterSignals()
|
self.signals = MusicMusterSignals()
|
||||||
self.signals.resize_rows_signal.connect(self.resizeRowsToContents)
|
self.signals.resize_rows_signal.connect(self.resizeRowsToContents)
|
||||||
self.signals.span_cells_signal.connect(self._span_cells)
|
self.signals.span_cells_signal.connect(self._span_cells)
|
||||||
@ -205,7 +204,7 @@ class PlaylistTab(QTableView):
|
|||||||
# Load playlist rows
|
# Load playlist rows
|
||||||
self.setModel(self.proxy_model)
|
self.setModel(self.proxy_model)
|
||||||
self._set_column_widths()
|
self._set_column_widths()
|
||||||
QTimer.singleShot(0, lambda: self.resizeRowsToContents())
|
self.resizeRowsToContents()
|
||||||
|
|
||||||
# ########## Overrident class functions ##########
|
# ########## Overrident class functions ##########
|
||||||
|
|
||||||
@ -695,6 +694,12 @@ class PlaylistTab(QTableView):
|
|||||||
self.setColumnWidth(column_number, record.f_int)
|
self.setColumnWidth(column_number, record.f_int)
|
||||||
else:
|
else:
|
||||||
self.setColumnWidth(column_number, Config.DEFAULT_COLUMN_WIDTH)
|
self.setColumnWidth(column_number, Config.DEFAULT_COLUMN_WIDTH)
|
||||||
|
# Stretch last column *after* setting column widths which is
|
||||||
|
# *much* faster
|
||||||
|
h_header = self.horizontalHeader()
|
||||||
|
if isinstance(h_header, QHeaderView):
|
||||||
|
h_header.sectionResized.connect(self._column_resize)
|
||||||
|
h_header.setStretchLastSection(True)
|
||||||
|
|
||||||
def set_row_as_next_track(self) -> None:
|
def set_row_as_next_track(self) -> None:
|
||||||
"""
|
"""
|
||||||
|
|||||||
@ -303,7 +303,7 @@ def test_move_one_row_between_playlists_to_end(monkeypatch, session):
|
|||||||
model_src = create_model_with_playlist_rows(session, create_rowcount, name="source")
|
model_src = create_model_with_playlist_rows(session, create_rowcount, name="source")
|
||||||
model_dst = create_model_with_playlist_rows(session, create_rowcount, name="destination")
|
model_dst = create_model_with_playlist_rows(session, create_rowcount, name="destination")
|
||||||
|
|
||||||
model_src.move_rows_between_playlists(from_rows, to_row, model_dst.playlist_id)
|
model_src.move_rows_between_playlists(from_rows, to_row, model_dst)
|
||||||
model_dst.refresh_data(session)
|
model_dst.refresh_data(session)
|
||||||
|
|
||||||
assert len(model_src.playlist_rows) == create_rowcount - len(from_rows)
|
assert len(model_src.playlist_rows) == create_rowcount - len(from_rows)
|
||||||
@ -323,7 +323,7 @@ def test_move_one_row_between_playlists_to_middle(monkeypatch, session):
|
|||||||
model_src = create_model_with_playlist_rows(session, create_rowcount, name="source")
|
model_src = create_model_with_playlist_rows(session, create_rowcount, name="source")
|
||||||
model_dst = create_model_with_playlist_rows(session, create_rowcount, name="destination")
|
model_dst = create_model_with_playlist_rows(session, create_rowcount, name="destination")
|
||||||
|
|
||||||
model_src.move_rows_between_playlists(from_rows, to_row, model_dst.playlist_id)
|
model_src.move_rows_between_playlists(from_rows, to_row, model_dst)
|
||||||
model_dst.refresh_data(session)
|
model_dst.refresh_data(session)
|
||||||
|
|
||||||
# Check the rows of the destination model
|
# Check the rows of the destination model
|
||||||
@ -347,7 +347,7 @@ def test_move_multiple_rows_between_playlists_to_end(monkeypatch, session):
|
|||||||
model_src = create_model_with_playlist_rows(session, create_rowcount, name="source")
|
model_src = create_model_with_playlist_rows(session, create_rowcount, name="source")
|
||||||
model_dst = create_model_with_playlist_rows(session, create_rowcount, name="destination")
|
model_dst = create_model_with_playlist_rows(session, create_rowcount, name="destination")
|
||||||
|
|
||||||
model_src.move_rows_between_playlists(from_rows, to_row, model_dst.playlist_id)
|
model_src.move_rows_between_playlists(from_rows, to_row, model_dst)
|
||||||
model_dst.refresh_data(session)
|
model_dst.refresh_data(session)
|
||||||
|
|
||||||
# Check the rows of the destination model
|
# Check the rows of the destination model
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user