add to playlist submenu, attached modals for windows opening, other fixes

This commit is contained in:
billy@pom 2026-01-21 06:14:50 -05:00
parent c85412a753
commit e2d28b50fb
8 changed files with 77 additions and 20 deletions

View File

@ -1,4 +1,3 @@
from collections.abc import Iterable
from PyQt5.QtWidgets import (
QAbstractScrollArea,
QDialog,
@ -9,19 +8,21 @@ from PyQt5.QtWidgets import (
QVBoxLayout,
)
from pprint import pformat
from logging import debug, error
from logging import error
class DebugWindow(QDialog):
def __init__(self, data):
def __init__(self, data, parent=None):
"""
Shows a dialog window
data can be str, list or dict
"""
super(DebugWindow, self).__init__()
super().__init__(parent)
self.setWindowTitle("debug")
self.setMinimumSize(400, 400)
self.data = data
if parent:
self.setMaximumSize(parent.size())
layout = QVBoxLayout()
# Labels & input fields
@ -59,3 +60,12 @@ class DebugWindow(QDialog):
error(f'Tried to load self.data as dict but could not. {e}')
self.setLayout(layout)
def resizeEvent(self, a0):
"""
Adjust maximum size with parent resize
"""
parent = self.parentWidget()
if parent:
self.setMaximumSize(parent.size())
super().resizeEvent(a0)

View File

@ -10,8 +10,9 @@ from logging import debug
class LyricsWindow(QDialog):
def __init__(self, song_filepath: str, lyrics: str):
super(LyricsWindow, self).__init__()
def __init__(self, song_filepath: str, lyrics: str, parent=None):
# super(LyricsWindow, self).__init__()
super().__init__(parent)
self.setWindowTitle("Lyrics")
self.setMinimumSize(400, 400)
self.lyrics: str = lyrics
@ -28,6 +29,15 @@ class LyricsWindow(QDialog):
layout.addWidget(save_button)
self.setLayout(layout)
def resizeEvent(self, a0):
"""
Adjust maximum size with parent resize
"""
parent = self.parentWidget()
if parent:
self.setMaximumSize(parent.size())
super().resizeEvent(a0)
def save(self):
"""Saves the current lyrics text to the USLT/lyrics ID3 tag"""
success = set_tag(

View File

@ -223,10 +223,24 @@ class MusicTable(QTableView):
menu = QMenu(self)
menu.setFont(font)
# TODO: secondary popover for playlist selection?
add_to_playlist_action = QAction("Add to playlist", self)
_ = add_to_playlist_action.triggered.connect(self.add_selected_files_to_playlist)
menu.addAction(add_to_playlist_action)
# OLD CODE but i keep cus i sais so
# add_to_playlist_action = QAction("Add to playlist", self)
# _ = add_to_playlist_action.triggered.connect(self.open_add_to_playlist_window)
# menu.addAction(add_to_playlist_action)
add_to_playlist_menu = QMenu("Add to playlist", menu)
with DBA.DBAccess() as db:
playlists = db.query(
"SELECT id, name FROM playlist ORDER BY date_created DESC;", ()
)
for playlist_id, playlist_name in playlists:
action = QAction(playlist_name, add_to_playlist_menu)
action.triggered.connect(
lambda checked=False, pid=playlist_id: self.add_selected_songs_to_playlist(pid)
)
add_to_playlist_menu.addAction(action)
menu.addMenu(add_to_playlist_menu)
# edit metadata
edit_metadata_action = QAction("Edit metadata", self)
_ = edit_metadata_action.triggered.connect(self.edit_selected_files_metadata)
@ -647,12 +661,25 @@ class MusicTable(QTableView):
error("Application window could not be found")
def add_selected_files_to_playlist(self):
def open_add_to_playlist_window(self):
"""Opens a playlist choice menu and adds the currently selected files to the chosen playlist"""
playlist_choice_window = AddToPlaylistWindow(
self.get_selected_songs_db_ids())
playlist_choice_window.exec_()
def add_selected_songs_to_playlist(self, playlist_id):
for song in self.get_selected_songs_db_ids():
try:
with DBA.DBAccess() as db:
db.execute(
"INSERT INTO song_playlist (playlist_id, song_id) VALUES (?, ?);",
(playlist_id, song),
)
except Exception as e:
error(
f"AddToPlaylistWindow.py save() | could not insert song into playlist: {e}"
)
def delete_songs(self):
"""Asks to delete the currently selected songs from the db and music table (not the filesystem)"""
@ -781,7 +808,7 @@ class MusicTable(QTableView):
lyrics = str(dic["lyrics"])
if not lyrics:
lyrics = ""
lyrics_window = LyricsWindow(selected_song_filepath, lyrics)
lyrics_window = LyricsWindow(selected_song_filepath, lyrics, self)
lyrics_window.exec_()
def setup_keyboard_shortcuts(self):

View File

@ -22,8 +22,9 @@ class PreferencesWindow(QDialog):
reloadConfigSignal = pyqtSignal()
reloadDatabaseSignal = pyqtSignal()
def __init__(self):
super(PreferencesWindow, self).__init__()
def __init__(self, parent=None):
# super(PreferencesWindow, self).__init__()
super().__init__(parent)
# Config
self.setWindowTitle("Preferences")
self.setMinimumSize(800, 600)
@ -69,6 +70,15 @@ class PreferencesWindow(QDialog):
# Set the layout
self.setLayout(main_layout)
def resizeEvent(self, a0):
"""
Adjust maximum size with parent resize
"""
parent = self.parentWidget()
if parent:
self.setMaximumSize(parent.size())
super().resizeEvent(a0)
def on_nav_item_clicked(self, item: QListWidgetItem):
self.current_category = item
self.clear_layout(self.content_layout)

View File

@ -550,7 +550,7 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
def open_preferences(self) -> None:
"""Opens the preferences window"""
preferences_window = PreferencesWindow()
preferences_window = PreferencesWindow(self)
preferences_window.reloadConfigSignal.connect(self.load_config)
preferences_window.reloadDatabaseSignal.connect(self.tableView.load_music_table)
preferences_window.exec_() # Display the preferences window modally
@ -558,7 +558,7 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
# View
def open_font_listing(self) -> None:
window = DebugWindow(QFontDatabase().families())
window = DebugWindow(QFontDatabase().families(), self)
window.exec_()
# Quick Actions

View File

@ -11,7 +11,7 @@ window_size=1152,894
[table]
# Music table user options
columns = title,artist,album,track_number,genre,album_date,codec,length_seconds,filepath
columns = title,artist,album,track_number,genre,album_date,codec,length_ms,filepath
column_ratios = 0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01
# 0 = ascending, 1 = descending
sort_order = artist:0,track_number:0,album:0

View File

@ -11,7 +11,7 @@ CREATE TABLE song(
artist varchar(255),
album_artist varchar(255),
track_number integer,
length_seconds integer,
length_ms integer,
genre varchar(255),
codec varchar(15),
album_date date,

View File

@ -73,7 +73,7 @@ def add_files_to_database(files: list[str], playlist_id: int | None = None, prog
debug(f"inserting a LOT of songs: {len(insert_data)}")
with DBA.DBAccess() as db:
db.executemany(
"INSERT OR IGNORE INTO song (filepath, title, album, artist, track_number, genre, codec, album_date, bitrate, length_seconds) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
"INSERT OR IGNORE INTO song (filepath, title, album, artist, track_number, genre, codec, album_date, bitrate, length_ms) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
insert_data,
)
insert_data = [] # Reset the insert_data list
@ -81,7 +81,7 @@ def add_files_to_database(files: list[str], playlist_id: int | None = None, prog
if insert_data:
with DBA.DBAccess() as db:
db.executemany(
"INSERT OR IGNORE INTO song (filepath, title, album, artist, track_number, genre, codec, album_date, bitrate, length_seconds) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
"INSERT OR IGNORE INTO song (filepath, title, album, artist, track_number, genre, codec, album_date, bitrate, length_ms) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
insert_data,
)
return True, failed_dict