Clean up data structures in musicmuster.py

Replace self.playlists and self.selection with self.current and a new
Current() class
This commit is contained in:
Keith Edmunds 2024-12-28 17:16:19 +00:00
parent 4bff1a8b59
commit 712c965095
4 changed files with 55 additions and 66 deletions

View File

@ -93,13 +93,6 @@ class MusicMusterSignals(QObject):
super().__init__()
@singleton
@dataclass
class Selection:
playlist_id: int = 0
rows: list[int] = field(default_factory=list)
class Tags(NamedTuple):
artist: str
title: str

View File

@ -49,7 +49,6 @@ import stackprinter # type: ignore
# App imports
from classes import (
MusicMusterSignals,
Selection,
TrackInfo,
)
from config import Config
@ -81,13 +80,17 @@ class DownloadCSV(QDialog):
self.ui.buttonBox.rejected.connect(self.reject)
@dataclass
class PlaylistData:
class Current:
base_model: PlaylistModel
proxy_model: PlaylistProxyModel
playlist_id: int = 0
selected_rows: list[int] = field(default_factory=list)
def __post_init__(self):
self.proxy_model.setSourceModel(self.base_model)
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_rows}>"
)
class PreviewManager:
@ -286,8 +289,7 @@ class Window(QMainWindow, Ui_MainWindow):
self.connect_signals_slots()
self.catch_return_key = False
self.importer: Optional[FileImporter] = None
self.selection = Selection()
self.playlists: dict[int, PlaylistData] = {}
self.current = Current()
if not Config.USE_INTERNAL_BROWSER:
webbrowser.register(
@ -325,7 +327,7 @@ class Window(QMainWindow, Ui_MainWindow):
)
def active_base_model(self) -> PlaylistModel:
return self.playlists[self.selection.playlist_id].base_model
return self.current.base_model
def active_tab(self) -> PlaylistTab:
return self.tabPlaylist.currentWidget()
@ -551,24 +553,21 @@ class Window(QMainWindow, Ui_MainWindow):
log.debug(f"create_playlist_tab({playlist=})")
# Create model and proxy model
self.playlists[playlist.id] = PlaylistData(
base_model=PlaylistModel(playlist.id), proxy_model=PlaylistProxyModel()
)
base_model = PlaylistModel(playlist.id)
proxy_model = PlaylistProxyModel()
proxy_model.setSourceModel(base_model)
# Create tab
playlist_tab = PlaylistTab(
musicmuster=self, model=self.playlists[playlist.id].proxy_model
)
playlist_tab = PlaylistTab(musicmuster=self, model=proxy_model)
idx = self.tabPlaylist.addTab(playlist_tab, playlist.name)
log.debug(f"create_playlist_tab() returned: {idx=}")
return idx
def debug(self):
"""Invoke debugger"""
visible_playlist_id = self.selection.playlist_id
print(f"Active playlist id={visible_playlist_id}")
import ipdb # type: ignore
ipdb.set_trace()
@ -579,7 +578,7 @@ class Window(QMainWindow, Ui_MainWindow):
"""
with db.Session() as session:
playlist_id = self.selection.playlist_id
playlist_id = self.current.playlist_id
playlist = session.get(Playlists, playlist_id)
if playlist:
if helpers.ask_yes_no(
@ -655,7 +654,7 @@ class Window(QMainWindow, Ui_MainWindow):
track_sequence.current = None
# Tell playlist previous track has finished
self.active_base_model().previous_track_ended()
self.current.base_model.previous_track_ended()
# Reset clocks
self.frame_fade.setStyleSheet("")
@ -677,7 +676,7 @@ class Window(QMainWindow, Ui_MainWindow):
def export_playlist_tab(self) -> None:
"""Export the current playlist to an m3u file"""
playlist_id = self.selection.playlist_id
playlist_id = self.current.playlist_id
with db.Session() as session:
# Get output filename
@ -726,7 +725,7 @@ class Window(QMainWindow, Ui_MainWindow):
if self.hide_played_tracks:
self.hide_played_tracks = False
self.active_base_model().hide_played_tracks(False)
self.current.base_model.hide_played_tracks(False)
self.btnHidePlayed.setText("Hide played")
else:
self.hide_played_tracks = True
@ -734,7 +733,7 @@ class Window(QMainWindow, Ui_MainWindow):
if Config.HIDE_PLAYED_MODE == Config.HIDE_PLAYED_MODE_SECTIONS:
self.active_tab().hide_played_sections()
else:
self.active_base_model().hide_played_tracks(True)
self.current.base_model.hide_played_tracks(True)
# Reset row heights
self.active_tab().resize_rows()
@ -747,8 +746,8 @@ class Window(QMainWindow, Ui_MainWindow):
# We need to keep a reference to the FileImporter else it will be
# garbage collected while import threads are still running
self.importer = FileImporter(
self.active_base_model(),
self.selection.rows[0],
self.current.base_model,
self.current.selected_rows[0],
)
self.importer.do_import()
@ -762,24 +761,24 @@ class Window(QMainWindow, Ui_MainWindow):
dlg.resize(500, 100)
ok = dlg.exec()
if ok:
self.active_base_model().insert_row(
proposed_row_number=self.selection.rows[0],
self.current.base_model.insert_row(
proposed_row_number=self.current.selected_rows[0],
note=dlg.textValue(),
)
def insert_track(self) -> None:
"""Show dialog box to select and add track from database"""
if self.selection.rows:
new_row_number = self.selection.rows[0]
if self.current.selected_rows:
new_row_number = self.current.selected_rows[0]
else:
new_row_number = self.active_base_model().rowCount()
new_row_number = self.current.base_model.rowCount()
with db.Session() as session:
dlg = TrackSelectDialog(
parent=self,
session=session,
new_row_number=new_row_number,
base_model=self.active_base_model(),
base_model=self.current.base_model,
)
dlg.exec()
session.commit()
@ -836,8 +835,8 @@ class Window(QMainWindow, Ui_MainWindow):
# Save the selected PlaylistRows items ready for a later
# paste
self.move_source_rows = self.selection.rows
self.move_source_model = self.active_base_model()
self.move_source_rows = self.current.selected_rows
self.move_source_model = self.current.base_model
log.debug(
f"mark_rows_for_moving(): {self.move_source_rows=} {self.move_source_model=}"
@ -850,7 +849,7 @@ class Window(QMainWindow, Ui_MainWindow):
# Identify destination playlist
playlists = []
source_playlist_id = self.selection.playlist_id
source_playlist_id = self.current.playlist_id
with db.Session() as session:
for playlist in Playlists.get_all(session):
@ -873,7 +872,7 @@ class Window(QMainWindow, Ui_MainWindow):
to_row = 0
# Move rows
self.active_base_model().move_rows_between_playlists(
self.current.base_model.move_rows_between_playlists(
row_numbers, to_row, to_playlist_id
)
@ -892,7 +891,7 @@ class Window(QMainWindow, Ui_MainWindow):
Move selected rows to another playlist
"""
selected_rows = self.selection.rows
selected_rows = self.current.selected_rows
if not selected_rows:
return
@ -903,7 +902,7 @@ class Window(QMainWindow, Ui_MainWindow):
Move unplayed rows to another playlist
"""
unplayed_rows = self.active_base_model().get_unplayed_rows()
unplayed_rows = self.current.base_model.get_unplayed_rows()
if not unplayed_rows:
return
# We can get a race condition as selected rows change while
@ -986,12 +985,12 @@ class Window(QMainWindow, Ui_MainWindow):
if not self.move_source_rows or not self.move_source_model:
return
to_playlist_model = self.active_base_model()
selected_rows = self.selection.rows
to_playlist_model = self.current.base_model
selected_rows = self.current.selected_rows
if selected_rows:
destination_row = selected_rows[0]
else:
destination_row = self.active_base_model().rowCount()
destination_row = self.current.base_model.rowCount()
# If we move a row to immediately under the current track, make
# that moved row the next track
@ -1176,8 +1175,8 @@ class Window(QMainWindow, Ui_MainWindow):
track.intro = intro
session.commit()
self.preview_manager.set_intro(intro)
self.active_base_model().refresh_row(session, row_number)
self.active_base_model().invalidate_row(row_number)
self.current.base_model.refresh_row(session, row_number)
self.current.base_model.invalidate_row(row_number)
def preview_start(self) -> None:
"""Restart preview"""
@ -1206,7 +1205,7 @@ class Window(QMainWindow, Ui_MainWindow):
"""
with db.Session() as session:
playlist_id = self.selection.playlist_id
playlist_id = self.current.playlist_id
playlist = session.get(Playlists, playlist_id)
if playlist:
new_name = self.solicit_playlist_name(session, playlist.name)
@ -1320,7 +1319,7 @@ class Window(QMainWindow, Ui_MainWindow):
self, "Duplicate template", "Template name already in use"
)
Playlists.save_as_template(
session, self.selection.playlist_id, template_name
session, self.current.playlist_id, template_name
)
session.commit()
helpers.show_OK(self, "Template", "Template saved")
@ -1348,9 +1347,7 @@ class Window(QMainWindow, Ui_MainWindow):
Incremental search of playlist
"""
active_proxy_model = self.playlists[self.selection.playlist_id].proxy_model
active_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) -> Optional[RowAndTrack]:
"""
@ -1358,7 +1355,7 @@ class Window(QMainWindow, Ui_MainWindow):
next track. If no next track, return None.
"""
row_number = self.selection.rows[0]
row_number = self.current.selected_rows[0]
if row_number is None:
if track_sequence.next:
if track_sequence.next.track_id:
@ -1366,7 +1363,7 @@ class Window(QMainWindow, Ui_MainWindow):
if row_number is None:
return None
track_info = self.active_base_model().get_row_info(row_number)
track_info = self.current.base_model.get_row_info(row_number)
if track_info is None:
return None
@ -1449,7 +1446,7 @@ class Window(QMainWindow, Ui_MainWindow):
return
# Switch to correct tab
if playlist_id != self.selection.playlist_id:
if playlist_id != self.current.playlist_id:
for idx in range(self.tabPlaylist.count()):
if self.tabPlaylist.widget(idx).playlist_id == playlist_id:
self.tabPlaylist.setCurrentIndex(idx)

View File

@ -1671,7 +1671,7 @@ class PlaylistProxyModel(QSortFilterProxyModel):
self.setFilterKeyColumn(-1)
def __repr__(self) -> str:
return f"<PlaylistProxyModel: sourceModel={self.sourceModel}>"
return f"<PlaylistProxyModel: sourceModel={self.sourceModel()}>"
def filterAcceptsRow(self, source_row: int, source_parent: QModelIndex) -> bool:
"""

View File

@ -37,7 +37,7 @@ import line_profiler
# App imports
from audacity_controller import AudacityController
from classes import ApplicationError, Col, MusicMusterSignals, Selection, TrackInfo
from classes import ApplicationError, Col, MusicMusterSignals, TrackInfo
from config import Config
from dialogs import TrackSelectDialog
from helpers import (
@ -295,9 +295,8 @@ class PlaylistTab(QTableView):
super().__init__()
# Save passed settings
self.musicmuster = (
musicmuster # TODO: do we need to keep a reference to musicmuster?
)
self.musicmuster = musicmuster
self.playlist_id = model.sourceModel().playlist_id
# Set up widget
@ -329,9 +328,6 @@ class PlaylistTab(QTableView):
self.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection)
self.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows)
# Singleton object to store selection
self.selection = Selection()
# Set up for Audacity
try:
self.ac: Optional[AudacityController] = AudacityController()
@ -487,7 +483,7 @@ class PlaylistTab(QTableView):
"""
selected_rows = self.get_selected_rows()
self.selection.rows = selected_rows
self.musicmuster.current.selected_rows = selected_rows
# If no rows are selected, we have nothing to do
if len(selected_rows) == 0:
@ -1115,8 +1111,11 @@ class PlaylistTab(QTableView):
Called when tab gets focus
"""
self.selection.playlist_id = self.playlist_id
self.selection.rows = self.get_selected_rows()
# Update musicmuster
self.musicmuster.current.playlist_id = self.playlist_id
self.musicmuster.current.selected_rows = self.get_selected_rows()
self.musicmuster.current.base_model = self.get_base_model()
self.musicmuster.current.proxy_model = self.model()
self.resize_rows()