Compare commits

..

2 Commits

Author SHA1 Message Date
Keith Edmunds
caf78df17f Differentiate between playlist tabs and db objects. Fixes #17 2021-06-06 16:40:36 +01:00
Keith Edmunds
20bd178cf1 Differentiate between playlist tabs and db objects. Fixes #17 2021-06-06 16:40:10 +01:00
2 changed files with 63 additions and 69 deletions

View File

@ -27,7 +27,7 @@ import music
from config import Config from config import Config
from model import (Notes, Playdates, Playlists, PlaylistTracks, from model import (Notes, Playdates, Playlists, PlaylistTracks,
Session, Settings, Tracks) Session, Settings, Tracks)
from playlists import Playlist from playlists import PlaylistTab
from songdb import create_track_from_file from songdb import create_track_from_file
from ui.dlg_search_database_ui import Ui_Dialog from ui.dlg_search_database_ui import Ui_Dialog
from ui.dlg_SelectPlaylist_ui import Ui_dlgSelectPlaylist from ui.dlg_SelectPlaylist_ui import Ui_dlgSelectPlaylist
@ -47,9 +47,9 @@ class Window(QMainWindow, Ui_MainWindow):
self.music = music.Music() self.music = music.Music()
self.current_track = None self.current_track = None
self.current_track_playlist = None self.current_track_playlist_tab = None
self.next_track = None self.next_track = None
self.next_track_playlist = None self.next_track_playlist_tab = None
self.previous_track = None self.previous_track = None
self.previous_track_position = None self.previous_track_position = None
self.spnVolume.setValue(Config.VOLUME_VLC_DEFAULT) self.spnVolume.setValue(Config.VOLUME_VLC_DEFAULT)
@ -57,7 +57,7 @@ class Window(QMainWindow, Ui_MainWindow):
self.menuTest.menuAction().setVisible(Config.TESTMODE) self.menuTest.menuAction().setVisible(Config.TESTMODE)
self.set_main_window_size() self.set_main_window_size()
self.visible_playlist = self.tabPlaylist.currentWidget self.visible_playlist_tab = self.tabPlaylist.currentWidget
self.load_last_playlists() self.load_last_playlists()
self.enable_play_next_controls() self.enable_play_next_controls()
@ -77,7 +77,7 @@ class Window(QMainWindow, Ui_MainWindow):
# Add to playlist on screen # Add to playlist on screen
# If we don't specify "repaint=False", playlist will # If we don't specify "repaint=False", playlist will
# also be saved to database # also be saved to database
self.visible_playlist().insert_track(session, track) self.visible_playlist_tab().insert_track(session, track)
def set_main_window_size(self): def set_main_window_size(self):
"Set size of window from database" "Set size of window from database"
@ -94,8 +94,8 @@ class Window(QMainWindow, Ui_MainWindow):
self.setGeometry(x, y, width, height) self.setGeometry(x, y, width, height)
def clear_selection(self): def clear_selection(self):
if self.visible_playlist(): if self.visible_playlist_tab():
self.visible_playlist().clearSelection() self.visible_playlist_tab().clearSelection()
def closeEvent(self, event): def closeEvent(self, event):
"Don't allow window to close when a track is playing" "Don't allow window to close when a track is playing"
@ -129,8 +129,8 @@ class Window(QMainWindow, Ui_MainWindow):
def connect_signals_slots(self): def connect_signals_slots(self):
self.actionAdd_file.triggered.connect(self.add_file) self.actionAdd_file.triggered.connect(self.add_file)
self.action_Clear_selection.triggered.connect(self.clear_selection) self.action_Clear_selection.triggered.connect(self.clear_selection)
self.actionClosePlaylist.triggered.connect(self.close_playlist) self.actionClosePlaylist.triggered.connect(self.close_playlist_tab)
self.actionExport_playlist.triggered.connect(self.export_playlist) self.actionExport_playlist.triggered.connect(self.export_playlist_tab)
self.actionFade.triggered.connect(self.fade) self.actionFade.triggered.connect(self.fade)
self.actionMoveSelected.triggered.connect(self.move_selected) self.actionMoveSelected.triggered.connect(self.move_selected)
self.actionNewPlaylist.triggered.connect(self.create_playlist) self.actionNewPlaylist.triggered.connect(self.create_playlist)
@ -155,7 +155,6 @@ class Window(QMainWindow, Ui_MainWindow):
self.btnSongInfo.clicked.connect(self.song_info_search) self.btnSongInfo.clicked.connect(self.song_info_search)
self.btnStop.clicked.connect(self.stop) self.btnStop.clicked.connect(self.stop)
self.spnVolume.valueChanged.connect(self.change_volume) self.spnVolume.valueChanged.connect(self.change_volume)
self.tabPlaylist.currentChanged.connect(self.tab_change)
self.timer.timeout.connect(self.tick) self.timer.timeout.connect(self.tick)
@ -169,8 +168,8 @@ class Window(QMainWindow, Ui_MainWindow):
ok = dlg.exec() ok = dlg.exec()
if ok: if ok:
with Session() as session: with Session() as session:
playlist = Playlists.new(session, dlg.textValue()) playlist_db = Playlists.new(session, dlg.textValue())
self.load_playlist(session, playlist) self.load_playlist(session, playlist_db)
def change_volume(self, volume): def change_volume(self, volume):
"Change player maximum volume" "Change player maximum volume"
@ -179,10 +178,10 @@ class Window(QMainWindow, Ui_MainWindow):
self.music.set_volume(volume) self.music.set_volume(volume)
def close_playlist(self): def close_playlist_tab(self):
with Session() as session: with Session() as session:
playlist_db = session.query(Playlists).filter( playlist_db = session.query(Playlists).filter(
Playlists.id == self.visible_playlist().id).one() Playlists.id == self.visible_playlist_tab().id).one()
playlist_db.close(session) playlist_db.close(session)
index = self.tabPlaylist.currentIndex() index = self.tabPlaylist.currentIndex()
self.tabPlaylist.removeTab(index) self.tabPlaylist.removeTab(index)
@ -197,13 +196,13 @@ class Window(QMainWindow, Ui_MainWindow):
Return note. Return note.
""" """
row = self.visible_playlist().get_selected_row() row = self.visible_playlist_tab().get_selected_row()
if row is None: if row is None:
row = self.visible_playlist().rowCount() row = self.visible_playlist_tab().rowCount()
DEBUG(f"musicmuster.create_note(text={text}): row={row}") DEBUG(f"musicmuster.create_note(text={text}): row={row}")
note = Notes.add_note( note = Notes.add_note(
session, self.visible_playlist().id, row, text) session, self.visible_playlist_tab().id, row, text)
return note return note
@ -215,16 +214,16 @@ class Window(QMainWindow, Ui_MainWindow):
DEBUG("enable_play_next_controls()") DEBUG("enable_play_next_controls()")
self.actionPlay_next.setEnabled(True) self.actionPlay_next.setEnabled(True)
def export_playlist(self): def export_playlist_tab(self):
"Export the current playlist to an m3u file" "Export the current playlist to an m3u file"
if not self.visible_playlist(): if not self.visible_playlist_tab():
return return
# Get output filename # Get output filename
pathspec = QFileDialog.getSaveFileName( pathspec = QFileDialog.getSaveFileName(
self, 'Save Playlist', self, 'Save Playlist',
directory=f"{self.visible_playlist().name}.m3u", directory=f"{self.visible_playlist_tab().name}.m3u",
filter="M3U files (*.m3u);;All files (*.*)" filter="M3U files (*.m3u);;All files (*.*)"
) )
if not pathspec: if not pathspec:
@ -237,11 +236,12 @@ class Window(QMainWindow, Ui_MainWindow):
# Get playlist db object # Get playlist db object
with Session() as session: with Session() as session:
p = Playlists.get_playlist(session, self.visible_playlist().id) playlist_db = Playlists.get_playlist(
session, self.visible_playlist_tab().id)
with open(path, "w") as f: with open(path, "w") as f:
# Required directive on first line # Required directive on first line
f.write("#EXTM3U\n") f.write("#EXTM3U\n")
for track in p.get_tracks(): for track in playlist_db.get_tracks():
f.write( f.write(
"#EXTINF:" "#EXTINF:"
f"{int(track.duration / 1000)}," f"{int(track.duration / 1000)},"
@ -273,17 +273,14 @@ class Window(QMainWindow, Ui_MainWindow):
if ok: if ok:
with Session() as session: with Session() as session:
note = self.create_note(session, dlg.textValue()) note = self.create_note(session, dlg.textValue())
self.visible_playlist().insert_note(session, note) self.visible_playlist_tab().insert_note(session, note)
def load_last_playlists(self): def load_last_playlists(self):
"Load the playlists that we loaded at end of last session" "Load the playlists that we loaded at end of last session"
with Session() as session: with Session() as session:
for playlist in Playlists.get_last_used(session): for playlist_db in Playlists.get_last_used(session):
DEBUG( self.load_playlist(session, playlist_db)
f"load_last_playlists(), playlist.name={playlist.name}, "
f"playlist.id={playlist.id}")
self.load_playlist(session, playlist)
def load_playlist(self, session, playlist_db): def load_playlist(self, session, playlist_db):
""" """
@ -291,18 +288,18 @@ class Window(QMainWindow, Ui_MainWindow):
the database object, get it populated and then add tab. the database object, get it populated and then add tab.
""" """
playlist_table = Playlist(self) playlist_tab = PlaylistTab(self)
playlist_table.populate(session, playlist_db) playlist_tab.populate(session, playlist_db)
idx = self.tabPlaylist.addTab(playlist_table, playlist_db.name) idx = self.tabPlaylist.addTab(playlist_tab, playlist_db.name)
self.tabPlaylist.setCurrentIndex(idx) self.tabPlaylist.setCurrentIndex(idx)
def move_selected(self): def move_selected(self):
"Move selected rows to another playlist" "Move selected rows to another playlist"
with Session() as session: with Session() as session:
playlists = [p for p in Playlists.get_all_playlists(session) playlist_dbs = [p for p in Playlists.get_all_playlists(session)
if p.id != self.visible_playlist().id] if p.id != self.visible_playlist_tab().id]
dlg = SelectPlaylistDialog(self, playlists=playlists) dlg = SelectPlaylistDialog(self, playlist_dbs=playlist_dbs)
dlg.exec() dlg.exec()
if not dlg.plid: if not dlg.plid:
return return
@ -319,7 +316,8 @@ class Window(QMainWindow, Ui_MainWindow):
rows = [] rows = []
for (row, track_id) in ( for (row, track_id) in (
self.visible_playlist().get_selected_rows_and_tracks()): self.visible_playlist_tab().get_selected_rows_and_tracks()
):
rows.append(row) rows.append(row)
track = Tracks.track_from_id(session, track_id) track = Tracks.track_from_id(session, track_id)
if destination_visible_playlist_tab: if destination_visible_playlist_tab:
@ -329,14 +327,14 @@ class Window(QMainWindow, Ui_MainWindow):
# Update database # Update database
PlaylistTracks.move_track( PlaylistTracks.move_track(
session, self.visible_playlist().id, row, dlg.plid) session, self.visible_playlist_tab().id, row, dlg.plid)
# Update destination playlist if visible # Update destination playlist if visible
if destination_visible_playlist_tab: if destination_visible_playlist_tab:
destination_visible_playlist_tab.repaint() destination_visible_playlist_tab.repaint()
# Update source playlist # Update source playlist
self.visible_playlist().remove_rows(rows) self.visible_playlist_tab().remove_rows(rows)
def play_next(self): def play_next(self):
""" """
@ -370,24 +368,24 @@ class Window(QMainWindow, Ui_MainWindow):
# Play next track # Play next track
self.current_track = self.next_track self.current_track = self.next_track
self.current_track_playlist = self.next_track_playlist self.current_track_playlist_tab = self.next_track_playlist_tab
self.next_track = None self.next_track = None
self.next_track_playlist = None self.next_track_playlist_tab = None
self.music.play(self.current_track.path) self.music.play(self.current_track.path)
# Update metadata # Update metadata
next_track_id = self.current_track_playlist.play_started() next_track_id = self.current_track_playlist_tab.play_started()
if next_track_id is not None: if next_track_id is not None:
self.next_track = Tracks.get_track(session, next_track_id) self.next_track = Tracks.get_track(session, next_track_id)
self.next_track_playlist = self.current_track_playlist self.next_track_playlist_tab = self.current_track_playlist_tab
# Check we can read it # Check we can read it
if not os.access(self.next_track.path, os.R_OK): if not os.access(self.next_track.path, os.R_OK):
self.show_warning( self.show_warning(
"Can't read next track", "Can't read next track",
self.next_track.path) self.next_track.path)
else: else:
self.next_track = self.next_track_playlist = None self.next_track = self.next_track_playlist_tab = None
# Tell database to record it as played # Tell database to record it as played
self.current_track.update_lastplayed() self.current_track.update_lastplayed()
@ -419,34 +417,35 @@ class Window(QMainWindow, Ui_MainWindow):
def open_playlist(self): def open_playlist(self):
with Session() as session: with Session() as session:
playlists = Playlists.get_all_closed_playlists(session) playlist_dbs = Playlists.get_all_closed_playlists(session)
dlg = SelectPlaylistDialog(self, playlists=playlists) dlg = SelectPlaylistDialog(self, playlist_dbs=playlist_dbs)
dlg.exec() dlg.exec()
if dlg.plid: if dlg.plid:
playlist = Playlists.open(session, dlg.plid) playlist_db = Playlists.open(session, dlg.plid)
self.load_playlist(session, playlist) self.load_playlist(session, playlist_db)
def select_next_track(self): def select_next_track(self):
"Select next or first track in playlist" "Select next or first track in playlist"
self.visible_playlist().select_next_track() self.visible_playlist_tab().select_next_track()
def select_previous_track(self): def select_previous_track(self):
"Select previous or first track in playlist" "Select previous or first track in playlist"
self.visible_playlist().select_previous_track() self.visible_playlist_tab().select_previous_track()
def set_next_track(self, next_track_id=None): def set_next_track(self, next_track_id=None):
"Set selected track as next" "Set selected track as next"
with Session() as session: with Session() as session:
if not next_track_id: if not next_track_id:
next_track_id = self.visible_playlist().set_selected_as_next() next_track_id = (
self.visible_playlist_tab().set_selected_as_next())
if next_track_id: if next_track_id:
if self.next_track_playlist != self.visible_playlist(): if self.next_track_playlist_tab != self.visible_playlist_tab():
if self.next_track_playlist: if self.next_track_playlist_tab:
self.next_track_playlist.clear_next() self.next_track_playlist_tab.clear_next()
self.next_track_playlist = self.visible_playlist() self.next_track_playlist_tab = self.visible_playlist_tab()
self.next_track = Tracks.get_track(session, next_track_id) self.next_track = Tracks.get_track(session, next_track_id)
self.update_headers() self.update_headers()
@ -464,7 +463,7 @@ class Window(QMainWindow, Ui_MainWindow):
- next track - next track
""" """
title = self.visible_playlist().get_selected_title() title = self.visible_playlist_tab().get_selected_title()
if not title: if not title:
if self.current_track: if self.current_track:
title = self.current_track.title title = self.current_track.title
@ -502,18 +501,13 @@ class Window(QMainWindow, Ui_MainWindow):
self.music.fade() self.music.fade()
else: else:
self.music.stop() self.music.stop()
self.current_track_playlist.clear_current() self.current_track_playlist_tab.clear_current()
# Shuffle tracks along # Shuffle tracks along
self.previous_track = self.current_track self.previous_track = self.current_track
self.update_headers() self.update_headers()
def tab_change(self):
"User has changed tabs"
pass
def test_function(self): def test_function(self):
"Placeholder for test function" "Placeholder for test function"
@ -599,11 +593,11 @@ class Window(QMainWindow, Ui_MainWindow):
if self.playing: if self.playing:
self.label_end_timer.setText("00:00") self.label_end_timer.setText("00:00")
self.frame_silent.setStyleSheet("") self.frame_silent.setStyleSheet("")
self.current_track_playlist.play_stopped() self.current_track_playlist_tab.play_stopped()
self.playing = False self.playing = False
self.previous_track = self.current_track self.previous_track = self.current_track
self.current_track = None self.current_track = None
self.current_track_playlist = None self.current_track_playlist_tab = None
self.previous_track_position = 0 self.previous_track_position = 0
self.update_headers() self.update_headers()
# Release player # Release player
@ -702,7 +696,7 @@ class DbDialog(QDialog):
# Add to playlist on screen # Add to playlist on screen
# If we don't specify "repaint=False", playlist will # If we don't specify "repaint=False", playlist will
# also be saved to database # also be saved to database
self.parent().visible_playlist().insert_track( self.parent().visible_playlist_tab().insert_track(
self.session, track) self.session, track)
# Select search text to make it easier for next search # Select search text to make it easier for next search
self.select_searchtext() self.select_searchtext()
@ -721,10 +715,10 @@ class DbDialog(QDialog):
class SelectPlaylistDialog(QDialog): class SelectPlaylistDialog(QDialog):
def __init__(self, parent=None, playlists=None): def __init__(self, parent=None, playlist_dbs=None):
super().__init__(parent) super().__init__(parent)
if playlists is None: if playlist_dbs is None:
return return
self.ui = Ui_dlgSelectPlaylist() self.ui = Ui_dlgSelectPlaylist()
self.ui.setupUi(self) self.ui.setupUi(self)
@ -740,7 +734,7 @@ class SelectPlaylistDialog(QDialog):
height = record.f_int or 600 height = record.f_int or 600
self.resize(width, height) self.resize(width, height)
for (plid, plname) in [(a.id, a.name) for a in playlists]: for (plid, plname) in [(a.id, a.name) for a in playlist_dbs]:
p = QListWidgetItem() p = QListWidgetItem()
p.setText(plname) p.setText(plname)
p.setData(Qt.UserRole, plid) p.setData(Qt.UserRole, plid)

View File

@ -20,7 +20,7 @@ from log import DEBUG, ERROR
from model import Notes, Playlists, PlaylistTracks, Session, Settings, Tracks from model import Notes, Playlists, PlaylistTracks, Session, Settings, Tracks
class Playlist(QTableWidget): class PlaylistTab(QTableWidget):
# Column names # Column names
COL_INDEX = 0 COL_INDEX = 0
COL_MSS = 1 COL_MSS = 1
@ -163,7 +163,7 @@ class Playlist(QTableWidget):
act_delete = self.menu.addAction('Delete') act_delete = self.menu.addAction('Delete')
act_delete.triggered.connect(lambda: self._delete_row(row)) act_delete.triggered.connect(lambda: self._delete_row(row))
return super(Playlist, self).eventFilter(source, event) return super(PlaylistTab, self).eventFilter(source, event)
# ########## Externally called functions ########## # ########## Externally called functions ##########
@ -841,7 +841,7 @@ class Playlist(QTableWidget):
database_notes = {} database_notes = {}
notes_rows = self._meta_get_notes() notes_rows = self._meta_get_notes()
# Playlist # PlaylistTab
for row in notes_rows: for row in notes_rows:
note_id = self._get_row_id(row) note_id = self._get_row_id(row)
if not note_id: if not note_id: