From 1add0bc85a8374e57184b14d55fdcad0d168811d Mon Sep 17 00:00:00 2001 From: billy Date: Sat, 4 Oct 2025 23:43:06 -0400 Subject: [PATCH] fixes and fonts and such --- components/HeaderTags.py | 132 +----------------------------------- components/MusicTable.py | 36 +++++++--- components/PlaylistsPane.py | 15 ++-- components/__init__.py | 2 +- main.py | 15 ++-- 5 files changed, 38 insertions(+), 162 deletions(-) diff --git a/components/HeaderTags.py b/components/HeaderTags.py index f573d82..d3254f3 100644 --- a/components/HeaderTags.py +++ b/components/HeaderTags.py @@ -1,8 +1,5 @@ -from configparser import ConfigParser -from pathlib import Path from typing import Optional -from appdirs import user_config_dir -from dataclasses import dataclass, asdict +from dataclasses import dataclass from mutagen.id3._frames import ( TIT2, TPE1, @@ -80,22 +77,6 @@ mutagen_id3_tag_mapping = { } -@dataclass -class SQLiteMap: - title: str | TIT2 | None = None - artist: str | TPE1 | None = None - album: str | TALB | None = None - album_artist: str | TPE2 | None = None - track_number: str | TRCK | None = None - genre: str | TCON | None = None - length_ms: str | TLEN | None = None - album_date: str | TDRC | None = None - codec: str | None = None - filepath: str | None = None - bitrate: str | None = None - # lyrics: str | USLT | None = None - # album_art: str | APIC | None = None - @dataclass class ID3Field: db: str # e.g., "title" @@ -134,114 +115,3 @@ class HeaderTags2: def get_editable_db_list(self) -> list: return [f.db for f in self.headers if f.editable] - - -class HeaderTags: - """ - Utility class to converting between different "standards" for tags (headers, id3, etc) - - `db`: dict = "db name": "db name string" - `gui`: dict = "db name": "gui string" - `id3`: dict = "db name": "id3 tag string" - `id3_keys`: dict = "id3 tag string": "db name" - `editable_fields`: list = "list of db names that are user editable" - `user_fields`: list = "list of db headers that the user has chosen to see in gui" - """ - - def __init__(self): - cfg_file = ( - Path(user_config_dir(appname="musicpom", appauthor="billypom")) - / "config.ini" - ) - self.config = ConfigParser() - self.config.read(cfg_file) - # print("header tag config") - # print(self.config) - self.user_fields: list = str(self.config["table"]["columns"]).split(",") - self.editable_fields: list = [ - "title", - "artist", - "album_artist", - "album", - "track_number", - "genre", - "album_date", - ] - self.fields = SQLiteMap() - self.headers = SQLiteMap( - title="title", - artist="artist", - album="album", - album_artist="alb artist", - track_number="track", - genre="genre", - album_date="year", - codec="codec", - length_ms="length", - filepath="path", - bitrate="bitrate", - ) - # self.id3 = SQLiteMap( - # title = "TIT2", - # artist = "TPE1", - # album = "TALB", - # album_artist = "TPE2", - # track_number = "TRCK", - # genre = "TCON", - # length_seconds = "TLEN", - # album_date = "TDRC", - # codec = None, - # filepath = None - # ) - self.db: dict = { - "title": "title", - "artist": "artist", - "album": "album", - "album_artist": "album_artist", - "track_number": "track_number", - "genre": "genre", - "album_date": "album_date", - "codec": "codec", - "length_seconds": "length_seconds", - "filepath": "filepath", - "bitrate": "bitrate", - } - self.gui: dict = { - "title": "title", - "artist": "artist", - "album": "album", - "album_artist": "alb artist", - "track_number": "track", - "genre": "genre", - "album_date": "year", - "codec": "codec", - "length_seconds": "length", - "filepath": "path", - "bitrate": "bitrate", - } - self.id3: dict = { - "title": "TIT2", - "artist": "TPE1", - "album_artist": "TPE2", - "album": "TALB", - "track_number": "TRCK", - "genre": "TCON", - "album_date": "TDRC", - "codec": None, - "length_seconds": "TLEN", - "filepath": None, - "bitrate": "TBIT", - } - # id3 is the key - self.id3_keys: dict = {} - for k, v in self.id3.items(): - if v is not None: - self.id3_keys[v] = k - - def get_user_gui_headers(self) -> list: - """Returns a list of headers for the GUI""" - gui_headers = [] - for db, gui in asdict(self.headers).items(): - if db in self.user_fields: - gui_headers.append(gui) - return gui_headers diff --git a/components/MusicTable.py b/components/MusicTable.py index 73acda1..4a58c16 100644 --- a/components/MusicTable.py +++ b/components/MusicTable.py @@ -2,6 +2,7 @@ import DBA from PyQt5.QtGui import ( QColor, QDragMoveEvent, + QFont, QPainter, QPen, QStandardItem, @@ -83,6 +84,10 @@ class MusicTable(QTableView): ) _ = self.config.read(self.cfg_file) + font: QFont = QFont() + font.setPointSize(11) + self.setFont(font) + # NOTE: # QTableView model2 = QSortFilterProxyModel(QStandardItemModel) # @@ -765,9 +770,13 @@ class MusicTable(QTableView): hint: You get a `playlist_id` from the signal emitted from PlaylistsPane as a tuple (1,) """ + if playlist_id: + if self.selected_playlist_id == playlist_id[0]: + # Don't reload if we clicked the same item + return # self.disconnect_data_changed() # self.disconnect_layout_changed() - self.save_scroll_position(self.current_playlist_id) + # self.save_scroll_position(self.current_playlist_id) self.model2.clear() # self.model2.setHorizontalHeaderLabels(self.headers.get_user_gui_headers()) self.model2.setHorizontalHeaderLabels(self.headers.db_list) @@ -780,10 +789,15 @@ class MusicTable(QTableView): params = "" is_playlist = 0 if len(playlist_id) > 0: - self.selected_playlist_id = playlist_id[0] - is_playlist = 1 + if playlist_id[0] == 0: + self.selected_playlist_id = 0 + is_playlist = 0 + else: + self.selected_playlist_id = playlist_id[0] + is_playlist = 1 else: - self.selected_playlist_id = None + self.selected_playlist_id = 0 + is_playlist = 0 # try: # # Check cache for already loaded QTableView QStandardItemModel @@ -1097,13 +1111,13 @@ class MusicTable(QTableView): except Exception: pass - def connect_layout_changed(self): - """Connects the layoutChanged signal from QTableView.model""" - try: - pass - _ = self.model2.layoutChanged.connect(self.restore_scroll_position) - except Exception: - pass + # def connect_layout_changed(self): + # """Connects the layoutChanged signal from QTableView.model""" + # try: + # pass + # _ = self.model2.layoutChanged.connect(self.restore_scroll_position) + # except Exception: + # pass # QT Roles diff --git a/components/PlaylistsPane.py b/components/PlaylistsPane.py index 7cab894..f95f4cc 100644 --- a/components/PlaylistsPane.py +++ b/components/PlaylistsPane.py @@ -1,3 +1,4 @@ +from PyQt5.QtGui import QFont from PyQt5.QtWidgets import ( QAction, QInputDialog, @@ -42,6 +43,10 @@ class PlaylistsPane(QTreeWidget): self.customContextMenuRequested.connect(self.showContextMenu) self.currentItemChanged.connect(self.playlist_clicked) self.playlist_db_id_choice: int | None = None + font: QFont = QFont() + font.setPointSize(16) + font.setBold(True) + self.setFont(font) def reload_playlists(self, progress_callback=None): """ @@ -50,7 +55,7 @@ class PlaylistsPane(QTreeWidget): """ # take all children away self._playlists_root.takeChildren() - # NOTE: implement user sorting by adding a column to playlist db table for 'rank' or something + # TODO: implement user sorting by adding a column to playlist db table for 'rank' or something with DBA.DBAccess() as db: playlists = db.query( "SELECT id, name FROM playlist ORDER BY date_created DESC;", () @@ -144,7 +149,7 @@ class PlaylistsPane(QTreeWidget): if item == self._playlists_root or item == self._library_root: self.playlist_db_id_choice = None # self.all_songs_selected() - self.allSongsSignal.emit() + self.playlistChoiceSignal.emit(0) elif isinstance(item, PlaylistWidgetItem): # debug(f"ID: {item.id}, name: {item.text(0)}") self.playlist_db_id_choice = item.id @@ -153,9 +158,3 @@ class PlaylistsPane(QTreeWidget): def load_qapp(self, qapp) -> None: """Necessary for using members and methods of main application window""" self.qapp = qapp - - # def all_songs_selected(self): - # """Emits a signal to display all songs in the library""" - # # I have no idea why this has to be in its own function, but it does - # # or else it doesn't work - # self.allSongsSignal.emit() diff --git a/components/__init__.py b/components/__init__.py index 2b3c518..9018c11 100644 --- a/components/__init__.py +++ b/components/__init__.py @@ -11,6 +11,6 @@ from .CreatePlaylistWindow import CreatePlaylistWindow from .PlaylistsPane import PlaylistsPane from .ExportPlaylistWindow import ExportPlaylistWindow from .QuestionBoxDetails import QuestionBoxDetails -from .HeaderTags import HeaderTags, HeaderTags2 +from .HeaderTags import HeaderTags2 from .MediaPlayer import MediaPlayer from .SearchLineEdit import SearchLineEdit diff --git a/main.py b/main.py index 4dff910..f63c621 100644 --- a/main.py +++ b/main.py @@ -157,7 +157,6 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow): self.actionOpenFiles.triggered.connect(self.open_files) # Open files window self.actionNewPlaylist.triggered.connect(self.playlistTreeView.create_playlist) self.actionExportPlaylist.triggered.connect(self.export_playlist) - # EDIT MENU self.actionPreferences.triggered.connect(self.open_preferences) # VIEW MENU @@ -207,14 +206,6 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow): def closeEvent(self, a0: QCloseEvent | None) -> None: """Save settings when closing the application""" - # MusicTable/tableView column widths - # list_of_column_widths = [] - # for i in range(self.tableView.model2.columnCount()): - # list_of_column_widths.append(str(self.tableView.columnWidth(i))) - # column_widths_as_string = ",".join(list_of_column_widths) - # debug(f"saving column widths: {column_widths_as_string}") - # self.config["table"]["column_widths"] = column_widths_as_string - self.config["settings"]["volume"] = str(self.current_volume) self.config["settings"]["window_size"] = (str(self.width()) + "," + str(self.height())) self.config['table']['column_ratios'] = ",".join(self.tableView.get_current_header_width_ratios()) @@ -687,8 +678,10 @@ if __name__ == "__main__": handlers=handlers, ) debug('--------- musicpom debug started') - debug('---------------------| ') - debug(f'----------------------> {handlers} ') + debug('--------------------------------') + debug(handlers) + debug('--------------------------------') + debug('--------------------------------') # Initialization config: ConfigParser = update_config_file() if not update_database_file():