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 ( from PyQt5.QtWidgets import (
QAbstractScrollArea, QAbstractScrollArea,
QDialog, QDialog,
@ -9,19 +8,21 @@ from PyQt5.QtWidgets import (
QVBoxLayout, QVBoxLayout,
) )
from pprint import pformat from pprint import pformat
from logging import debug, error from logging import error
class DebugWindow(QDialog): class DebugWindow(QDialog):
def __init__(self, data): def __init__(self, data, parent=None):
""" """
Shows a dialog window Shows a dialog window
data can be str, list or dict data can be str, list or dict
""" """
super(DebugWindow, self).__init__() super().__init__(parent)
self.setWindowTitle("debug") self.setWindowTitle("debug")
self.setMinimumSize(400, 400) self.setMinimumSize(400, 400)
self.data = data self.data = data
if parent:
self.setMaximumSize(parent.size())
layout = QVBoxLayout() layout = QVBoxLayout()
# Labels & input fields # Labels & input fields
@ -59,3 +60,12 @@ class DebugWindow(QDialog):
error(f'Tried to load self.data as dict but could not. {e}') error(f'Tried to load self.data as dict but could not. {e}')
self.setLayout(layout) 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): class LyricsWindow(QDialog):
def __init__(self, song_filepath: str, lyrics: str): def __init__(self, song_filepath: str, lyrics: str, parent=None):
super(LyricsWindow, self).__init__() # super(LyricsWindow, self).__init__()
super().__init__(parent)
self.setWindowTitle("Lyrics") self.setWindowTitle("Lyrics")
self.setMinimumSize(400, 400) self.setMinimumSize(400, 400)
self.lyrics: str = lyrics self.lyrics: str = lyrics
@ -28,6 +29,15 @@ class LyricsWindow(QDialog):
layout.addWidget(save_button) layout.addWidget(save_button)
self.setLayout(layout) 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): def save(self):
"""Saves the current lyrics text to the USLT/lyrics ID3 tag""" """Saves the current lyrics text to the USLT/lyrics ID3 tag"""
success = set_tag( success = set_tag(

View File

@ -223,10 +223,24 @@ class MusicTable(QTableView):
menu = QMenu(self) menu = QMenu(self)
menu.setFont(font) menu.setFont(font)
# TODO: secondary popover for playlist selection?
add_to_playlist_action = QAction("Add to playlist", self) # OLD CODE but i keep cus i sais so
_ = add_to_playlist_action.triggered.connect(self.add_selected_files_to_playlist) # add_to_playlist_action = QAction("Add to playlist", self)
menu.addAction(add_to_playlist_action) # _ = 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
edit_metadata_action = QAction("Edit metadata", self) edit_metadata_action = QAction("Edit metadata", self)
_ = edit_metadata_action.triggered.connect(self.edit_selected_files_metadata) _ = edit_metadata_action.triggered.connect(self.edit_selected_files_metadata)
@ -647,12 +661,25 @@ class MusicTable(QTableView):
error("Application window could not be found") 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""" """Opens a playlist choice menu and adds the currently selected files to the chosen playlist"""
playlist_choice_window = AddToPlaylistWindow( playlist_choice_window = AddToPlaylistWindow(
self.get_selected_songs_db_ids()) self.get_selected_songs_db_ids())
playlist_choice_window.exec_() 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): def delete_songs(self):
"""Asks to delete the currently selected songs from the db and music table (not the filesystem)""" """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"]) lyrics = str(dic["lyrics"])
if not lyrics: if not lyrics:
lyrics = "" lyrics = ""
lyrics_window = LyricsWindow(selected_song_filepath, lyrics) lyrics_window = LyricsWindow(selected_song_filepath, lyrics, self)
lyrics_window.exec_() lyrics_window.exec_()
def setup_keyboard_shortcuts(self): def setup_keyboard_shortcuts(self):

View File

@ -22,8 +22,9 @@ class PreferencesWindow(QDialog):
reloadConfigSignal = pyqtSignal() reloadConfigSignal = pyqtSignal()
reloadDatabaseSignal = pyqtSignal() reloadDatabaseSignal = pyqtSignal()
def __init__(self): def __init__(self, parent=None):
super(PreferencesWindow, self).__init__() # super(PreferencesWindow, self).__init__()
super().__init__(parent)
# Config # Config
self.setWindowTitle("Preferences") self.setWindowTitle("Preferences")
self.setMinimumSize(800, 600) self.setMinimumSize(800, 600)
@ -69,6 +70,15 @@ class PreferencesWindow(QDialog):
# Set the layout # Set the layout
self.setLayout(main_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): def on_nav_item_clicked(self, item: QListWidgetItem):
self.current_category = item self.current_category = item
self.clear_layout(self.content_layout) self.clear_layout(self.content_layout)

View File

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

View File

@ -11,7 +11,7 @@ window_size=1152,894
[table] [table]
# Music table user options # 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 column_ratios = 0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01
# 0 = ascending, 1 = descending # 0 = ascending, 1 = descending
sort_order = artist:0,track_number:0,album:0 sort_order = artist:0,track_number:0,album:0

View File

@ -11,7 +11,7 @@ CREATE TABLE song(
artist varchar(255), artist varchar(255),
album_artist varchar(255), album_artist varchar(255),
track_number integer, track_number integer,
length_seconds integer, length_ms integer,
genre varchar(255), genre varchar(255),
codec varchar(15), codec varchar(15),
album_date date, 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)}") debug(f"inserting a LOT of songs: {len(insert_data)}")
with DBA.DBAccess() as db: with DBA.DBAccess() as db:
db.executemany( 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,
) )
insert_data = [] # Reset the insert_data list 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: if insert_data:
with DBA.DBAccess() as db: with DBA.DBAccess() as db:
db.executemany( 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,
) )
return True, failed_dict return True, failed_dict