Logic works; playlistrow.py doesn't yet update database but prints a message saying db needs to be updated.
183 lines
5.3 KiB
Python
183 lines
5.3 KiB
Python
# Standard library imports
|
|
from typing import Optional
|
|
|
|
# PyQt imports
|
|
from PyQt6.QtCore import QEvent, Qt
|
|
from PyQt6.QtGui import QKeyEvent
|
|
from PyQt6.QtWidgets import (
|
|
QDialog,
|
|
QListWidgetItem,
|
|
QMainWindow,
|
|
)
|
|
from PyQt6.QtWidgets import (
|
|
QDialog,
|
|
QHBoxLayout,
|
|
QLabel,
|
|
QLineEdit,
|
|
QListWidget,
|
|
QListWidgetItem,
|
|
QPushButton,
|
|
QVBoxLayout,
|
|
)
|
|
|
|
# Third party imports
|
|
from sqlalchemy.orm.session import Session
|
|
|
|
# App imports
|
|
from classes import ApplicationError, InsertTrack, MusicMusterSignals
|
|
from helpers import (
|
|
ask_yes_no,
|
|
get_relative_date,
|
|
ms_to_mmss,
|
|
)
|
|
from log import log
|
|
from models import Settings, Tracks
|
|
from playlistmodel import PlaylistModel
|
|
import repository
|
|
from ui import dlg_TrackSelect_ui
|
|
|
|
|
|
class TrackInsertDialog(QDialog):
|
|
def __init__(
|
|
self,
|
|
parent: QMainWindow,
|
|
playlist_id: int,
|
|
add_to_header: Optional[bool] = False,
|
|
) -> None:
|
|
"""
|
|
Subclassed QDialog to manage track selection
|
|
"""
|
|
|
|
super().__init__(parent)
|
|
self.playlist_id = playlist_id
|
|
self.add_to_header = add_to_header
|
|
self.setWindowTitle("Insert Track")
|
|
|
|
# Title input on one line
|
|
self.title_label = QLabel("Title:")
|
|
self.title_edit = QLineEdit()
|
|
self.title_edit.textChanged.connect(self.update_list)
|
|
|
|
title_layout = QHBoxLayout()
|
|
title_layout.addWidget(self.title_label)
|
|
title_layout.addWidget(self.title_edit)
|
|
|
|
# Track list
|
|
self.track_list = QListWidget()
|
|
self.track_list.itemDoubleClicked.connect(self.add_clicked)
|
|
self.track_list.itemSelectionChanged.connect(self.selection_changed)
|
|
|
|
# Note input on one line
|
|
self.note_label = QLabel("Note:")
|
|
self.note_edit = QLineEdit()
|
|
|
|
note_layout = QHBoxLayout()
|
|
note_layout.addWidget(self.note_label)
|
|
note_layout.addWidget(self.note_edit)
|
|
|
|
# Track path
|
|
self.path = QLabel()
|
|
path_layout = QHBoxLayout()
|
|
path_layout.addWidget(self.path)
|
|
|
|
# Buttons
|
|
self.add_btn = QPushButton("Add")
|
|
self.add_close_btn = QPushButton("Add and close")
|
|
self.close_btn = QPushButton("Close")
|
|
|
|
self.add_btn.clicked.connect(self.add_clicked)
|
|
self.add_close_btn.clicked.connect(self.add_and_close_clicked)
|
|
self.close_btn.clicked.connect(self.close)
|
|
|
|
btn_layout = QHBoxLayout()
|
|
btn_layout.addWidget(self.add_btn)
|
|
btn_layout.addWidget(self.add_close_btn)
|
|
btn_layout.addWidget(self.close_btn)
|
|
|
|
# Main layout
|
|
layout = QVBoxLayout()
|
|
layout.addLayout(title_layout)
|
|
layout.addWidget(self.track_list)
|
|
layout.addLayout(note_layout)
|
|
layout.addLayout(path_layout)
|
|
layout.addLayout(btn_layout)
|
|
|
|
self.setLayout(layout)
|
|
self.resize(800, 600)
|
|
# TODO
|
|
# record = Settings.get_setting(self.session, "dbdialog_width")
|
|
# width = record.f_int or 800
|
|
# record = Settings.get_setting(self.session, "dbdialog_height")
|
|
# height = record.f_int or 600
|
|
# self.resize(width, height)
|
|
|
|
self.signals = MusicMusterSignals()
|
|
|
|
def update_list(self, text: str) -> None:
|
|
self.track_list.clear()
|
|
if text.strip() == "":
|
|
# Do not search or populate list if input is empty
|
|
return
|
|
|
|
if text.startswith("a/") and len(text) > 2:
|
|
self.tracks = repository.tracks_like_artist(text[2:])
|
|
else:
|
|
self.tracks = repository.tracks_like_title(text)
|
|
|
|
for track in self.tracks:
|
|
duration_str = ms_to_mmss(track.duration)
|
|
last_played_str = get_relative_date(track.lastplayed)
|
|
item_str = (
|
|
f"{track.title} - {track.artist} [{duration_str}] {last_played_str}"
|
|
)
|
|
item = QListWidgetItem(item_str)
|
|
item.setData(Qt.ItemDataRole.UserRole, track.track_id)
|
|
self.track_list.addItem(item)
|
|
|
|
def get_selected_track_id(self) -> int | None:
|
|
selected_items = self.track_list.selectedItems()
|
|
if selected_items:
|
|
return selected_items[0].data(Qt.ItemDataRole.UserRole)
|
|
return None
|
|
|
|
def add_clicked(self):
|
|
track_id = self.get_selected_track_id()
|
|
note_text = self.note_edit.text()
|
|
if track_id is None and not note_text:
|
|
return
|
|
|
|
insert_track_data = InsertTrack(self.playlist_id, track_id, note_text)
|
|
|
|
self.title_edit.clear()
|
|
self.note_edit.clear()
|
|
self.track_list.clear()
|
|
self.title_edit.setFocus()
|
|
|
|
if self.add_to_header:
|
|
self.signals.signal_add_track_to_header.emit(insert_track_data)
|
|
self.accept()
|
|
else:
|
|
self.signals.signal_insert_track.emit(insert_track_data)
|
|
|
|
def add_and_close_clicked(self):
|
|
self.add_clicked()
|
|
self.accept()
|
|
|
|
def selection_changed(self) -> None:
|
|
"""Display selected track path in dialog box"""
|
|
|
|
self.path.setText("")
|
|
|
|
track_id = self.get_selected_track_id()
|
|
if track_id is None:
|
|
return
|
|
|
|
tracklist = [t for t in self.tracks if t.track_id == track_id]
|
|
if not tracklist:
|
|
return
|
|
if len(tracklist) > 1:
|
|
raise ApplicationError("More than one track returned")
|
|
track = tracklist[0]
|
|
|
|
self.path.setText(track.path)
|