Compare commits

...

3 Commits

Author SHA1 Message Date
Keith Edmunds
c58eb47cc1 musicmuster.current cleanup 2025-04-21 11:49:10 +01:00
Keith Edmunds
847840251c More signal / signal handler cleanups 2025-04-21 11:48:16 +01:00
Keith Edmunds
f172eaaeb2 Clean up signals
Remove search_wikipedia_signal and search_songfacts_signal. Improve
signal names. Make Current a dataclass.
2025-04-21 10:37:27 +01:00
6 changed files with 161 additions and 92 deletions

View File

@ -247,11 +247,6 @@ 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)
@ -284,14 +279,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.signal_track_ended() self.emit_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 signal_track_ended(self) -> None: def emit_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.signal_track_ended() self.emit_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.signal_track_ended() self.emit_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 from dataclasses import dataclass, field
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,
TrackAndPlaylist, SelectedRows,
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 ask_yes_no, file_is_unreadable, get_name from helpers import 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,15 +104,6 @@ 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 ")
) )
@ -152,17 +143,12 @@ 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 = 0 playlist_id: int
selected_row_numbers: list[int] = [] selected_row_numbers: list[int] = field(default_factory=list)
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):
@ -1225,7 +1211,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() self.current: Current | None = None
self.track_sequence = TrackSequence() self.track_sequence = TrackSequence()
self.signals = MusicMusterSignals() self.signals = MusicMusterSignals()
self.connect_signals_slots() self.connect_signals_slots()
@ -1255,7 +1241,10 @@ 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 self.track_sequence.current and self.track_sequence.current.music.is_playing(): if (
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"
@ -1508,6 +1497,9 @@ 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(
@ -1532,6 +1524,9 @@ 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:
@ -1621,6 +1616,9 @@ 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()
@ -1738,14 +1736,13 @@ 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) self.signals.enable_escape_signal.connect(self.enable_escape_signal_handler)
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.signal_next_track_changed_handler) self.signals.signal_next_track_changed.connect(self.next_track_changed_handler)
self.signals.signal_set_next_track.connect(self.signal_set_next_track_handler) self.signals.signal_set_next_track.connect(self.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.end_of_track_actions) self.signals.signal_track_ended.connect(self.track_ended_handler)
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)
@ -1762,8 +1759,13 @@ 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:
@ -1806,7 +1808,7 @@ class Window(QMainWindow):
) )
# @log_call # @log_call
def enable_escape(self, enabled: bool) -> None: def enable_escape_signal_handler(self, enabled: bool) -> None:
""" """
Manage signal to enable/disable handling ESC character. Manage signal to enable/disable handling ESC character.
@ -1818,7 +1820,7 @@ class Window(QMainWindow):
self.menu_actions["clear_selection"].setEnabled(enabled) self.menu_actions["clear_selection"].setEnabled(enabled)
# @log_call # @log_call
def end_of_track_actions(self) -> None: def track_ended_handler(self) -> None:
""" """
Called by signal_track_ended Called by signal_track_ended
@ -1849,6 +1851,9 @@ 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)
@ -1921,7 +1926,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._active_tab().resize_rows() self.signals.resize_rows_signal.emit(self.current.playlist_id)
def import_files_wrapper(self, checked: bool = False) -> None: def import_files_wrapper(self, checked: bool = False) -> None:
""" """
@ -1930,12 +1935,18 @@ 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)
@ -1954,6 +1965,9 @@ 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()
@ -1981,7 +1995,7 @@ class Window(QMainWindow):
if not track_info: if not track_info:
return return
self.signals.search_songfacts_signal.emit(track_info.title) self.open_songfacts_browser(track_info.title)
def lookup_row_in_wikipedia(self, checked: bool = False) -> None: def lookup_row_in_wikipedia(self, checked: bool = False) -> None:
""" """
@ -1992,13 +2006,16 @@ class Window(QMainWindow):
if not track_info: if not track_info:
return return
self.signals.search_wikipedia_signal.emit(track_info.title) self.open_wikipedia_browser(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(
@ -2013,7 +2030,7 @@ class Window(QMainWindow):
Move passed playlist rows to another playlist Move passed playlist rows to another playlist
""" """
if not row_numbers: if not row_numbers or self.current is None:
return return
# Identify destination playlist # Identify destination playlist
@ -2049,6 +2066,9 @@ 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:
@ -2056,6 +2076,9 @@ 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
@ -2091,7 +2114,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: if not self.move_source or self.current is None:
return return
to_playlist_model = self.current.base_model to_playlist_model = self.current.base_model
@ -2106,7 +2129,7 @@ class Window(QMainWindow):
from_rows, to_row, to_playlist_model.playlist_id from_rows, to_row, to_playlist_model.playlist_id
) )
self._active_tab().resize_rows() self.signals.resize_rows_signal.emit(self.current.playlist_id)
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
@ -2116,7 +2139,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(to_row) to_playlist_model.set_next_row_handler(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:
@ -2159,7 +2182,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. end_of_track_actions() will # Move next track to current track. signal_track_ended_handler() 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
@ -2267,6 +2290,9 @@ 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
@ -2308,6 +2334,9 @@ 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)
@ -2425,6 +2454,9 @@ 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:
@ -2433,6 +2465,9 @@ 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:
@ -2465,6 +2500,9 @@ 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()
@ -2503,6 +2541,9 @@ 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:
@ -2521,7 +2562,20 @@ class Window(QMainWindow):
self._active_tab().scroll_to_top(playlist_track.row_number) self._active_tab().scroll_to_top(playlist_track.row_number)
def signal_set_next_track_handler(self, plr: PlaylistRow) -> None: def playlist_selected_rows_handler(
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
""" """
@ -2529,7 +2583,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 signal_next_track_changed_handler(self) -> None: def next_track_changed_handler(self) -> None:
""" """
Handle next track changed Handle next track changed
""" """
@ -2629,7 +2683,10 @@ class Window(QMainWindow):
""" """
# If track is playing, update track clocks time and colours # If track is playing, update track clocks time and colours
if self.track_sequence.current and self.track_sequence.current.music.is_playing(): if (
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())
@ -2684,6 +2741,24 @@ 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,17 +93,15 @@ 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.add_track_to_header) self.signals.signal_add_track_to_header.connect(self.signal_add_track_to_header_handler)
self.signals.signal_begin_insert_rows.connect(self.begin_insert_rows) self.signals.signal_begin_insert_rows.connect(self.begin_insert_rows_handler)
self.signals.signal_end_insert_rows.connect(self.end_insert_rows) self.signals.signal_end_insert_rows.connect(self.end_insert_rows_handler)
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.set_selected_rows) self.signals.signal_playlist_selected_rows.connect(self.playlist_selected_rows_handler)
self.signals.signal_set_next_row.connect(self.set_next_row) self.signals.signal_set_next_row.connect(self.set_next_row_handler)
self.signals.signal_track_started.connect(self.track_started) self.signals.signal_track_started.connect(self.track_started_handler)
self.signals.signal_track_ended.connect(self.previous_track_ended) self.signals.signal_track_ended.connect(self.signal_track_ended_handler)
self.signals.signal_next_track_changed.connect( self.signals.signal_next_track_changed.connect(self.next_track_changed_handler)
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):
@ -152,7 +150,7 @@ class PlaylistModel(QAbstractTableModel):
return header_row return header_row
# @log_call # @log_call
def add_track_to_header(self, track_and_playlist: TrackAndPlaylist) -> None: def signal_add_track_to_header_handler(self, track_and_playlist: TrackAndPlaylist) -> None:
""" """
Handle signal_add_track_to_header Handle signal_add_track_to_header
""" """
@ -251,7 +249,7 @@ class PlaylistModel(QAbstractTableModel):
return len(Col) return len(Col)
# @log_call # @log_call
def track_started(self) -> None: def track_started_handler(self) -> None:
""" """
Handle signal_track_started signal. Handle signal_track_started signal.
@ -896,7 +894,7 @@ class PlaylistModel(QAbstractTableModel):
self.track_sequence.update() self.track_sequence.update()
self.update_track_times() self.update_track_times()
def begin_insert_rows(self, insert_rows: InsertRows) -> None: def begin_insert_rows_handler(self, insert_rows: InsertRows) -> None:
""" """
Prepare model to insert rows Prepare model to insert rows
""" """
@ -906,7 +904,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(self, playlist_id: int) -> None: def end_insert_rows_handler(self, playlist_id: int) -> None:
""" """
End insert rows End insert rows
""" """
@ -972,7 +970,7 @@ class PlaylistModel(QAbstractTableModel):
return return
# @log_call # @log_call
def previous_track_ended(self, playlist_id: int) -> None: def signal_track_ended_handler(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.
@ -988,12 +986,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:previous_track_ended called with no current track" f"{self}: playlistmodel:signal_track_ended_handler 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}: previous_track_ended called with no row number " f"{self}: signal_track_ended_handler called with no row number "
f"({self.track_sequence.previous=})" f"({self.track_sequence.previous=})"
) )
return return
@ -1255,7 +1253,7 @@ class PlaylistModel(QAbstractTableModel):
return True return True
# @log_call # @log_call
def set_selected_rows(self, selected_rows: SelectedRows) -> None: def playlist_selected_rows_handler(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
@ -1267,7 +1265,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(self, playlist_id: int) -> None: def set_next_row_handler(self, playlist_id: int) -> None:
""" """
Handle signal_set_next_row Handle signal_set_next_row
""" """
@ -1306,7 +1304,7 @@ class PlaylistModel(QAbstractTableModel):
self.signals.signal_set_next_track.emit(plr) self.signals.signal_set_next_track.emit(plr)
def signal_next_track_changed_handler(self) -> None: def next_track_changed_handler(self) -> None:
""" """
Handle next track changed Handle next track changed
""" """

View File

@ -41,7 +41,6 @@ from classes import (
MusicMusterSignals, MusicMusterSignals,
PlaylistStyle, PlaylistStyle,
SelectedRows, SelectedRows,
TrackAndPlaylist,
TrackInfo TrackInfo
) )
from config import Config from config import Config
@ -310,9 +309,9 @@ class PlaylistTab(QTableView):
# Connect signals # Connect signals
self.signals = MusicMusterSignals() self.signals = MusicMusterSignals()
self.signals.resize_rows_signal.connect(self.resize_rows) self.signals.resize_rows_signal.connect(self.resize_rows_handler)
self.signals.span_cells_signal.connect(self._span_cells) self.signals.span_cells_signal.connect(self._span_cells_handler)
self.signals.signal_track_started.connect(self.track_started) self.signals.signal_track_started.connect(self.track_started_handler)
# Selection model # Selection model
self.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection) self.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection)
@ -343,7 +342,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() self.resize_rows_handler()
# ########## Overridden class functions ########## # ########## Overridden class functions ##########
@ -354,12 +353,12 @@ class PlaylistTab(QTableView):
Override closeEditor to enable play controls and update display. Override closeEditor to enable play controls and update display.
""" """
self.musicmuster.enable_escape(True) self.signals.enable_escape_signal.emit(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() self.resize_rows_handler()
# 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
@ -430,11 +429,11 @@ class PlaylistTab(QTableView):
self.clear_selection() self.clear_selection()
# Resize rows # Resize rows
self.resize_rows() self.resize_rows_handler()
# 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(set_next_row) self.get_base_model().set_next_row_handler(set_next_row)
event.accept() event.accept()
@ -729,7 +728,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(self) -> None: def track_started_handler(self) -> None:
""" """
Called when track starts playing Called when track starts playing
""" """
@ -965,7 +964,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(self, playlist_id: Optional[int] = None) -> None: def resize_rows_handler(self, playlist_id: Optional[int] = None) -> None:
""" """
If playlist_id is us, resize rows If playlist_id is us, resize rows
""" """
@ -1092,10 +1091,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(model_row_number) self.get_base_model().set_next_row_handler(model_row_number)
self.clearSelection() self.clearSelection()
def _span_cells( def _span_cells_handler(
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:
""" """
@ -1131,12 +1130,14 @@ class PlaylistTab(QTableView):
""" """
# Update musicmuster # Update musicmuster
self.musicmuster.current.playlist_id = self.playlist_id self.musicmuster.update_current(
self.musicmuster.current.selected_row_numbers = self.get_selected_rows() base_model=self.get_base_model(),
self.musicmuster.current.base_model = self.get_base_model() proxy_model=self.model(),
self.musicmuster.current.proxy_model = self.model() playlist_id=self.playlist_id,
selected_row_numbers=self.get_selected_rows(),
)
self.resize_rows() self.resize_rows_handler()
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.add_track_to_header( self.model.signal_add_track_to_header_handler(
TrackAndPlaylist(playlist_id=self.model.playlist_id, track_id=prd.track_id) TrackAndPlaylist(playlist_id=self.model.playlist_id, track_id=prd.track_id)
) )