Compare commits

..

No commits in common. "712c965095373d878f28dd6c6e02df63614562d8" and "7ce07c1cc7b3783675fb9bb86617525ab429d209" have entirely different histories.

4 changed files with 81 additions and 58 deletions

View File

@ -93,6 +93,13 @@ 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,6 +49,7 @@ import stackprinter # type: ignore
# App imports
from classes import (
MusicMusterSignals,
Selection,
TrackInfo,
)
from config import Config
@ -80,17 +81,13 @@ class DownloadCSV(QDialog):
self.ui.buttonBox.rejected.connect(self.reject)
class Current:
@dataclass
class PlaylistData:
base_model: PlaylistModel
proxy_model: PlaylistProxyModel
playlist_id: int = 0
selected_rows: 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_rows}>"
)
def __post_init__(self):
self.proxy_model.setSourceModel(self.base_model)
class PreviewManager:
@ -289,7 +286,8 @@ class Window(QMainWindow, Ui_MainWindow):
self.connect_signals_slots()
self.catch_return_key = False
self.importer: Optional[FileImporter] = None
self.current = Current()
self.selection = Selection()
self.playlists: dict[int, PlaylistData] = {}
if not Config.USE_INTERNAL_BROWSER:
webbrowser.register(
@ -327,7 +325,7 @@ class Window(QMainWindow, Ui_MainWindow):
)
def active_base_model(self) -> PlaylistModel:
return self.current.base_model
return self.playlists[self.selection.playlist_id].base_model
def active_tab(self) -> PlaylistTab:
return self.tabPlaylist.currentWidget()
@ -553,21 +551,24 @@ class Window(QMainWindow, Ui_MainWindow):
log.debug(f"create_playlist_tab({playlist=})")
# Create model and proxy model
base_model = PlaylistModel(playlist.id)
proxy_model = PlaylistProxyModel()
proxy_model.setSourceModel(base_model)
self.playlists[playlist.id] = PlaylistData(
base_model=PlaylistModel(playlist.id), proxy_model=PlaylistProxyModel()
)
# Create tab
playlist_tab = PlaylistTab(musicmuster=self, model=proxy_model)
playlist_tab = PlaylistTab(
musicmuster=self, model=self.playlists[playlist.id].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.active_tab().playlist_id
print(f"Active playlist id={visible_playlist_id}")
import ipdb # type: ignore
ipdb.set_trace()
@ -578,7 +579,7 @@ class Window(QMainWindow, Ui_MainWindow):
"""
with db.Session() as session:
playlist_id = self.current.playlist_id
playlist_id = self.active_tab().playlist_id
playlist = session.get(Playlists, playlist_id)
if playlist:
if helpers.ask_yes_no(
@ -654,7 +655,7 @@ class Window(QMainWindow, Ui_MainWindow):
track_sequence.current = None
# Tell playlist previous track has finished
self.current.base_model.previous_track_ended()
self.active_tab().previous_track_ended()
# Reset clocks
self.frame_fade.setStyleSheet("")
@ -676,7 +677,10 @@ class Window(QMainWindow, Ui_MainWindow):
def export_playlist_tab(self) -> None:
"""Export the current playlist to an m3u file"""
playlist_id = self.current.playlist_id
if not self.active_tab():
return
playlist_id = self.active_tab().playlist_id
with db.Session() as session:
# Get output filename
@ -725,7 +729,7 @@ class Window(QMainWindow, Ui_MainWindow):
if self.hide_played_tracks:
self.hide_played_tracks = False
self.current.base_model.hide_played_tracks(False)
self.active_base_model().hide_played_tracks(False)
self.btnHidePlayed.setText("Hide played")
else:
self.hide_played_tracks = True
@ -733,7 +737,7 @@ class Window(QMainWindow, Ui_MainWindow):
if Config.HIDE_PLAYED_MODE == Config.HIDE_PLAYED_MODE_SECTIONS:
self.active_tab().hide_played_sections()
else:
self.current.base_model.hide_played_tracks(True)
self.active_base_model().hide_played_tracks(True)
# Reset row heights
self.active_tab().resize_rows()
@ -743,11 +747,11 @@ class Window(QMainWindow, Ui_MainWindow):
Pass import files call to file_importer module
"""
# We need to keep a reference to the FileImporter else it will be
# We need to keep a referent to the FileImporter else it will be
# garbage collected while import threads are still running
self.importer = FileImporter(
self.current.base_model,
self.current.selected_rows[0],
self.active_base_model(),
self.active_tab().source_model_selected_row_number(),
)
self.importer.do_import()
@ -761,24 +765,24 @@ class Window(QMainWindow, Ui_MainWindow):
dlg.resize(500, 100)
ok = dlg.exec()
if ok:
self.current.base_model.insert_row(
proposed_row_number=self.current.selected_rows[0],
self.active_base_model().insert_row(
proposed_row_number=self.active_tab().source_model_selected_row_number(),
note=dlg.textValue(),
)
def insert_track(self) -> None:
"""Show dialog box to select and add track from database"""
if self.current.selected_rows:
new_row_number = self.current.selected_rows[0]
else:
new_row_number = self.current.base_model.rowCount()
new_row_number = (
self.active_tab().source_model_selected_row_number()
or self.active_base_model().rowCount()
)
with db.Session() as session:
dlg = TrackSelectDialog(
parent=self,
session=session,
new_row_number=new_row_number,
base_model=self.current.base_model,
base_model=self.active_base_model(),
)
dlg.exec()
session.commit()
@ -835,8 +839,8 @@ class Window(QMainWindow, Ui_MainWindow):
# Save the selected PlaylistRows items ready for a later
# paste
self.move_source_rows = self.current.selected_rows
self.move_source_model = self.current.base_model
self.move_source_rows = self.active_tab().get_selected_rows()
self.move_source_model = self.active_base_model()
log.debug(
f"mark_rows_for_moving(): {self.move_source_rows=} {self.move_source_model=}"
@ -849,7 +853,8 @@ class Window(QMainWindow, Ui_MainWindow):
# Identify destination playlist
playlists = []
source_playlist_id = self.current.playlist_id
visible_tab = self.active_tab()
source_playlist_id = visible_tab.playlist_id
with db.Session() as session:
for playlist in Playlists.get_all(session):
@ -872,7 +877,7 @@ class Window(QMainWindow, Ui_MainWindow):
to_row = 0
# Move rows
self.current.base_model.move_rows_between_playlists(
self.active_base_model().move_rows_between_playlists(
row_numbers, to_row, to_playlist_id
)
@ -891,7 +896,7 @@ class Window(QMainWindow, Ui_MainWindow):
Move selected rows to another playlist
"""
selected_rows = self.current.selected_rows
selected_rows = self.active_tab().get_selected_rows()
if not selected_rows:
return
@ -902,7 +907,7 @@ class Window(QMainWindow, Ui_MainWindow):
Move unplayed rows to another playlist
"""
unplayed_rows = self.current.base_model.get_unplayed_rows()
unplayed_rows = self.active_base_model().get_unplayed_rows()
if not unplayed_rows:
return
# We can get a race condition as selected rows change while
@ -985,12 +990,12 @@ class Window(QMainWindow, Ui_MainWindow):
if not self.move_source_rows or not self.move_source_model:
return
to_playlist_model = self.current.base_model
selected_rows = self.current.selected_rows
to_playlist_model = self.active_base_model()
selected_rows = self.active_tab().get_selected_rows()
if selected_rows:
destination_row = selected_rows[0]
else:
destination_row = self.current.base_model.rowCount()
destination_row = self.active_base_model().rowCount()
# If we move a row to immediately under the current track, make
# that moved row the next track
@ -1175,8 +1180,8 @@ class Window(QMainWindow, Ui_MainWindow):
track.intro = intro
session.commit()
self.preview_manager.set_intro(intro)
self.current.base_model.refresh_row(session, row_number)
self.current.base_model.invalidate_row(row_number)
self.active_base_model().refresh_row(session, row_number)
self.active_base_model().invalidate_row(row_number)
def preview_start(self) -> None:
"""Restart preview"""
@ -1205,7 +1210,7 @@ class Window(QMainWindow, Ui_MainWindow):
"""
with db.Session() as session:
playlist_id = self.current.playlist_id
playlist_id = self.active_tab().playlist_id
playlist = session.get(Playlists, playlist_id)
if playlist:
new_name = self.solicit_playlist_name(session, playlist.name)
@ -1319,7 +1324,7 @@ class Window(QMainWindow, Ui_MainWindow):
self, "Duplicate template", "Template name already in use"
)
Playlists.save_as_template(
session, self.current.playlist_id, template_name
session, self.active_tab().playlist_id, template_name
)
session.commit()
helpers.show_OK(self, "Template", "Template saved")
@ -1347,7 +1352,9 @@ class Window(QMainWindow, Ui_MainWindow):
Incremental search of playlist
"""
self.current.proxy_model.set_incremental_search(self.txtSearch.text())
active_proxy_model = self.playlists[self.selection.playlist_id].proxy_model
active_proxy_model.set_incremental_search(self.txtSearch.text())
def selected_or_next_track_info(self) -> Optional[RowAndTrack]:
"""
@ -1355,7 +1362,7 @@ class Window(QMainWindow, Ui_MainWindow):
next track. If no next track, return None.
"""
row_number = self.current.selected_rows[0]
row_number = self.active_tab().source_model_selected_row_number()
if row_number is None:
if track_sequence.next:
if track_sequence.next.track_id:
@ -1363,7 +1370,7 @@ class Window(QMainWindow, Ui_MainWindow):
if row_number is None:
return None
track_info = self.current.base_model.get_row_info(row_number)
track_info = self.active_base_model().get_row_info(row_number)
if track_info is None:
return None
@ -1446,7 +1453,7 @@ class Window(QMainWindow, Ui_MainWindow):
return
# Switch to correct tab
if playlist_id != self.current.playlist_id:
if playlist_id != self.active_tab().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, TrackInfo
from classes import ApplicationError, Col, MusicMusterSignals, Selection, TrackInfo
from config import Config
from dialogs import TrackSelectDialog
from helpers import (
@ -295,8 +295,9 @@ class PlaylistTab(QTableView):
super().__init__()
# Save passed settings
self.musicmuster = musicmuster
self.musicmuster = (
musicmuster # TODO: do we need to keep a reference to musicmuster?
)
self.playlist_id = model.sourceModel().playlist_id
# Set up widget
@ -328,6 +329,9 @@ 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()
@ -483,7 +487,7 @@ class PlaylistTab(QTableView):
"""
selected_rows = self.get_selected_rows()
self.musicmuster.current.selected_rows = selected_rows
self.selection.rows = selected_rows
# If no rows are selected, we have nothing to do
if len(selected_rows) == 0:
@ -926,6 +930,14 @@ class PlaylistTab(QTableView):
except ApplicationError as e:
show_warning(self.musicmuster, "Audacity error", str(e))
def previous_track_ended(self) -> None:
"""
Called when track ends
"""
# Let the model know
self.get_base_model().previous_track_ended()
def _remove_comments(self) -> None:
"""
Remove comments from selected rows
@ -1037,7 +1049,7 @@ class PlaylistTab(QTableView):
def _selected_row_indexes(self) -> List[QModelIndex]:
"""
Return a list of indexes of column 0 of selected rows
Return a list of indexes of column 1 of selected rows
"""
sm = self.selectionModel()
@ -1111,11 +1123,8 @@ class PlaylistTab(QTableView):
Called when tab gets focus
"""
# 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.selection.playlist_id = self.playlist_id
self.selection.rows = self.get_selected_rows()
self.resize_rows()