|
|
|
@ -38,7 +38,7 @@ from PyQt5.QtWidgets import (
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
from config import Config
|
|
|
|
from config import Config
|
|
|
|
from dbconfig import Session
|
|
|
|
from dbconfig import Session, scoped_session
|
|
|
|
from helpers import (
|
|
|
|
from helpers import (
|
|
|
|
ask_yes_no,
|
|
|
|
ask_yes_no,
|
|
|
|
file_is_readable,
|
|
|
|
file_is_readable,
|
|
|
|
@ -126,7 +126,7 @@ class PlaylistTab(QTableWidget):
|
|
|
|
ROW_DURATION = Qt.UserRole + 2
|
|
|
|
ROW_DURATION = Qt.UserRole + 2
|
|
|
|
PLAYLISTROW_ID = Qt.UserRole + 3
|
|
|
|
PLAYLISTROW_ID = Qt.UserRole + 3
|
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, musicmuster: QMainWindow, session: Session,
|
|
|
|
def __init__(self, musicmuster: QMainWindow, session: scoped_session,
|
|
|
|
playlist_id: int, *args, **kwargs) -> None:
|
|
|
|
playlist_id: int, *args, **kwargs) -> None:
|
|
|
|
super().__init__(*args, **kwargs)
|
|
|
|
super().__init__(*args, **kwargs)
|
|
|
|
self.musicmuster = musicmuster
|
|
|
|
self.musicmuster = musicmuster
|
|
|
|
@ -554,7 +554,7 @@ class PlaylistTab(QTableWidget):
|
|
|
|
|
|
|
|
|
|
|
|
return [self._get_playlistrow_id(a) for a in self._get_selected_rows()]
|
|
|
|
return [self._get_playlistrow_id(a) for a in self._get_selected_rows()]
|
|
|
|
|
|
|
|
|
|
|
|
def get_selected_playlistrows(self, session: Session) -> Optional[List]:
|
|
|
|
def get_selected_playlistrows(self, session: scoped_session) -> Optional[List]:
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
Return a list of PlaylistRows of the selected rows
|
|
|
|
Return a list of PlaylistRows of the selected rows
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
@ -562,7 +562,7 @@ class PlaylistTab(QTableWidget):
|
|
|
|
plr_ids = self.get_selected_playlistrow_ids()
|
|
|
|
plr_ids = self.get_selected_playlistrow_ids()
|
|
|
|
return [session.get(PlaylistRows, a) for a in plr_ids]
|
|
|
|
return [session.get(PlaylistRows, a) for a in plr_ids]
|
|
|
|
|
|
|
|
|
|
|
|
def insert_header(self, session: Session, note: str,
|
|
|
|
def insert_header(self, session: scoped_session, note: str,
|
|
|
|
repaint: bool = True) -> None:
|
|
|
|
repaint: bool = True) -> None:
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
Insert section header into playlist tab.
|
|
|
|
Insert section header into playlist tab.
|
|
|
|
@ -579,7 +579,7 @@ class PlaylistTab(QTableWidget):
|
|
|
|
self.insert_row(session, plr, repaint)
|
|
|
|
self.insert_row(session, plr, repaint)
|
|
|
|
self.save_playlist(session)
|
|
|
|
self.save_playlist(session)
|
|
|
|
|
|
|
|
|
|
|
|
def insert_row(self, session: Session, plr: PlaylistRows,
|
|
|
|
def insert_row(self, session: scoped_session, plr: PlaylistRows,
|
|
|
|
repaint: bool = True) -> None:
|
|
|
|
repaint: bool = True) -> None:
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
Insert passed playlist row (plr) into playlist tab.
|
|
|
|
Insert passed playlist row (plr) into playlist tab.
|
|
|
|
@ -668,7 +668,7 @@ class PlaylistTab(QTableWidget):
|
|
|
|
if repaint:
|
|
|
|
if repaint:
|
|
|
|
self.update_display(session)
|
|
|
|
self.update_display(session)
|
|
|
|
|
|
|
|
|
|
|
|
def insert_track(self, session: Session, track: Tracks,
|
|
|
|
def insert_track(self, session: scoped_session, track: Tracks,
|
|
|
|
note: str = None, repaint: bool = True) -> None:
|
|
|
|
note: str = None, repaint: bool = True) -> None:
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
Insert track into playlist tab.
|
|
|
|
Insert track into playlist tab.
|
|
|
|
@ -705,7 +705,7 @@ class PlaylistTab(QTableWidget):
|
|
|
|
# Let display update, then save playlist
|
|
|
|
# Let display update, then save playlist
|
|
|
|
QTimer.singleShot(0, lambda: self.save_playlist(session))
|
|
|
|
QTimer.singleShot(0, lambda: self.save_playlist(session))
|
|
|
|
|
|
|
|
|
|
|
|
def play_started(self, session: Session) -> None:
|
|
|
|
def play_started(self, session: scoped_session) -> None:
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
Notification from musicmuster that track has started playing.
|
|
|
|
Notification from musicmuster that track has started playing.
|
|
|
|
|
|
|
|
|
|
|
|
@ -718,7 +718,15 @@ class PlaylistTab(QTableWidget):
|
|
|
|
- Update display
|
|
|
|
- Update display
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
search_from = self._get_current_track_row_number() + 1
|
|
|
|
current_row = self._get_current_track_row_number()
|
|
|
|
|
|
|
|
if not current_row:
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
search_from = current_row + 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Mark current row as played
|
|
|
|
|
|
|
|
self._set_played_row(session, current_row)
|
|
|
|
|
|
|
|
|
|
|
|
next_row = self._find_next_track_row(session, search_from)
|
|
|
|
next_row = self._find_next_track_row(session, search_from)
|
|
|
|
if next_row:
|
|
|
|
if next_row:
|
|
|
|
self._set_next(session, next_row)
|
|
|
|
self._set_next(session, next_row)
|
|
|
|
@ -726,7 +734,7 @@ class PlaylistTab(QTableWidget):
|
|
|
|
# Update display
|
|
|
|
# Update display
|
|
|
|
self.update_display(session)
|
|
|
|
self.update_display(session)
|
|
|
|
|
|
|
|
|
|
|
|
def populate_display(self, session: Session, playlist_id: int,
|
|
|
|
def populate_display(self, session: scoped_session, playlist_id: int,
|
|
|
|
scroll_to_top: bool = True) -> None:
|
|
|
|
scroll_to_top: bool = True) -> None:
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
Populate display from the associated playlist ID
|
|
|
|
Populate display from the associated playlist ID
|
|
|
|
@ -740,6 +748,9 @@ class PlaylistTab(QTableWidget):
|
|
|
|
|
|
|
|
|
|
|
|
# Add the rows
|
|
|
|
# Add the rows
|
|
|
|
playlist = session.get(Playlists, playlist_id)
|
|
|
|
playlist = session.get(Playlists, playlist_id)
|
|
|
|
|
|
|
|
if not playlist:
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
for plr in playlist.rows:
|
|
|
|
for plr in playlist.rows:
|
|
|
|
self.insert_row(session, plr, repaint=False)
|
|
|
|
self.insert_row(session, plr, repaint=False)
|
|
|
|
|
|
|
|
|
|
|
|
@ -775,7 +786,7 @@ class PlaylistTab(QTableWidget):
|
|
|
|
# Reset drag mode
|
|
|
|
# Reset drag mode
|
|
|
|
self.setDragEnabled(False)
|
|
|
|
self.setDragEnabled(False)
|
|
|
|
|
|
|
|
|
|
|
|
def save_playlist(self, session: Session) -> None:
|
|
|
|
def save_playlist(self, session: scoped_session) -> None:
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
Get the PlaylistRow objects for each row in the display. Correct
|
|
|
|
Get the PlaylistRow objects for each row in the display. Correct
|
|
|
|
the row_number and playlist_id if necessary. Remove any row
|
|
|
|
the row_number and playlist_id if necessary. Remove any row
|
|
|
|
@ -941,7 +952,7 @@ class PlaylistTab(QTableWidget):
|
|
|
|
with Session() as session:
|
|
|
|
with Session() as session:
|
|
|
|
self.update_display(session)
|
|
|
|
self.update_display(session)
|
|
|
|
|
|
|
|
|
|
|
|
def update_display(self, session: Session) -> None:
|
|
|
|
def update_display(self, session: scoped_session) -> None:
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
Set row colours, fonts, etc
|
|
|
|
Set row colours, fonts, etc
|
|
|
|
|
|
|
|
|
|
|
|
@ -1263,7 +1274,7 @@ class PlaylistTab(QTableWidget):
|
|
|
|
return (index.row() + 1 if self._is_below(event.pos(), index)
|
|
|
|
return (index.row() + 1 if self._is_below(event.pos(), index)
|
|
|
|
else index.row())
|
|
|
|
else index.row())
|
|
|
|
|
|
|
|
|
|
|
|
def _find_next_track_row(self, session: Session,
|
|
|
|
def _find_next_track_row(self, session: scoped_session,
|
|
|
|
starting_row: int = None) -> Optional[int]:
|
|
|
|
starting_row: int = None) -> Optional[int]:
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
Find next track to play. If a starting row is given, start there;
|
|
|
|
Find next track to play. If a starting row is given, start there;
|
|
|
|
@ -1344,7 +1355,7 @@ class PlaylistTab(QTableWidget):
|
|
|
|
|
|
|
|
|
|
|
|
return playlistrow_id
|
|
|
|
return playlistrow_id
|
|
|
|
|
|
|
|
|
|
|
|
def _get_playlistrow_object(self, session: Session, row: int) -> int:
|
|
|
|
def _get_playlistrow_object(self, session: scoped_session, row: int) -> int:
|
|
|
|
"""Return the playlistrow object associated with this row"""
|
|
|
|
"""Return the playlistrow object associated with this row"""
|
|
|
|
|
|
|
|
|
|
|
|
playlistrow_id = (self.item(row, USERDATA).data(self.PLAYLISTROW_ID))
|
|
|
|
playlistrow_id = (self.item(row, USERDATA).data(self.PLAYLISTROW_ID))
|
|
|
|
@ -1515,7 +1526,7 @@ class PlaylistTab(QTableWidget):
|
|
|
|
)
|
|
|
|
)
|
|
|
|
raise AttributeError(f"Multiple '{metadata}' metadata {matches}")
|
|
|
|
raise AttributeError(f"Multiple '{metadata}' metadata {matches}")
|
|
|
|
|
|
|
|
|
|
|
|
def _move_row(self, session: Session, plr: PlaylistRows,
|
|
|
|
def _move_row(self, session: scoped_session, plr: PlaylistRows,
|
|
|
|
new_row_number: int) -> None:
|
|
|
|
new_row_number: int) -> None:
|
|
|
|
"""Move playlist row to new_row_number using parent copy/paste"""
|
|
|
|
"""Move playlist row to new_row_number using parent copy/paste"""
|
|
|
|
|
|
|
|
|
|
|
|
@ -1726,7 +1737,7 @@ class PlaylistTab(QTableWidget):
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
self.musicmuster.lblSumPlaytime.setText("")
|
|
|
|
self.musicmuster.lblSumPlaytime.setText("")
|
|
|
|
|
|
|
|
|
|
|
|
def _set_column_widths(self, session: Session) -> None:
|
|
|
|
def _set_column_widths(self, session: scoped_session) -> None:
|
|
|
|
"""Column widths from settings"""
|
|
|
|
"""Column widths from settings"""
|
|
|
|
|
|
|
|
|
|
|
|
for column_name, data in columns.items():
|
|
|
|
for column_name, data in columns.items():
|
|
|
|
@ -1742,7 +1753,7 @@ class PlaylistTab(QTableWidget):
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
self.setColumnWidth(idx, Config.DEFAULT_COLUMN_WIDTH)
|
|
|
|
self.setColumnWidth(idx, Config.DEFAULT_COLUMN_WIDTH)
|
|
|
|
|
|
|
|
|
|
|
|
def _set_next(self, session: Session, row_number: int) -> None:
|
|
|
|
def _set_next(self, session: scoped_session, row_number: int) -> None:
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
Set passed row as next playlist row to play.
|
|
|
|
Set passed row as next playlist row to play.
|
|
|
|
|
|
|
|
|
|
|
|
@ -1777,10 +1788,13 @@ class PlaylistTab(QTableWidget):
|
|
|
|
self.clear_selection()
|
|
|
|
self.clear_selection()
|
|
|
|
self.update_display(session)
|
|
|
|
self.update_display(session)
|
|
|
|
|
|
|
|
|
|
|
|
def _set_played_row(self, session: Session, row: int) -> None:
|
|
|
|
def _set_played_row(self, session: scoped_session, row: int) -> None:
|
|
|
|
"""Mark this row as played"""
|
|
|
|
"""Mark this row as played"""
|
|
|
|
|
|
|
|
|
|
|
|
plr = session.get(PlaylistRows, self._get_playlistrow_id(row))
|
|
|
|
plr = session.get(PlaylistRows, self._get_playlistrow_id(row))
|
|
|
|
|
|
|
|
if not plr:
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
plr.played = True
|
|
|
|
plr.played = True
|
|
|
|
session.commit()
|
|
|
|
session.commit()
|
|
|
|
|
|
|
|
|
|
|
|
|