This commit is contained in:
billypom on debian 2025-08-03 22:49:04 -04:00
parent 511b118790
commit 69ce4bc763
6 changed files with 131 additions and 113 deletions

View File

@ -7,16 +7,16 @@ from typing import Optional
@dataclass @dataclass
class SQLiteMap: class SQLiteMap:
title: Optional[str] = None title: str | None = None
artist: Optional[str] = None artist: str | None = None
album: Optional[str] = None album: str | None = None
album_artist: Optional[str] = None album_artist: str | None = None
track_number: Optional[str] = None track_number: str | None = None
genre: Optional[str] = None genre: str | None = None
length_seconds: Optional[str] = None length_seconds: str | None = None
album_date: Optional[str] = None album_date: str | None = None
codec: Optional[str] = None codec: str | None = None
filepath: Optional[str] = None filepath: str | None = None
""" """

View File

@ -118,8 +118,7 @@ class MusicTable(QTableView):
) )
self.config = ConfigParser() self.config = ConfigParser()
self.config.read(cfg_file) self.config.read(cfg_file)
print("music table config:") debug(f"music table config: {self.config}")
print(self.config)
# Threads # Threads
self.threadpool = QThreadPool self.threadpool = QThreadPool
@ -138,7 +137,8 @@ class MusicTable(QTableView):
# Properties # Properties
self.setAcceptDrops(True) self.setAcceptDrops(True)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff) self.setHorizontalScrollBarPolicy(
Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
self.setEditTriggers(QAbstractItemView.EditTrigger.EditKeyPressed) self.setEditTriggers(QAbstractItemView.EditTrigger.EditKeyPressed)
self.setAlternatingRowColors(True) self.setAlternatingRowColors(True)
self.setSelectionMode(QAbstractItemView.ExtendedSelection) self.setSelectionMode(QAbstractItemView.ExtendedSelection)
@ -146,7 +146,7 @@ class MusicTable(QTableView):
# header # header
self.horizontal_header: QHeaderView = self.horizontalHeader() self.horizontal_header: QHeaderView = self.horizontalHeader()
assert self.horizontal_header is not None # i hate look at linting errors assert self.horizontal_header is not None # i hate look at linting errors
self.horizontal_header.setStretchLastSection(True) self.horizontal_header.setStretchLastSection(False)
self.horizontal_header.setSectionResizeMode(QHeaderView.Interactive) self.horizontal_header.setSectionResizeMode(QHeaderView.Interactive)
self.horizontal_header.sortIndicatorChanged.connect(self.on_sort) self.horizontal_header.sortIndicatorChanged.connect(self.on_sort)
# dumb vertical estupido # dumb vertical estupido
@ -159,7 +159,8 @@ class MusicTable(QTableView):
self.deleteKey.connect(self.delete_songs) self.deleteKey.connect(self.delete_songs)
self.doubleClicked.connect(self.play_selected_audio_file) self.doubleClicked.connect(self.play_selected_audio_file)
self.enterKey.connect(self.play_selected_audio_file) self.enterKey.connect(self.play_selected_audio_file)
self.model2.dataChanged.connect(self.on_cell_data_changed) # editing cells self.model2.dataChanged.connect(
self.on_cell_data_changed) # editing cells
# self.model2.layoutChanged.connect(self.restore_scroll_position) # self.model2.layoutChanged.connect(self.restore_scroll_position)
self.horizontal_header.sectionResized.connect(self.on_header_resized) self.horizontal_header.sectionResized.connect(self.on_header_resized)
# Final actions # Final actions
@ -202,11 +203,13 @@ class MusicTable(QTableView):
"""Right-click context menu""" """Right-click context menu"""
menu = QMenu(self) menu = QMenu(self)
add_to_playlist_action = QAction("Add to playlist", self) add_to_playlist_action = QAction("Add to playlist", self)
add_to_playlist_action.triggered.connect(self.add_selected_files_to_playlist) add_to_playlist_action.triggered.connect(
self.add_selected_files_to_playlist)
menu.addAction(add_to_playlist_action) menu.addAction(add_to_playlist_action)
# 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)
menu.addAction(edit_metadata_action) menu.addAction(edit_metadata_action)
# edit lyrics # edit lyrics
edit_lyrics_action = QAction("Lyrics (View/Edit)", self) edit_lyrics_action = QAction("Lyrics (View/Edit)", self)
@ -214,10 +217,12 @@ class MusicTable(QTableView):
menu.addAction(edit_lyrics_action) menu.addAction(edit_lyrics_action)
# jump to current song in table # jump to current song in table
jump_to_current_song_action = QAction("Jump to current song", self) jump_to_current_song_action = QAction("Jump to current song", self)
jump_to_current_song_action.triggered.connect(self.jump_to_current_song) jump_to_current_song_action.triggered.connect(
self.jump_to_current_song)
menu.addAction(jump_to_current_song_action) menu.addAction(jump_to_current_song_action)
# open in file explorer # open in file explorer
open_containing_folder_action = QAction("Open in system file manager", self) open_containing_folder_action = QAction(
"Open in system file manager", self)
open_containing_folder_action.triggered.connect(self.open_directory) open_containing_folder_action.triggered.connect(self.open_directory)
menu.addAction(open_containing_folder_action) menu.addAction(open_containing_folder_action)
# view id3 tags (debug) # view id3 tags (debug)
@ -380,59 +385,58 @@ class MusicTable(QTableView):
self.set_selected_song_qmodel_index() self.set_selected_song_qmodel_index()
self.viewport().update() # type: ignore self.viewport().update() # type: ignore
def on_header_resized(self, logicalIndex, oldSize, newSize): def on_header_resized(self, logicalIndex: int, oldSize: int, newSize: int):
"""Handles keeping headers inside the viewport""" """Handles keeping headers inside the viewport"""
# FIXME: how resize good # FIXME: how resize good
pass
# https://stackoverflow.com/questions/46775438/how-to-limit-qheaderview-size-when-resizing-sections # https://stackoverflow.com/questions/46775438/how-to-limit-qheaderview-size-when-resizing-sections
col_count = self.model2.columnCount() # col_count = self.model2.columnCount()
qtableview_width = self.size().width() # qtableview_width = self.size().width()
sum_of_cols = self.horizontal_header.length() # sum_of_cols = self.horizontal_header.length()
# debug(f'qtable_width: {qtableview_width}') # debug(f'qtable_width: {qtableview_width}')
# debug(f'sum of cols: {sum_of_cols}') # debug(f'sum of cols: {sum_of_cols}')
# check for discrepancy # if sum_of_cols != qtableview_width: # check for discrepancy
if sum_of_cols != qtableview_width: # if logicalIndex < col_count: # if not the last header
# if not the last header # next_header_size = self.horizontal_header.sectionSize(logicalIndex + 1)
if logicalIndex < col_count: # if next_header_size > (sum_of_cols - qtableview_width): # if it should shrink
next_header_size = self.horizontal_header.sectionSize(logicalIndex + 1) # self.horizontal_header.resizeSection(
# If it should shrink # logicalIndex + 1,
if next_header_size > (sum_of_cols - qtableview_width): # next_header_size - (sum_of_cols - qtableview_width),
# shrink it # ) # shrink it
self.horizontal_header.resizeSection( # else:
logicalIndex + 1, # self.horizontal_header.resizeSection(logicalIndex, oldSize) # block the resize
next_header_size - (sum_of_cols - qtableview_width),
)
else:
# block the resize
self.horizontal_header.resizeSection(logicalIndex, oldSize)
def on_cell_data_changed(self, topLeft: QModelIndex, bottomRight: QModelIndex): def on_cell_data_changed(self, topLeft: QModelIndex, bottomRight: QModelIndex):
"""Handles updating ID3 tags when data changes in a cell""" """Handles updating ID3 tags when data changes in a cell"""
# FIXME: broken # FIXME: broken
if isinstance(self.model2, QStandardItemModel):
# if isinstance(self.model2, QStandardItemModel):
debug("on_cell_data_changed") debug("on_cell_data_changed")
# get the ID of the row that was edited # get the ID of the row that was edited
id_index = self.model2.index(topLeft.row(), 0) id_index = self.model2.index(topLeft.row(), 0)
# get the db song_id from the row # get the db song_id from the row
song_id = self.model2.data(id_index, Qt.ItemDataRole.UserRole) song_id: int = self.model2.data(id_index, Qt.ItemDataRole.UserRole)
user_index = self.headers.user_fields.index("filepath") user_index = self.headers.user_fields.index("filepath")
filepath = self.currentIndex().siblingAtColumn(user_index).data() filepath = self.currentIndex().siblingAtColumn(user_index).data()
# update the ID3 information # update the ID3 information
user_input_data = topLeft.data() user_input_data: str = topLeft.data()
edited_column_name = self.headers.user_fields[topLeft.column()] edited_column_name: str = self.headers.user_fields[topLeft.column()]
debug(f"on_cell_data_changed | edited column name: {edited_column_name}") debug(
f"on_cell_data_changed | edited column name: {edited_column_name}")
response = set_tag(filepath, edited_column_name, user_input_data) response = set_tag(filepath, edited_column_name, user_input_data)
if response: if response:
# Update the library with new metadata # Update the library with new metadata
update_song_in_database(song_id, edited_column_name, user_input_data) _ = update_song_in_database(
song_id, edited_column_name, user_input_data)
return return
def handle_progress(self, data): def handle_progress(self, data: object):
"""Emits data to main""" """Emits data to main"""
self.handleProgressSignal.emit(data) self.handleProgressSignal.emit(data)
def on_get_audio_files_recursively_finished(self, result): def on_get_audio_files_recursively_finished(self, result: list[str]):
"""file search completion handler""" """file search completion handler"""
if result: if result:
self.add_files_to_library(result) self.add_files_to_library(result)
@ -456,7 +460,8 @@ class MusicTable(QTableView):
except IndexError: except IndexError:
pass pass
except Exception as e: except Exception as e:
debug(f"on_add_files_to_database_finished() | Something went wrong: {e}") debug(
f"on_add_files_to_database_finished() | Something went wrong: {e}")
# ____________________ # ____________________
# | | # | |
@ -484,8 +489,8 @@ class MusicTable(QTableView):
- File > Open > List of song(s) - File > Open > List of song(s)
""" """
worker = Worker(add_files_to_database, files) worker = Worker(add_files_to_database, files)
worker.signals.signal_progress.connect(self.qapp.handle_progress) _ = worker.signals.signal_progress.connect(self.qapp.handle_progress)
worker.signals.signal_result.connect(self.on_add_files_to_database_finished) _ = worker.signals.signal_result.connect(self.on_add_files_to_database_finished)
worker.signals.signal_finished.connect(self.load_music_table) worker.signals.signal_finished.connect(self.load_music_table)
if self.qapp: if self.qapp:
threadpool = self.qapp.threadpool threadpool = self.qapp.threadpool
@ -495,15 +500,15 @@ class MusicTable(QTableView):
def add_selected_files_to_playlist(self): def add_selected_files_to_playlist(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(self.get_selected_songs_db_ids()) playlist_choice_window = AddToPlaylistWindow(
self.get_selected_songs_db_ids())
playlist_choice_window.exec_() playlist_choice_window.exec_()
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)"""
# FIXME: determine if we are in a playlist or not # NOTE: provide extra questionbox option?
# then delete songs from only the playlist
# or provide extra questionbox option
# | Delete from playlist & lib | Delete from playlist only | Cancel | # | Delete from playlist & lib | Delete from playlist only | Cancel |
# Currently, this just deletes from the playlist, or the main lib & any playlists
selected_filepaths = self.get_selected_songs_filepaths() selected_filepaths = self.get_selected_songs_filepaths()
if self.selected_playlist_id: if self.selected_playlist_id:
question_dialog = QuestionBoxDetails( question_dialog = QuestionBoxDetails(
@ -513,9 +518,12 @@ class MusicTable(QTableView):
) )
reply = question_dialog.execute() reply = question_dialog.execute()
if reply: if reply:
worker = Worker(batch_delete_filepaths_from_playlist, selected_filepaths, self.selected_playlist_id) worker = Worker(batch_delete_filepaths_from_playlist,
worker.signals.signal_progress.connect(self.qapp.handle_progress) selected_filepaths, self.selected_playlist_id)
worker.signals.signal_finished.connect(self.delete_selected_row_indices) worker.signals.signal_progress.connect(
self.qapp.handle_progress)
worker.signals.signal_finished.connect(
self.delete_selected_row_indices)
if self.qapp: if self.qapp:
threadpool = self.qapp.threadpool threadpool = self.qapp.threadpool
threadpool.start(worker) threadpool.start(worker)
@ -527,9 +535,12 @@ class MusicTable(QTableView):
) )
reply = question_dialog.execute() reply = question_dialog.execute()
if reply: if reply:
worker = Worker(batch_delete_filepaths_from_database, selected_filepaths) worker = Worker(
worker.signals.signal_progress.connect(self.qapp.handle_progress) batch_delete_filepaths_from_database, selected_filepaths)
worker.signals.signal_finished.connect(self.delete_selected_row_indices) worker.signals.signal_progress.connect(
self.qapp.handle_progress)
worker.signals.signal_finished.connect(
self.delete_selected_row_indices)
if self.qapp: if self.qapp:
threadpool = self.qapp.threadpool threadpool = self.qapp.threadpool
threadpool.start(worker) threadpool.start(worker)
@ -563,7 +574,8 @@ class MusicTable(QTableView):
"""Moves screen to the selected song, then selects the row""" """Moves screen to the selected song, then selects the row"""
debug("jump_to_selected_song") debug("jump_to_selected_song")
# get the proxy model index # get the proxy model index
proxy_index = self.proxymodel.mapFromSource(self.selected_song_qmodel_index) proxy_index = self.proxymodel.mapFromSource(
self.selected_song_qmodel_index)
self.scrollTo(proxy_index) self.scrollTo(proxy_index)
self.selectRow(proxy_index.row()) self.selectRow(proxy_index.row())
@ -573,7 +585,8 @@ class MusicTable(QTableView):
# get the proxy model index # get the proxy model index
debug(self.current_song_filepath) debug(self.current_song_filepath)
debug(self.current_song_qmodel_index) debug(self.current_song_qmodel_index)
proxy_index = self.proxymodel.mapFromSource(self.current_song_qmodel_index) proxy_index = self.proxymodel.mapFromSource(
self.current_song_qmodel_index)
self.scrollTo(proxy_index) self.scrollTo(proxy_index)
self.selectRow(proxy_index.row()) self.selectRow(proxy_index.row())
@ -684,7 +697,8 @@ class MusicTable(QTableView):
) )
# debug(f"reorganize_files() | Moved: {filepath} -> {new_path}") # debug(f"reorganize_files() | Moved: {filepath} -> {new_path}")
except Exception as e: except Exception as e:
error(f"reorganize_files() | Error moving file: {filepath} | {e}") error(
f"reorganize_files() | Error moving file: {filepath} | {e}")
# Draw the rest of the owl # Draw the rest of the owl
# QMessageBox.information( # QMessageBox.information(
# self, "Reorganization complete", "Files successfully reorganized" # self, "Reorganization complete", "Files successfully reorganized"
@ -709,7 +723,8 @@ class MusicTable(QTableView):
self.disconnect_layout_changed() self.disconnect_layout_changed()
self.vertical_scroll_position = self.verticalScrollBar().value() # type: ignore self.vertical_scroll_position = self.verticalScrollBar().value() # type: ignore
self.model2.clear() self.model2.clear()
self.model2.setHorizontalHeaderLabels(self.headers.get_user_gui_headers()) self.model2.setHorizontalHeaderLabels(
self.headers.get_user_gui_headers())
fields = ", ".join(self.headers.user_fields) fields = ", ".join(self.headers.user_fields)
search_clause = ( search_clause = (
"title LIKE ? OR artist LIKE ? OR album LIKE ?" "title LIKE ? OR artist LIKE ? OR album LIKE ?"
@ -731,7 +746,8 @@ class MusicTable(QTableView):
query = f"{query} WHERE {search_clause};" query = f"{query} WHERE {search_clause};"
else: else:
query = f"{query} AND {search_clause};" query = f"{query} AND {search_clause};"
data = db.query(query, (self.selected_playlist_id, params)) data = db.query(
query, (self.selected_playlist_id, params))
else: else:
data = db.query(query, (self.selected_playlist_id,)) data = db.query(query, (self.selected_playlist_id,))
@ -788,7 +804,8 @@ class MusicTable(QTableView):
# reloading the model destroys and makes new indexes # reloading the model destroys and makes new indexes
# so we look for the new index of the current song on load # so we look for the new index of the current song on load
current_song_filepath = self.get_current_song_filepath() current_song_filepath = self.get_current_song_filepath()
debug(f"load_music_table() | current filepath: {current_song_filepath}") debug(
f"load_music_table() | current filepath: {current_song_filepath}")
for row in range(self.model2.rowCount()): for row in range(self.model2.rowCount()):
real_index = self.model2.index( real_index = self.model2.index(
row, self.headers.user_fields.index("filepath") row, self.headers.user_fields.index("filepath")
@ -814,7 +831,8 @@ class MusicTable(QTableView):
""" """
Loads the header widths from the last application close. Loads the header widths from the last application close.
""" """
table_view_column_widths = str(self.config["table"]["column_widths"]).split(",") table_view_column_widths = str(
self.config["table"]["column_widths"]).split(",")
debug(f"loaded header widths: {table_view_column_widths}") debug(f"loaded header widths: {table_view_column_widths}")
if not isinstance(table_view_column_widths, list): if not isinstance(table_view_column_widths, list):
for i in range(self.model2.columnCount() - 1): for i in range(self.model2.columnCount() - 1):
@ -898,7 +916,8 @@ class MusicTable(QTableView):
selected_rows = self.get_selected_rows() selected_rows = self.get_selected_rows()
filepaths = [] filepaths = []
for row in selected_rows: for row in selected_rows:
idx = self.proxymodel.index(row, self.headers.user_fields.index("filepath")) idx = self.proxymodel.index(
row, self.headers.user_fields.index("filepath"))
filepaths.append(idx.data()) filepaths.append(idx.data())
return filepaths return filepaths

View File

@ -1,7 +1,6 @@
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
QAction, QAction,
QInputDialog, QInputDialog,
QListWidget,
QMenu, QMenu,
QMessageBox, QMessageBox,
QTreeWidget, QTreeWidget,
@ -10,6 +9,7 @@ from PyQt5.QtWidgets import (
from PyQt5.QtCore import QThreadPool, pyqtSignal, Qt, QPoint from PyQt5.QtCore import QThreadPool, pyqtSignal, Qt, QPoint
import DBA import DBA
from logging import debug from logging import debug
from components.ErrorDialog import ErrorDialog
from utils import Worker from utils import Worker
from components import CreatePlaylistWindow from components import CreatePlaylistWindow
@ -43,10 +43,6 @@ class PlaylistsPane(QTreeWidget):
self.customContextMenuRequested.connect(self.showContextMenu) self.customContextMenuRequested.connect(self.showContextMenu)
self.currentItemChanged.connect(self.playlist_clicked) self.currentItemChanged.connect(self.playlist_clicked)
self.playlist_db_id_choice: int | None = None self.playlist_db_id_choice: int | None = None
self.threadpool: QThreadPool | None = None
def set_threadpool(self, threadpool: QThreadPool):
self.threadpool = threadpool
def reload_playlists(self, progress_callback=None): def reload_playlists(self, progress_callback=None):
""" """
@ -60,7 +56,7 @@ class PlaylistsPane(QTreeWidget):
playlists = db.query( playlists = db.query(
"SELECT id, name FROM playlist ORDER BY date_created DESC;", () "SELECT id, name FROM playlist ORDER BY date_created DESC;", ()
) )
debug(f'PlaylistsPane: | playlists = {playlists}') # debug(f'PlaylistsPane: | playlists = {playlists}')
for playlist in playlists: for playlist in playlists:
branch = PlaylistWidgetItem(self, playlist[0], playlist[1]) branch = PlaylistWidgetItem(self, playlist[0], playlist[1])
self._playlists_root.addChild(branch) self._playlists_root.addChild(branch)
@ -86,7 +82,7 @@ class PlaylistsPane(QTreeWidget):
def create_playlist(self): def create_playlist(self):
"""Creates a database record for a playlist, given a name""" """Creates a database record for a playlist, given a name"""
window = CreatePlaylistWindow(self.playlistCreatedSignal) window = CreatePlaylistWindow(self.playlistCreatedSignal)
window.playlistCreatedSignal.connect(self.reload_playlists) # type: ignore window.playlistCreatedSignal.connect(self.reload_playlists)
window.exec_() window.exec_()
def rename_playlist(self, *args): def rename_playlist(self, *args):
@ -110,8 +106,9 @@ class PlaylistsPane(QTreeWidget):
(text, self.playlist_db_id_choice), (text, self.playlist_db_id_choice),
) )
worker = Worker(self.reload_playlists) worker = Worker(self.reload_playlists)
if self.threadpool: if self.qapp:
self.threadpool.start(worker) threadpool = self.qapp.threadpool
threadpool.start(worker)
def delete_playlist(self, *args): def delete_playlist(self, *args):
"""Deletes a playlist""" """Deletes a playlist"""
@ -123,14 +120,18 @@ class PlaylistsPane(QTreeWidget):
QMessageBox.Yes, QMessageBox.Yes,
) )
if reply == QMessageBox.Yes: if reply == QMessageBox.Yes:
if self.qapp:
with DBA.DBAccess() as db: with DBA.DBAccess() as db:
db.execute( db.execute(
"DELETE FROM playlist WHERE id = ?;", (self.playlist_db_id_choice,) "DELETE FROM playlist WHERE id = ?;", (self.playlist_db_id_choice,)
) )
# reload # reload
worker = Worker(self.reload_playlists) worker = Worker(self.reload_playlists)
if self.threadpool: threadpool = self.qapp.threadpool
self.threadpool.start(worker) threadpool.start(worker)
else:
error_dialog = ErrorDialog("Main application [qapp] not loaded - aborting operation")
error_dialog.exec()
def playlist_clicked(self, item): def playlist_clicked(self, item):
"""Specific playlist pane index was clicked""" """Specific playlist pane index was clicked"""
@ -139,10 +140,14 @@ class PlaylistsPane(QTreeWidget):
# self.all_songs_selected() # self.all_songs_selected()
self.allSongsSignal.emit() self.allSongsSignal.emit()
elif isinstance(item, PlaylistWidgetItem): elif isinstance(item, PlaylistWidgetItem):
debug(f"ID: {item.id}, name: {item.text(0)}") # debug(f"ID: {item.id}, name: {item.text(0)}")
self.playlist_db_id_choice = item.id self.playlist_db_id_choice = item.id
self.playlistChoiceSignal.emit(int(item.id)) self.playlistChoiceSignal.emit(int(item.id))
def load_qapp(self, qapp) -> None:
"""Necessary for using members and methods of main application window"""
self.qapp = qapp
# def all_songs_selected(self): # def all_songs_selected(self):
# """Emits a signal to display all songs in the library""" # """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 # # I have no idea why this has to be in its own function, but it does

View File

@ -42,7 +42,7 @@ class SearchLineEdit(QLineEdit):
def on_text_changed(self): def on_text_changed(self):
"""Reset a timer each time text is changed""" """Reset a timer each time text is changed"""
self.timer.start(300) self.timer.start(1500)
def on_typing_stopped(self): def on_typing_stopped(self):
"""When timer reaches end, emit the text that is currently entered""" """When timer reaches end, emit the text that is currently entered"""

12
main.py
View File

@ -92,7 +92,6 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
/ "config.ini" / "config.ini"
) )
self.config.read(self.cfg_file) self.config.read(self.cfg_file)
debug(f"\tmain config: {self.config}")
self.threadpool: QThreadPool = QThreadPool() self.threadpool: QThreadPool = QThreadPool()
# UI # UI
self.setupUi(self) self.setupUi(self)
@ -105,6 +104,7 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
self.status_bar.addPermanentWidget(self.permanent_status_label) self.status_bar.addPermanentWidget(self.permanent_status_label)
self.setStatusBar(self.status_bar) self.setStatusBar(self.status_bar)
# table
self.selected_song_filepath: str | None = None self.selected_song_filepath: str | None = None
self.current_song_filepath: str | None = None self.current_song_filepath: str | None = None
self.current_song_metadata: ID3 | dict | None = None self.current_song_metadata: ID3 | dict | None = None
@ -113,7 +113,6 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
# widget bits # widget bits
self.tableView: MusicTable self.tableView: MusicTable
self.album_art_scene: QGraphicsScene = QGraphicsScene() self.album_art_scene: QGraphicsScene = QGraphicsScene()
# self.player: QMediaPlayer = QMediaPlayer() # Audio player object
self.player: QMediaPlayer = MediaPlayer() self.player: QMediaPlayer = MediaPlayer()
# set index on choose song # set index on choose song
# index is the model2's row number? i guess? # index is the model2's row number? i guess?
@ -143,6 +142,7 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
# sharing functions with other classes and that # sharing functions with other classes and that
self.tableView.load_qapp(self) self.tableView.load_qapp(self)
self.albumGraphicsView.load_qapp(self) self.albumGraphicsView.load_qapp(self)
self.playlistTreeView.load_qapp(self)
self.headers = HeaderTags() self.headers = HeaderTags()
# Settings init # Settings init
@ -214,7 +214,6 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
self.tableView.load_music_table self.tableView.load_music_table
) )
self.playlistTreeView.allSongsSignal.connect(self.tableView.load_music_table) self.playlistTreeView.allSongsSignal.connect(self.tableView.load_music_table)
self.playlistTreeView.set_threadpool(self.threadpool)
# albumGraphicsView # albumGraphicsView
self.albumGraphicsView.albumArtDropped.connect( self.albumGraphicsView.albumArtDropped.connect(
@ -393,16 +392,11 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
def load_config(self) -> None: def load_config(self) -> None:
"""does what it says""" """does what it says"""
cfg_file = ( cfg_file = (
Path(user_config_dir(appname="musicpom", appauthor="billypom")) Path(user_config_dir(appname="musicpom", appauthor="billypom")) / "config.ini"
/ "config.ini"
) )
self.config.read(cfg_file) self.config.read(cfg_file)
debug("load_config()") debug("load_config()")
def get_thread_pool(self) -> QThreadPool:
"""Returns the threadpool instance"""
return self.threadpool
def set_permanent_status_bar_message(self, message: str) -> None: def set_permanent_status_bar_message(self, message: str) -> None:
""" """
Sets the permanent message label in the status bar Sets the permanent message label in the status bar

View File

@ -27,10 +27,10 @@ class WorkerSignals(QObject):
# pandas DataFrames or numpy arrays. Instead, pass the minimum amount of information needed # pandas DataFrames or numpy arrays. Instead, pass the minimum amount of information needed
# (i.e. lists of filepaths) # (i.e. lists of filepaths)
signal_started = pyqtSignal() signal_started: pyqtSignal = pyqtSignal()
signal_result = pyqtSignal(object) signal_result: pyqtSignal = pyqtSignal(object)
signal_finished = pyqtSignal() signal_finished: pyqtSignal = pyqtSignal()
signal_progress = pyqtSignal(str) signal_progress: pyqtSignal = pyqtSignal(str)
class Worker(QRunnable): class Worker(QRunnable):
@ -46,12 +46,12 @@ class Worker(QRunnable):
:param kwargs: Keywords to pass to the callback function :param kwargs: Keywords to pass to the callback function
""" """
def __init__(self, fn, *args, **kwargs): def __init__(self, fn, *args: object, **kwargs: object):
super(Worker, self).__init__() super(Worker, self).__init__()
# Store constructor arguments (re-used for processing) # Store constructor arguments (re-used for processing)
self.fn = fn self.fn = fn
self.args = args self.args: object = args
self.kwargs = kwargs self.kwargs: object = kwargs
self.signals: WorkerSignals = WorkerSignals() self.signals: WorkerSignals = WorkerSignals()
# Add a callback to our kwargs # Add a callback to our kwargs