Compare commits

..

No commits in common. "c58eb47cc1b706abe70765c883ac483fbe1a0f88" and "25771f52356a563cc011202d88cc4283c42db38b" have entirely different histories.

6 changed files with 92 additions and 161 deletions

View File

@ -247,6 +247,11 @@ class MusicMusterSignals(QObject):
# Signals that the playlist_id passed should resize all rows. # Signals that the playlist_id passed should resize all rows.
resize_rows_signal = pyqtSignal(int) resize_rows_signal = pyqtSignal(int)
# Signal to open browser at songfacts or wikipedia page matching
# passed string.
search_songfacts_signal = pyqtSignal(str)
search_wikipedia_signal = pyqtSignal(str)
# Displays a warning dialog # Displays a warning dialog
show_warning_signal = pyqtSignal(str, str) show_warning_signal = pyqtSignal(str, str)
@ -279,14 +284,14 @@ class MusicMusterSignals(QObject):
# Emited when a track starts playing # Emited when a track starts playing
signal_track_started = pyqtSignal() signal_track_started = pyqtSignal()
# Emitted when track ends or is manually faded
signal_track_ended = pyqtSignal(int)
# Used by model to signal spanning of cells to playlist for headers # Used by model to signal spanning of cells to playlist for headers
span_cells_signal = pyqtSignal(int, int, int, int, int) span_cells_signal = pyqtSignal(int, int, int, int, int)
# Dispay status message to user # Dispay status message to user
status_message_signal = pyqtSignal(str, int) status_message_signal = pyqtSignal(str, int)
# Emitted when track ends or is manually faded
signal_track_ended = pyqtSignal(int)
def __post_init__(self): def __post_init__(self):
super().__init__() super().__init__()

View File

@ -101,7 +101,7 @@ class Music:
if not self.player.get_position() > 0 and self.player.is_playing(): if not self.player.get_position() > 0 and self.player.is_playing():
return return
self.emit_signal_track_ended() self.signal_track_ended()
self.fader_worker = _FadeTrack(self.player, fade_seconds=fade_seconds) self.fader_worker = _FadeTrack(self.player, fade_seconds=fade_seconds)
self.fader_worker.finished.connect(self.player.release) self.fader_worker.finished.connect(self.player.release)
@ -225,7 +225,7 @@ class Music:
log.debug(f"Volume reset from {volume=}") log.debug(f"Volume reset from {volume=}")
sleep(0.1) sleep(0.1)
def emit_signal_track_ended(self) -> None: def signal_track_ended(self) -> None:
""" """
Multiple parts of the Music class can signal that the track has Multiple parts of the Music class can signal that the track has
ended. Handle them all here to ensure that only one such signal ended. Handle them all here to ensure that only one such signal
@ -254,7 +254,7 @@ class Music:
self.player.stop() self.player.stop()
self.player.release() self.player.release()
self.player = None self.player = None
self.emit_signal_track_ended() self.signal_track_ended()
def track_end_event_handler(self, event: vlc.Event) -> None: def track_end_event_handler(self, event: vlc.Event) -> None:
""" """
@ -262,4 +262,4 @@ class Music:
""" """
log.debug("track_end_event_handler() called") log.debug("track_end_event_handler() called")
self.emit_signal_track_ended() self.signal_track_ended()

View File

@ -6,7 +6,7 @@ from functools import partial
from slugify import slugify # type: ignore from slugify import slugify # type: ignore
from typing import Any, Callable from typing import Any, Callable
import argparse import argparse
from dataclasses import dataclass, field from dataclasses import dataclass
import datetime as dt import datetime as dt
import os import os
import subprocess import subprocess
@ -70,14 +70,14 @@ from classes import (
MusicMusterSignals, MusicMusterSignals,
PlaylistDTO, PlaylistDTO,
QueryDTO, QueryDTO,
SelectedRows, TrackAndPlaylist,
TrackInfo, TrackInfo,
) )
from config import Config from config import Config
from dialogs import TrackInsertDialog from dialogs import TrackInsertDialog
from file_importer import FileImporter from file_importer import FileImporter
from helpers import file_is_unreadable, get_name from helpers import ask_yes_no, file_is_unreadable, get_name
from log import log, log_call from log import log, log_call
from playlistmodel import PlaylistModel, PlaylistProxyModel from playlistmodel import PlaylistModel, PlaylistProxyModel
from playlistrow import PlaylistRow, TrackSequence from playlistrow import PlaylistRow, TrackSequence
@ -104,6 +104,15 @@ class SignalMonitor:
self.signals.resize_rows_signal.connect( self.signals.resize_rows_signal.connect(
partial(self.show_signal, "resize_rows_signal ") partial(self.show_signal, "resize_rows_signal ")
) )
self.signals.search_songfacts_signal.connect(
partial(self.show_signal, "search_songfacts_signal ")
)
self.signals.search_wikipedia_signal.connect(
partial(self.show_signal, "search_wikipedia_signal ")
)
self.signals.show_warning_signal.connect(
partial(self.show_signal, "show_warning_signal ")
)
self.signals.signal_add_track_to_header.connect( self.signals.signal_add_track_to_header.connect(
partial(self.show_signal, "signal_add_track_to_header ") partial(self.show_signal, "signal_add_track_to_header ")
) )
@ -143,12 +152,17 @@ class SignalMonitor:
log.debug(f"{name=}, args={args}") log.debug(f"{name=}, args={args}")
@dataclass
class Current: class Current:
base_model: PlaylistModel base_model: PlaylistModel
proxy_model: PlaylistProxyModel proxy_model: PlaylistProxyModel
playlist_id: int playlist_id: int = 0
selected_row_numbers: list[int] = field(default_factory=list) selected_row_numbers: list[int] = []
def __repr__(self):
return (
f"<Current(base_model={self.base_model}, proxy_model={self.proxy_model}, "
f"playlist_id={self.playlist_id}, selected_rows={self.selected_row_numbers}>"
)
class DownloadCSV(QDialog): class DownloadCSV(QDialog):
@ -1211,7 +1225,7 @@ class Window(QMainWindow):
self.disable_selection_timing = False self.disable_selection_timing = False
self.catch_return_key = False self.catch_return_key = False
self.importer: FileImporter | None = None self.importer: FileImporter | None = None
self.current: Current | None = None self.current = Current()
self.track_sequence = TrackSequence() self.track_sequence = TrackSequence()
self.signals = MusicMusterSignals() self.signals = MusicMusterSignals()
self.connect_signals_slots() self.connect_signals_slots()
@ -1241,10 +1255,7 @@ class Window(QMainWindow):
return return
# Don't allow window to close when a track is playing # Don't allow window to close when a track is playing
if ( if self.track_sequence.current and self.track_sequence.current.music.is_playing():
self.track_sequence.current
and self.track_sequence.current.music.is_playing()
):
event.ignore() event.ignore()
helpers.show_warning( helpers.show_warning(
self, "Track playing", "Can't close application while track is playing" self, "Track playing", "Can't close application while track is playing"
@ -1497,9 +1508,6 @@ class Window(QMainWindow):
but unused. but unused.
""" """
if self.current is None:
return
playlist = ds.playlist_by_id(self.current.playlist_id) playlist = ds.playlist_by_id(self.current.playlist_id)
if playlist: if playlist:
if helpers.ask_yes_no( if helpers.ask_yes_no(
@ -1524,9 +1532,6 @@ class Window(QMainWindow):
def save_as_template(self, checked: bool = False) -> None: def save_as_template(self, checked: bool = False) -> None:
"""Save current playlist as template""" """Save current playlist as template"""
if self.current is None:
return
template_names = [a.name for a in ds.playlists_templates_all()] template_names = [a.name for a in ds.playlists_templates_all()]
while True: while True:
@ -1616,9 +1621,6 @@ class Window(QMainWindow):
Show query dialog with query_id selected Show query dialog with query_id selected
""" """
if self.current is None:
return
# Keep a reference else it will be gc'd # Keep a reference else it will be gc'd
self.query_dialog = QueryDialog(self.current.playlist_id, query_id) self.query_dialog = QueryDialog(self.current.playlist_id, query_id)
self.query_dialog.exec() self.query_dialog.exec()
@ -1736,13 +1738,14 @@ class Window(QMainWindow):
self.tabBar = self.playlist_section.tabPlaylist.tabBar() self.tabBar = self.playlist_section.tabPlaylist.tabBar()
self.txtSearch.textChanged.connect(self.search_playlist_text_changed) self.txtSearch.textChanged.connect(self.search_playlist_text_changed)
self.signals.enable_escape_signal.connect(self.enable_escape_signal_handler) self.signals.enable_escape_signal.connect(self.enable_escape)
self.signals.search_songfacts_signal.connect(self.open_songfacts_browser)
self.signals.search_wikipedia_signal.connect(self.open_wikipedia_browser)
self.signals.show_warning_signal.connect(self.show_warning) self.signals.show_warning_signal.connect(self.show_warning)
self.signals.signal_next_track_changed.connect(self.next_track_changed_handler) self.signals.signal_next_track_changed.connect(self.signal_next_track_changed_handler)
self.signals.signal_set_next_track.connect(self.set_next_track_handler) self.signals.signal_set_next_track.connect(self.signal_set_next_track_handler)
self.signals.status_message_signal.connect(self.show_status_message) self.signals.status_message_signal.connect(self.show_status_message)
self.signals.signal_track_ended.connect(self.track_ended_handler) self.signals.signal_track_ended.connect(self.end_of_track_actions)
self.signals.signal_playlist_selected_rows.connect(self.playlist_selected_rows_handler)
self.timer10.timeout.connect(self.tick_10ms) self.timer10.timeout.connect(self.tick_10ms)
self.timer500.timeout.connect(self.tick_500ms) self.timer500.timeout.connect(self.tick_500ms)
@ -1759,13 +1762,8 @@ class Window(QMainWindow):
# TODO should be able to have the model handle row depending on # TODO should be able to have the model handle row depending on
# how current_row_or_end is used # how current_row_or_end is used
if self.current is None:
return 0 # hack, but should never be called without self.current set
if self.current.selected_row_numbers: if self.current.selected_row_numbers:
return self.current.selected_row_numbers[0] return self.current.selected_row_numbers[0]
if not self.current.base_model:
return 0 # hack, but mostly there WILL be a current model
return self.current.base_model.rowCount() return self.current.base_model.rowCount()
def debug(self, checked: bool = False) -> None: def debug(self, checked: bool = False) -> None:
@ -1808,7 +1806,7 @@ class Window(QMainWindow):
) )
# @log_call # @log_call
def enable_escape_signal_handler(self, enabled: bool) -> None: def enable_escape(self, enabled: bool) -> None:
""" """
Manage signal to enable/disable handling ESC character. Manage signal to enable/disable handling ESC character.
@ -1820,7 +1818,7 @@ class Window(QMainWindow):
self.menu_actions["clear_selection"].setEnabled(enabled) self.menu_actions["clear_selection"].setEnabled(enabled)
# @log_call # @log_call
def track_ended_handler(self) -> None: def end_of_track_actions(self) -> None:
""" """
Called by signal_track_ended Called by signal_track_ended
@ -1851,9 +1849,6 @@ class Window(QMainWindow):
def export_playlist_tab(self, checked: bool = False) -> None: def export_playlist_tab(self, checked: bool = False) -> None:
"""Export the current playlist to an m3u file""" """Export the current playlist to an m3u file"""
if self.current is None:
return
playlist_id = self.current.playlist_id playlist_id = self.current.playlist_id
playlist = ds.playlist_by_id(playlist_id) playlist = ds.playlist_by_id(playlist_id)
@ -1926,7 +1921,7 @@ class Window(QMainWindow):
self.current.base_model.hide_played_tracks(True) self.current.base_model.hide_played_tracks(True)
# Reset row heights # Reset row heights
self.signals.resize_rows_signal.emit(self.current.playlist_id) self._active_tab().resize_rows()
def import_files_wrapper(self, checked: bool = False) -> None: def import_files_wrapper(self, checked: bool = False) -> None:
""" """
@ -1935,18 +1930,12 @@ class Window(QMainWindow):
# We need to keep a reference to the FileImporter else it will be # We need to keep a reference to the FileImporter else it will be
# garbage collected while import threads are still running # garbage collected while import threads are still running
if self.current is None:
return
self.importer = FileImporter(self.current.base_model, self.current_row_or_end()) self.importer = FileImporter(self.current.base_model, self.current_row_or_end())
self.importer.start() self.importer.start()
def insert_header(self, checked: bool = False) -> None: def insert_header(self, checked: bool = False) -> None:
"""Show dialog box to enter header text and add to playlist""" """Show dialog box to enter header text and add to playlist"""
if self.current is None:
return
# Get header text # Get header text
dlg: QInputDialog = QInputDialog(self) dlg: QInputDialog = QInputDialog(self)
dlg.setInputMode(QInputDialog.InputMode.TextInput) dlg.setInputMode(QInputDialog.InputMode.TextInput)
@ -1965,9 +1954,6 @@ class Window(QMainWindow):
def insert_track(self, checked: bool = False) -> None: def insert_track(self, checked: bool = False) -> None:
"""Show dialog box to select and add track from database""" """Show dialog box to select and add track from database"""
if self.current is None:
return
dlg = TrackInsertDialog(parent=self, playlist_id=self.current.playlist_id) dlg = TrackInsertDialog(parent=self, playlist_id=self.current.playlist_id)
dlg.exec() dlg.exec()
@ -1995,7 +1981,7 @@ class Window(QMainWindow):
if not track_info: if not track_info:
return return
self.open_songfacts_browser(track_info.title) self.signals.search_songfacts_signal.emit(track_info.title)
def lookup_row_in_wikipedia(self, checked: bool = False) -> None: def lookup_row_in_wikipedia(self, checked: bool = False) -> None:
""" """
@ -2006,16 +1992,13 @@ class Window(QMainWindow):
if not track_info: if not track_info:
return return
self.open_wikipedia_browser(track_info.title) self.signals.search_wikipedia_signal.emit(track_info.title)
def mark_rows_for_moving(self, checked: bool = False) -> None: def mark_rows_for_moving(self, checked: bool = False) -> None:
""" """
Cut rows ready for pasting. Cut rows ready for pasting.
""" """
if self.current is None:
return
# Save the selected PlaylistRows items ready for a later # Save the selected PlaylistRows items ready for a later
# paste # paste
self.move_source = MoveSource( self.move_source = MoveSource(
@ -2030,7 +2013,7 @@ class Window(QMainWindow):
Move passed playlist rows to another playlist Move passed playlist rows to another playlist
""" """
if not row_numbers or self.current is None: if not row_numbers:
return return
# Identify destination playlist # Identify destination playlist
@ -2066,9 +2049,6 @@ class Window(QMainWindow):
Move selected rows to another playlist Move selected rows to another playlist
""" """
if self.current is None:
return
self.move_playlist_rows(self.current.selected_row_numbers) self.move_playlist_rows(self.current.selected_row_numbers)
def move_unplayed(self, checked: bool = False) -> None: def move_unplayed(self, checked: bool = False) -> None:
@ -2076,9 +2056,6 @@ class Window(QMainWindow):
Move unplayed rows to another playlist Move unplayed rows to another playlist
""" """
if self.current is None:
return
unplayed_rows = self.current.base_model.get_unplayed_rows() unplayed_rows = self.current.base_model.get_unplayed_rows()
if not unplayed_rows: if not unplayed_rows:
return return
@ -2114,7 +2091,7 @@ class Window(QMainWindow):
'checked' is a dummy parameter passed to us by the menu 'checked' is a dummy parameter passed to us by the menu
""" """
if not self.move_source or self.current is None: if not self.move_source:
return return
to_playlist_model = self.current.base_model to_playlist_model = self.current.base_model
@ -2129,7 +2106,7 @@ class Window(QMainWindow):
from_rows, to_row, to_playlist_model.playlist_id from_rows, to_row, to_playlist_model.playlist_id
) )
self.signals.resize_rows_signal.emit(self.current.playlist_id) self._active_tab().resize_rows()
self._active_tab().clear_selection() self._active_tab().clear_selection()
# If we move a row to immediately under the current track, make # If we move a row to immediately under the current track, make
@ -2139,7 +2116,7 @@ class Window(QMainWindow):
and self.track_sequence.current.playlist_id == to_playlist_model.playlist_id and self.track_sequence.current.playlist_id == to_playlist_model.playlist_id
and to_row == self.track_sequence.current.row_number + 1 and to_row == self.track_sequence.current.row_number + 1
): ):
to_playlist_model.set_next_row_handler(to_row) to_playlist_model.set_next_row(to_row)
# @log_call # @log_call
def play_next(self, position: float | None = None, checked: bool = False) -> None: def play_next(self, position: float | None = None, checked: bool = False) -> None:
@ -2182,7 +2159,7 @@ class Window(QMainWindow):
if self.track_sequence.current: if self.track_sequence.current:
self.track_sequence.current.fade() self.track_sequence.current.fade()
# Move next track to current track. signal_track_ended_handler() will # Move next track to current track. end_of_track_actions() will
# have been called when previous track ended or when fade() was # have been called when previous track ended or when fade() was
# called above, and that in turn will have saved current track to # called above, and that in turn will have saved current track to
# previous_track # previous_track
@ -2290,9 +2267,6 @@ class Window(QMainWindow):
def preview_mark(self) -> None: def preview_mark(self) -> None:
"""Set intro time""" """Set intro time"""
if self.current is None:
return
if self.preview_manager.is_playing(): if self.preview_manager.is_playing():
track_id = self.preview_manager.track_id track_id = self.preview_manager.track_id
row_number = self.preview_manager.row_number row_number = self.preview_manager.row_number
@ -2334,9 +2308,6 @@ class Window(QMainWindow):
Rename current playlist. checked is passed by menu but not used here Rename current playlist. checked is passed by menu but not used here
""" """
if self.current is None:
return
playlist = ds.playlist_by_id(self.current.playlist_id) playlist = ds.playlist_by_id(self.current.playlist_id)
if playlist: if playlist:
new_name = self.get_playlist_name(playlist.name) new_name = self.get_playlist_name(playlist.name)
@ -2454,9 +2425,6 @@ class Window(QMainWindow):
Incremental search of playlist Incremental search of playlist
""" """
if self.current is None:
return
self.current.proxy_model.set_incremental_search(self.txtSearch.text()) self.current.proxy_model.set_incremental_search(self.txtSearch.text())
def selected_or_next_track_info(self) -> PlaylistRow | None: def selected_or_next_track_info(self) -> PlaylistRow | None:
@ -2465,9 +2433,6 @@ class Window(QMainWindow):
next track. If no next track, return None. next track. If no next track, return None.
""" """
if self.current is None:
return None
row_number: int | None = None row_number: int | None = None
if self.current.selected_row_numbers: if self.current.selected_row_numbers:
@ -2500,9 +2465,6 @@ class Window(QMainWindow):
Set currently-selected row on visible playlist tab as next track Set currently-selected row on visible playlist tab as next track
""" """
if self.current is None:
return
self.signals.signal_set_next_row.emit(self.current.playlist_id) self.signals.signal_set_next_row.emit(self.current.playlist_id)
self.clear_selection() self.clear_selection()
@ -2541,9 +2503,6 @@ class Window(QMainWindow):
def show_track(self, playlist_track: PlaylistRow) -> None: def show_track(self, playlist_track: PlaylistRow) -> None:
"""Scroll to show track""" """Scroll to show track"""
if self.current is None:
return
# Switch to the correct tab # Switch to the correct tab
playlist_id = playlist_track.playlist_id playlist_id = playlist_track.playlist_id
if not playlist_id: if not playlist_id:
@ -2562,20 +2521,7 @@ class Window(QMainWindow):
self._active_tab().scroll_to_top(playlist_track.row_number) self._active_tab().scroll_to_top(playlist_track.row_number)
def playlist_selected_rows_handler( def signal_set_next_track_handler(self, plr: PlaylistRow) -> None:
self, selected_rows: SelectedRows
) -> None:
"""
Handle signal_playlist_selected_rows to keep track of which rows
are selected in the current model
"""
if self.current is None:
return
self.current.selected_row_numbers = selected_rows.rows
def set_next_track_handler(self, plr: PlaylistRow) -> None:
""" """
Handle signal_set_next_track Handle signal_set_next_track
""" """
@ -2583,7 +2529,7 @@ class Window(QMainWindow):
self.track_sequence.set_next(plr) self.track_sequence.set_next(plr)
self.signals.signal_next_track_changed.emit() self.signals.signal_next_track_changed.emit()
def next_track_changed_handler(self) -> None: def signal_next_track_changed_handler(self) -> None:
""" """
Handle next track changed Handle next track changed
""" """
@ -2683,10 +2629,7 @@ class Window(QMainWindow):
""" """
# If track is playing, update track clocks time and colours # If track is playing, update track clocks time and colours
if ( if self.track_sequence.current and self.track_sequence.current.music.is_playing():
self.track_sequence.current
and self.track_sequence.current.music.is_playing()
):
# Elapsed time # Elapsed time
self.header_section.label_elapsed_timer.setText( self.header_section.label_elapsed_timer.setText(
helpers.ms_to_mmss(self.track_sequence.current.time_playing()) helpers.ms_to_mmss(self.track_sequence.current.time_playing())
@ -2741,24 +2684,6 @@ class Window(QMainWindow):
helpers.ms_to_mmss(time_to_silence) helpers.ms_to_mmss(time_to_silence)
) )
def update_current(
self,
base_model: PlaylistModel,
proxy_model: PlaylistProxyModel,
playlist_id: int,
selected_row_numbers: list[int]
) -> None:
"""
Update self.current when playlist tab changes. Called by new playlist
"""
self.current = Current(
base_model=base_model,
proxy_model=proxy_model,
playlist_id=playlist_id,
selected_row_numbers=selected_row_numbers
)
def update_headers(self) -> None: def update_headers(self) -> None:
""" """
Update last / current / next track headers Update last / current / next track headers

View File

@ -93,15 +93,17 @@ class PlaylistModel(QAbstractTableModel):
self.played_tracks_hidden = False self.played_tracks_hidden = False
# Connect signals # Connect signals
self.signals.signal_add_track_to_header.connect(self.signal_add_track_to_header_handler) self.signals.signal_add_track_to_header.connect(self.add_track_to_header)
self.signals.signal_begin_insert_rows.connect(self.begin_insert_rows_handler) self.signals.signal_begin_insert_rows.connect(self.begin_insert_rows)
self.signals.signal_end_insert_rows.connect(self.end_insert_rows_handler) self.signals.signal_end_insert_rows.connect(self.end_insert_rows)
self.signals.signal_insert_track.connect(self.insert_row_signal_handler) self.signals.signal_insert_track.connect(self.insert_row_signal_handler)
self.signals.signal_playlist_selected_rows.connect(self.playlist_selected_rows_handler) self.signals.signal_playlist_selected_rows.connect(self.set_selected_rows)
self.signals.signal_set_next_row.connect(self.set_next_row_handler) self.signals.signal_set_next_row.connect(self.set_next_row)
self.signals.signal_track_started.connect(self.track_started_handler) self.signals.signal_track_started.connect(self.track_started)
self.signals.signal_track_ended.connect(self.signal_track_ended_handler) self.signals.signal_track_ended.connect(self.previous_track_ended)
self.signals.signal_next_track_changed.connect(self.next_track_changed_handler) self.signals.signal_next_track_changed.connect(
self.signal_next_track_changed_handler
)
# Populate self.playlist_rows # Populate self.playlist_rows
for dto in ds.playlistrows_by_playlist(self.playlist_id): for dto in ds.playlistrows_by_playlist(self.playlist_id):
@ -150,7 +152,7 @@ class PlaylistModel(QAbstractTableModel):
return header_row return header_row
# @log_call # @log_call
def signal_add_track_to_header_handler(self, track_and_playlist: TrackAndPlaylist) -> None: def add_track_to_header(self, track_and_playlist: TrackAndPlaylist) -> None:
""" """
Handle signal_add_track_to_header Handle signal_add_track_to_header
""" """
@ -249,7 +251,7 @@ class PlaylistModel(QAbstractTableModel):
return len(Col) return len(Col)
# @log_call # @log_call
def track_started_handler(self) -> None: def track_started(self) -> None:
""" """
Handle signal_track_started signal. Handle signal_track_started signal.
@ -894,7 +896,7 @@ class PlaylistModel(QAbstractTableModel):
self.track_sequence.update() self.track_sequence.update()
self.update_track_times() self.update_track_times()
def begin_insert_rows_handler(self, insert_rows: InsertRows) -> None: def begin_insert_rows(self, insert_rows: InsertRows) -> None:
""" """
Prepare model to insert rows Prepare model to insert rows
""" """
@ -904,7 +906,7 @@ class PlaylistModel(QAbstractTableModel):
super().beginInsertRows(QModelIndex(), insert_rows.from_row, insert_rows.to_row) super().beginInsertRows(QModelIndex(), insert_rows.from_row, insert_rows.to_row)
def end_insert_rows_handler(self, playlist_id: int) -> None: def end_insert_rows(self, playlist_id: int) -> None:
""" """
End insert rows End insert rows
""" """
@ -970,7 +972,7 @@ class PlaylistModel(QAbstractTableModel):
return return
# @log_call # @log_call
def signal_track_ended_handler(self, playlist_id: int) -> None: def previous_track_ended(self, playlist_id: int) -> None:
""" """
Notification from signal_track_ended that the previous track has ended. Notification from signal_track_ended that the previous track has ended.
@ -986,12 +988,12 @@ class PlaylistModel(QAbstractTableModel):
# Sanity check # Sanity check
if not self.track_sequence.previous: if not self.track_sequence.previous:
log.error( log.error(
f"{self}: playlistmodel:signal_track_ended_handler called with no current track" f"{self}: playlistmodel:previous_track_ended called with no current track"
) )
return return
if self.track_sequence.previous.row_number is None: if self.track_sequence.previous.row_number is None:
log.error( log.error(
f"{self}: signal_track_ended_handler called with no row number " f"{self}: previous_track_ended called with no row number "
f"({self.track_sequence.previous=})" f"({self.track_sequence.previous=})"
) )
return return
@ -1253,7 +1255,7 @@ class PlaylistModel(QAbstractTableModel):
return True return True
# @log_call # @log_call
def playlist_selected_rows_handler(self, selected_rows: SelectedRows) -> None: def set_selected_rows(self, selected_rows: SelectedRows) -> None:
""" """
Handle signal_playlist_selected_rows to keep track of which rows Handle signal_playlist_selected_rows to keep track of which rows
are selected in the view are selected in the view
@ -1265,7 +1267,7 @@ class PlaylistModel(QAbstractTableModel):
self.selected_rows = [self.playlist_rows[a] for a in selected_rows.rows] self.selected_rows = [self.playlist_rows[a] for a in selected_rows.rows]
# @log_call # @log_call
def set_next_row_handler(self, playlist_id: int) -> None: def set_next_row(self, playlist_id: int) -> None:
""" """
Handle signal_set_next_row Handle signal_set_next_row
""" """
@ -1304,7 +1306,7 @@ class PlaylistModel(QAbstractTableModel):
self.signals.signal_set_next_track.emit(plr) self.signals.signal_set_next_track.emit(plr)
def next_track_changed_handler(self) -> None: def signal_next_track_changed_handler(self) -> None:
""" """
Handle next track changed Handle next track changed
""" """

View File

@ -41,6 +41,7 @@ from classes import (
MusicMusterSignals, MusicMusterSignals,
PlaylistStyle, PlaylistStyle,
SelectedRows, SelectedRows,
TrackAndPlaylist,
TrackInfo TrackInfo
) )
from config import Config from config import Config
@ -309,9 +310,9 @@ class PlaylistTab(QTableView):
# Connect signals # Connect signals
self.signals = MusicMusterSignals() self.signals = MusicMusterSignals()
self.signals.resize_rows_signal.connect(self.resize_rows_handler) self.signals.resize_rows_signal.connect(self.resize_rows)
self.signals.span_cells_signal.connect(self._span_cells_handler) self.signals.span_cells_signal.connect(self._span_cells)
self.signals.signal_track_started.connect(self.track_started_handler) self.signals.signal_track_started.connect(self.track_started)
# Selection model # Selection model
self.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection) self.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection)
@ -342,7 +343,7 @@ class PlaylistTab(QTableView):
v_header.sectionHandleDoubleClicked.connect(self.resizeRowToContents) v_header.sectionHandleDoubleClicked.connect(self.resizeRowToContents)
# Setting ResizeToContents causes screen flash on load # Setting ResizeToContents causes screen flash on load
self.resize_rows_handler() self.resize_rows()
# ########## Overridden class functions ########## # ########## Overridden class functions ##########
@ -353,12 +354,12 @@ class PlaylistTab(QTableView):
Override closeEditor to enable play controls and update display. Override closeEditor to enable play controls and update display.
""" """
self.signals.enable_escape_signal.emit(True) self.musicmuster.enable_escape(True)
super(PlaylistTab, self).closeEditor(editor, hint) super(PlaylistTab, self).closeEditor(editor, hint)
# Optimise row heights after increasing row height for editing # Optimise row heights after increasing row height for editing
self.resize_rows_handler() self.resize_rows()
# Update start times in case a start time in a note has been # Update start times in case a start time in a note has been
# edited # edited
@ -429,11 +430,11 @@ class PlaylistTab(QTableView):
self.clear_selection() self.clear_selection()
# Resize rows # Resize rows
self.resize_rows_handler() self.resize_rows()
# Set next row if we are immediately under current row # Set next row if we are immediately under current row
if set_next_row: if set_next_row:
self.get_base_model().set_next_row_handler(set_next_row) self.get_base_model().set_next_row(set_next_row)
event.accept() event.accept()
@ -728,7 +729,7 @@ class PlaylistTab(QTableView):
cb.setText(track_path, mode=cb.Mode.Clipboard) cb.setText(track_path, mode=cb.Mode.Clipboard)
# @log_call # @log_call
def track_started_handler(self) -> None: def track_started(self) -> None:
""" """
Called when track starts playing Called when track starts playing
""" """
@ -964,7 +965,7 @@ class PlaylistTab(QTableView):
self.get_base_model().rescan_track(row_number) self.get_base_model().rescan_track(row_number)
self.clear_selection() self.clear_selection()
def resize_rows_handler(self, playlist_id: Optional[int] = None) -> None: def resize_rows(self, playlist_id: Optional[int] = None) -> None:
""" """
If playlist_id is us, resize rows If playlist_id is us, resize rows
""" """
@ -1091,10 +1092,10 @@ class PlaylistTab(QTableView):
log.debug(f"set_row_as_next_track() {model_row_number=}") log.debug(f"set_row_as_next_track() {model_row_number=}")
if model_row_number is None: if model_row_number is None:
return return
self.get_base_model().set_next_row_handler(model_row_number) self.get_base_model().set_next_row(model_row_number)
self.clearSelection() self.clearSelection()
def _span_cells_handler( def _span_cells(
self, playlist_id: int, row: int, column: int, rowSpan: int, columnSpan: int self, playlist_id: int, row: int, column: int, rowSpan: int, columnSpan: int
) -> None: ) -> None:
""" """
@ -1130,14 +1131,12 @@ class PlaylistTab(QTableView):
""" """
# Update musicmuster # Update musicmuster
self.musicmuster.update_current( self.musicmuster.current.playlist_id = self.playlist_id
base_model=self.get_base_model(), self.musicmuster.current.selected_row_numbers = self.get_selected_rows()
proxy_model=self.model(), self.musicmuster.current.base_model = self.get_base_model()
playlist_id=self.playlist_id, self.musicmuster.current.proxy_model = self.model()
selected_row_numbers=self.get_selected_rows(),
)
self.resize_rows_handler() self.resize_rows()
def _unmark_as_next(self) -> None: def _unmark_as_next(self) -> None:
"""Rescan track""" """Rescan track"""

View File

@ -225,7 +225,7 @@ class TestMMMiscRowMove(unittest.TestCase):
self.model.selected_rows = [self.model.playlist_rows[insert_row]] self.model.selected_rows = [self.model.playlist_rows[insert_row]]
prd = self.model.playlist_rows[1] prd = self.model.playlist_rows[1]
self.model.signal_add_track_to_header_handler( self.model.add_track_to_header(
TrackAndPlaylist(playlist_id=self.model.playlist_id, track_id=prd.track_id) TrackAndPlaylist(playlist_id=self.model.playlist_id, track_id=prd.track_id)
) )