WIP: Implement move rows to playlist
This commit is contained in:
parent
12541e1ff7
commit
c8194fad80
@ -18,7 +18,7 @@ from sqlalchemy import (
|
|||||||
delete,
|
delete,
|
||||||
Float,
|
Float,
|
||||||
ForeignKey,
|
ForeignKey,
|
||||||
# func,
|
func,
|
||||||
Integer,
|
Integer,
|
||||||
select,
|
select,
|
||||||
String,
|
String,
|
||||||
@ -317,15 +317,15 @@ class Playlists(Base):
|
|||||||
# self.loaded = False
|
# self.loaded = False
|
||||||
# session.add(self)
|
# session.add(self)
|
||||||
# session.flush()
|
# session.flush()
|
||||||
#
|
|
||||||
# @classmethod
|
@classmethod
|
||||||
# def get_all(cls, session: Session) -> List["Playlists"]:
|
def get_all(cls, session: Session) -> List["Playlists"]:
|
||||||
# """Returns a list of all playlists ordered by last use"""
|
"""Returns a list of all playlists ordered by last use"""
|
||||||
#
|
|
||||||
# return (
|
return (
|
||||||
# session.query(cls).order_by(
|
session.query(cls).order_by(
|
||||||
# cls.loaded.desc(), cls.last_used.desc())
|
cls.loaded.desc(), cls.last_used.desc())
|
||||||
# ).all()
|
).all()
|
||||||
#
|
#
|
||||||
# @classmethod
|
# @classmethod
|
||||||
# def get_closed(cls, session: Session) -> List["Playlists"]:
|
# def get_closed(cls, session: Session) -> List["Playlists"]:
|
||||||
@ -508,6 +508,31 @@ class PlaylistRows(Base):
|
|||||||
# Ensure new row numbers are available to the caller
|
# Ensure new row numbers are available to the caller
|
||||||
session.commit()
|
session.commit()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def move_to_playlist(session: Session,
|
||||||
|
playlistrow_ids: List[int],
|
||||||
|
destination_playlist_id: int) -> None:
|
||||||
|
"""
|
||||||
|
Move the list of playlistrow_ids to the end of destination_playlist
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Find last row of destination playlist
|
||||||
|
last_row = session.execute(
|
||||||
|
select(func.max(PlaylistRows.row_number))
|
||||||
|
.where(PlaylistRows.playlist_id == destination_playlist_id)
|
||||||
|
).scalar_one()
|
||||||
|
if last_row is None:
|
||||||
|
last_row = 0
|
||||||
|
|
||||||
|
# Update the PlaylistRows entries
|
||||||
|
for plr_id in playlistrow_ids:
|
||||||
|
last_row += 1
|
||||||
|
plr = session.get(PlaylistRows, plr_id)
|
||||||
|
plr.row_number = last_row
|
||||||
|
plr.playlist_id = destination_playlist_id
|
||||||
|
|
||||||
|
session.commit()
|
||||||
|
|
||||||
# @classmethod
|
# @classmethod
|
||||||
# def get_playlist_rows(cls, playlist_id: int) -> \
|
# def get_playlist_rows(cls, playlist_id: int) -> \
|
||||||
# Optional[List["PlaylistRows"]]:
|
# Optional[List["PlaylistRows"]]:
|
||||||
|
|||||||
@ -13,16 +13,17 @@ import sys
|
|||||||
# from typing import Callable, Dict, List, Optional, Tuple
|
# from typing import Callable, Dict, List, Optional, Tuple
|
||||||
#
|
#
|
||||||
# from PyQt5.QtCore import QDate, QEvent, QProcess, Qt, QTime, QTimer, QUrl
|
# from PyQt5.QtCore import QDate, QEvent, QProcess, Qt, QTime, QTimer, QUrl
|
||||||
|
from PyQt5.QtCore import Qt
|
||||||
# from PyQt5.QtGui import QColor
|
# from PyQt5.QtGui import QColor
|
||||||
# from PyQt5.QtWebEngineWidgets import QWebEngineView as QWebView
|
# from PyQt5.QtWebEngineWidgets import QWebEngineView as QWebView
|
||||||
from PyQt5.QtWidgets import (
|
from PyQt5.QtWidgets import (
|
||||||
QApplication,
|
QApplication,
|
||||||
# QDialog,
|
QDialog,
|
||||||
# QFileDialog,
|
# QFileDialog,
|
||||||
# QInputDialog,
|
# QInputDialog,
|
||||||
QLabel,
|
QLabel,
|
||||||
# QLineEdit,
|
# QLineEdit,
|
||||||
# QListWidgetItem,
|
QListWidgetItem,
|
||||||
QMainWindow,
|
QMainWindow,
|
||||||
# QMessageBox,
|
# QMessageBox,
|
||||||
)
|
)
|
||||||
@ -35,14 +36,15 @@ from dbconfig import engine, Session
|
|||||||
from models import (
|
from models import (
|
||||||
Base,
|
Base,
|
||||||
# Playdates,
|
# Playdates,
|
||||||
|
PlaylistRows,
|
||||||
Playlists,
|
Playlists,
|
||||||
# Settings,
|
Settings,
|
||||||
Tracks
|
Tracks
|
||||||
)
|
)
|
||||||
from playlists import PlaylistTab
|
from playlists import PlaylistTab
|
||||||
# from sqlalchemy.orm.exc import DetachedInstanceError
|
# from sqlalchemy.orm.exc import DetachedInstanceError
|
||||||
# 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
|
||||||
# from ui.downloadcsv_ui import Ui_DateSelect
|
# from ui.downloadcsv_ui import Ui_DateSelect
|
||||||
from config import Config
|
from config import Config
|
||||||
from ui.main_window_ui import Ui_MainWindow
|
from ui.main_window_ui import Ui_MainWindow
|
||||||
@ -503,51 +505,58 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
playlist.mark_open(session)
|
playlist.mark_open(session)
|
||||||
|
|
||||||
def move_selected(self) -> None:
|
def move_selected(self) -> None:
|
||||||
"""Move selected rows to another playlist"""
|
"""
|
||||||
|
Move selected rows to another playlist
|
||||||
|
|
||||||
# ***KAE
|
Actions required:
|
||||||
pass
|
- identify destination playlist
|
||||||
|
- update playlist for the rows in the database
|
||||||
|
- remove them from the display
|
||||||
|
- update destination playlist display if loaded
|
||||||
|
"""
|
||||||
|
|
||||||
# with Session() as session:
|
# Identify destination playlist
|
||||||
# visible_tab = self.visible_playlist_tab()
|
with Session() as session:
|
||||||
# visible_tab_id = visible_tab.playlist_id
|
visible_tab = self.visible_playlist_tab()
|
||||||
#
|
source_playlist = visible_tab.playlist_id
|
||||||
# source_playlist = None
|
playlists = []
|
||||||
# playlists = []
|
for playlist in Playlists.get_all(session):
|
||||||
# for playlist in Playlists.get_all(session):
|
if playlist.id == source_playlist:
|
||||||
# if playlist.id == visible_tab_id:
|
continue
|
||||||
# source_playlist = playlist
|
else:
|
||||||
# else:
|
playlists.append(playlist)
|
||||||
# playlists.append(playlist)
|
|
||||||
#
|
# Get destination playlist id
|
||||||
# # Get destination playlist id
|
dlg = SelectPlaylistDialog(self, playlists=playlists,
|
||||||
# dlg = SelectPlaylistDialog(self, playlists=playlists,
|
session=session)
|
||||||
# session=session)
|
dlg.exec()
|
||||||
# dlg.exec()
|
if not dlg.playlist:
|
||||||
# if not dlg.playlist:
|
return
|
||||||
# return
|
destination_playlist = dlg.playlist
|
||||||
# destination_playlist = dlg.playlist
|
|
||||||
#
|
# Update playlist for the rows in the database
|
||||||
# self.visible_playlist_tab().move_selected_to_playlist(
|
plr_ids = visible_tab.get_selected_playlistrow_ids()
|
||||||
# session, destination_playlist.id)
|
PlaylistRows.move_to_playlist(
|
||||||
#
|
session, plr_ids, destination_playlist.id
|
||||||
# # Update destination playlist_tab if visible (if not visible, it
|
)
|
||||||
# # will be re-populated when it is opened)
|
|
||||||
# destination_visible_playlist_tab = None
|
# Remove moved rows from display
|
||||||
# for tab in range(self.tabPlaylist.count()):
|
visible_tab.remove_selected_rows()
|
||||||
# # Non-playlist tabs won't have a 'playlist_id' attribute
|
|
||||||
# if not hasattr(self.tabPlaylist.widget(tab), 'playlist_id'):
|
# Update destination playlist_tab if visible (if not visible, it
|
||||||
# continue
|
# will be re-populated when it is opened)
|
||||||
# if self.tabPlaylist.widget(tab).playlist_id == dlg.playlist.id:
|
destination_visible_playlist_tab = None
|
||||||
# destination_visible_playlist_tab = (
|
for tab in range(self.tabPlaylist.count()):
|
||||||
# self.tabPlaylist.widget(tab))
|
# Non-playlist tabs won't have a 'playlist_id' attribute
|
||||||
# break
|
if not hasattr(self.tabPlaylist.widget(tab), 'playlist_id'):
|
||||||
#
|
continue
|
||||||
# if destination_visible_playlist_tab:
|
if self.tabPlaylist.widget(tab).playlist_id == dlg.playlist.id:
|
||||||
# # We need to commit to database for populate to work
|
destination_visible_playlist_tab = (
|
||||||
# session.commit()
|
self.tabPlaylist.widget(tab))
|
||||||
# destination_visible_playlist_tab.populate(
|
break
|
||||||
# session, dlg.playlist.id)
|
if destination_visible_playlist_tab:
|
||||||
|
destination_visible_playlist_tab.populate(
|
||||||
|
session, dlg.playlist.id)
|
||||||
#
|
#
|
||||||
# def open_info_tabs(self) -> None:
|
# def open_info_tabs(self) -> None:
|
||||||
# """
|
# """
|
||||||
@ -1095,57 +1104,57 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
# self.ui.dateTimeEdit.setTime(QTime(19, 59, 0))
|
# self.ui.dateTimeEdit.setTime(QTime(19, 59, 0))
|
||||||
# self.ui.buttonBox.accepted.connect(self.accept)
|
# self.ui.buttonBox.accepted.connect(self.accept)
|
||||||
# self.ui.buttonBox.rejected.connect(self.reject)
|
# self.ui.buttonBox.rejected.connect(self.reject)
|
||||||
#
|
|
||||||
#
|
|
||||||
# class SelectPlaylistDialog(QDialog):
|
class SelectPlaylistDialog(QDialog):
|
||||||
# def __init__(self, parent=None, playlists=None, session=None):
|
def __init__(self, parent=None, playlists=None, session=None):
|
||||||
# super().__init__(parent)
|
super().__init__(parent)
|
||||||
#
|
|
||||||
# if playlists is None:
|
if playlists is None:
|
||||||
# return
|
return
|
||||||
# self.ui = Ui_dlgSelectPlaylist()
|
self.ui = Ui_dlgSelectPlaylist()
|
||||||
# self.ui.setupUi(self)
|
self.ui.setupUi(self)
|
||||||
# self.ui.lstPlaylists.itemDoubleClicked.connect(self.list_doubleclick)
|
self.ui.lstPlaylists.itemDoubleClicked.connect(self.list_doubleclick)
|
||||||
# self.ui.buttonBox.accepted.connect(self.open)
|
self.ui.buttonBox.accepted.connect(self.open)
|
||||||
# self.ui.buttonBox.rejected.connect(self.close)
|
self.ui.buttonBox.rejected.connect(self.close)
|
||||||
# self.session = session
|
self.session = session
|
||||||
# self.playlist = None
|
self.playlist = None
|
||||||
# self.plid = None
|
self.plid = None
|
||||||
#
|
|
||||||
# record = Settings.get_int_settings(
|
record = Settings.get_int_settings(
|
||||||
# self.session, "select_playlist_dialog_width")
|
self.session, "select_playlist_dialog_width")
|
||||||
# width = record.f_int or 800
|
width = record.f_int or 800
|
||||||
# record = Settings.get_int_settings(
|
record = Settings.get_int_settings(
|
||||||
# self.session, "select_playlist_dialog_height")
|
self.session, "select_playlist_dialog_height")
|
||||||
# height = record.f_int or 600
|
height = record.f_int or 600
|
||||||
# self.resize(width, height)
|
self.resize(width, height)
|
||||||
#
|
|
||||||
# for playlist in playlists:
|
for playlist in playlists:
|
||||||
# p = QListWidgetItem()
|
p = QListWidgetItem()
|
||||||
# p.setText(playlist.name)
|
p.setText(playlist.name)
|
||||||
# p.setData(Qt.UserRole, playlist)
|
p.setData(Qt.UserRole, playlist)
|
||||||
# self.ui.lstPlaylists.addItem(p)
|
self.ui.lstPlaylists.addItem(p)
|
||||||
#
|
|
||||||
# def __del__(self): # review
|
def __del__(self): # review
|
||||||
# record = Settings.get_int_settings(
|
record = Settings.get_int_settings(
|
||||||
# self.session, "select_playlist_dialog_height")
|
self.session, "select_playlist_dialog_height")
|
||||||
# if record.f_int != self.height():
|
if record.f_int != self.height():
|
||||||
# record.update(self.session, {'f_int': self.height()})
|
record.update(self.session, {'f_int': self.height()})
|
||||||
#
|
|
||||||
# record = Settings.get_int_settings(
|
record = Settings.get_int_settings(
|
||||||
# self.session, "select_playlist_dialog_width")
|
self.session, "select_playlist_dialog_width")
|
||||||
# if record.f_int != self.width():
|
if record.f_int != self.width():
|
||||||
# record.update(self.session, {'f_int': self.width()})
|
record.update(self.session, {'f_int': self.width()})
|
||||||
#
|
|
||||||
# def list_doubleclick(self, entry): # review
|
def list_doubleclick(self, entry): # review
|
||||||
# self.playlist = entry.data(Qt.UserRole)
|
self.playlist = entry.data(Qt.UserRole)
|
||||||
# self.accept()
|
self.accept()
|
||||||
#
|
|
||||||
# def open(self): # review
|
def open(self): # review
|
||||||
# if self.ui.lstPlaylists.selectedItems():
|
if self.ui.lstPlaylists.selectedItems():
|
||||||
# item = self.ui.lstPlaylists.currentItem()
|
item = self.ui.lstPlaylists.currentItem()
|
||||||
# self.playlist = item.data(Qt.UserRole)
|
self.playlist = item.data(Qt.UserRole)
|
||||||
# self.accept()
|
self.accept()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@ -340,6 +340,13 @@ class PlaylistTab(QTableWidget):
|
|||||||
self.clearSelection()
|
self.clearSelection()
|
||||||
self.setDragEnabled(False)
|
self.setDragEnabled(False)
|
||||||
|
|
||||||
|
def get_selected_playlistrow_ids(self) -> Optional[List]:
|
||||||
|
"""
|
||||||
|
Return a list of PlaylistRow ids of the selected rows
|
||||||
|
"""
|
||||||
|
|
||||||
|
return [self._get_playlistrow_id(a) for a in self._selected_rows()]
|
||||||
|
|
||||||
# def closeEvent(self, event) -> None:
|
# def closeEvent(self, event) -> None:
|
||||||
# """Save column widths"""
|
# """Save column widths"""
|
||||||
#
|
#
|
||||||
@ -697,6 +704,16 @@ class PlaylistTab(QTableWidget):
|
|||||||
# KAE self.save_playlist(session)
|
# KAE self.save_playlist(session)
|
||||||
self.update_display(session)
|
self.update_display(session)
|
||||||
|
|
||||||
|
def remove_selected_rows(self) -> None:
|
||||||
|
"""Remove selected rows from display"""
|
||||||
|
|
||||||
|
# Remove rows from display. Do so in reverse order so that
|
||||||
|
# row numbers remain valid.
|
||||||
|
for row in sorted(self._selected_rows(), reverse=True):
|
||||||
|
self.removeRow(row)
|
||||||
|
# Reset drag mode
|
||||||
|
self.setDragEnabled(False)
|
||||||
|
|
||||||
def save_playlist(self, session: Session) -> None:
|
def save_playlist(self, session: Session) -> None:
|
||||||
"""
|
"""
|
||||||
Save playlist to database
|
Save playlist to database
|
||||||
@ -1254,22 +1271,14 @@ class PlaylistTab(QTableWidget):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# Delete rows from database
|
# Delete rows from database
|
||||||
# Each item in a row will be returned from selectedItems(), so
|
plr_ids = self.get_selected_playlistrow_ids()
|
||||||
# make a set to remove duplicate row numbers
|
|
||||||
selected_rows = sorted(
|
|
||||||
set(item.row() for item in self.selectedItems())
|
|
||||||
)
|
|
||||||
plr_ids = [self._get_playlistrow_id(a) for a in selected_rows]
|
|
||||||
with Session() as session:
|
with Session() as session:
|
||||||
PlaylistRows.delete_rows(session, plr_ids)
|
PlaylistRows.delete_rows(session, plr_ids)
|
||||||
|
|
||||||
# Fix up row numbers left in this playlist
|
# Fix up row numbers left in this playlist
|
||||||
PlaylistRows.fixup_rownumbers(session, self.playlist_id)
|
PlaylistRows.fixup_rownumbers(session, self.playlist_id)
|
||||||
|
#Remove selected rows from display
|
||||||
# Remove rows from display. Do so in reverse order so that
|
self.remove_selected_rows()
|
||||||
# row numbers remain valid.
|
|
||||||
for row in sorted(selected_rows, reverse=True):
|
|
||||||
self.removeRow(row)
|
|
||||||
|
|
||||||
def _drop_on(self, event):
|
def _drop_on(self, event):
|
||||||
"""
|
"""
|
||||||
@ -1736,9 +1745,7 @@ class PlaylistTab(QTableWidget):
|
|||||||
if self.selecting_in_progress:
|
if self.selecting_in_progress:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Get the row number of all selected items and put into a set
|
selected_rows = self._selected_rows()
|
||||||
# to deduplicate
|
|
||||||
selected_rows = set([item.row() for item in self.selectedItems()])
|
|
||||||
# If no rows are selected, we have nothing to do
|
# If no rows are selected, we have nothing to do
|
||||||
if len(selected_rows) == 0:
|
if len(selected_rows) == 0:
|
||||||
self.musicmuster.lblSumPlaytime.setText("")
|
self.musicmuster.lblSumPlaytime.setText("")
|
||||||
@ -1754,6 +1761,14 @@ class PlaylistTab(QTableWidget):
|
|||||||
f"Selected duration: {helpers.ms_to_mmss(ms)}")
|
f"Selected duration: {helpers.ms_to_mmss(ms)}")
|
||||||
else:
|
else:
|
||||||
self.musicmuster.lblSumPlaytime.setText("")
|
self.musicmuster.lblSumPlaytime.setText("")
|
||||||
|
|
||||||
|
def _selected_rows(self) -> Optional[List[int]]:
|
||||||
|
"""Return a list of selected row numbers"""
|
||||||
|
|
||||||
|
# Use a set to deduplicate result (a selected row will have all
|
||||||
|
# items in that row selected)
|
||||||
|
return [row for row in set([a.row() for a in self.selectedItems()])]
|
||||||
|
|
||||||
#
|
#
|
||||||
# def _select_tracks(self, played: bool) -> None:
|
# def _select_tracks(self, played: bool) -> None:
|
||||||
# """
|
# """
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user