From e2d28b50fb56db55bc334defad5b93a41e5c2552 Mon Sep 17 00:00:00 2001 From: "billy@pom" Date: Wed, 21 Jan 2026 06:14:50 -0500 Subject: [PATCH] add to playlist submenu, attached modals for windows opening, other fixes --- components/DebugWindow.py | 18 +++++++++++---- components/LyricsWindow.py | 14 ++++++++++-- components/MusicTable.py | 39 ++++++++++++++++++++++++++++----- components/PreferencesWindow.py | 14 ++++++++++-- main.py | 4 ++-- sample_config.ini | 2 +- sql/init.sql | 2 +- utils/add_files_to_database.py | 4 ++-- 8 files changed, 77 insertions(+), 20 deletions(-) diff --git a/components/DebugWindow.py b/components/DebugWindow.py index f3ec7f5..06cf0d9 100644 --- a/components/DebugWindow.py +++ b/components/DebugWindow.py @@ -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) diff --git a/components/LyricsWindow.py b/components/LyricsWindow.py index d6f8fd7..979d9e3 100644 --- a/components/LyricsWindow.py +++ b/components/LyricsWindow.py @@ -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( diff --git a/components/MusicTable.py b/components/MusicTable.py index 2f7195b..04b9da8 100644 --- a/components/MusicTable.py +++ b/components/MusicTable.py @@ -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): diff --git a/components/PreferencesWindow.py b/components/PreferencesWindow.py index f9c50b0..a6f58d6 100644 --- a/components/PreferencesWindow.py +++ b/components/PreferencesWindow.py @@ -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) diff --git a/main.py b/main.py index 5e00111..ffd274e 100644 --- a/main.py +++ b/main.py @@ -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 diff --git a/sample_config.ini b/sample_config.ini index 456fba0..1d66c7d 100644 --- a/sample_config.ini +++ b/sample_config.ini @@ -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 diff --git a/sql/init.sql b/sql/init.sql index 7e46bf5..54556f2 100644 --- a/sql/init.sql +++ b/sql/init.sql @@ -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, diff --git a/utils/add_files_to_database.py b/utils/add_files_to_database.py index e21bba0..423e3be 100644 --- a/utils/add_files_to_database.py +++ b/utils/add_files_to_database.py @@ -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