stay on selected song after sort feature

This commit is contained in:
billypom on debian 2025-04-14 18:04:16 -04:00
parent 1970235224
commit b219d0109e
3 changed files with 76 additions and 20 deletions

View File

@ -1,6 +1,9 @@
from collections.abc import Iterable
from PyQt5.QtWidgets import (
QDialog,
QPlainTextEdit,
QTableWidget,
QTableWidgetItem,
QVBoxLayout,
)
from pprint import pformat
@ -8,16 +11,45 @@ from logging import debug
class DebugWindow(QDialog):
def __init__(self, text: str):
def __init__(self, data):
"""
Shows a dialog window
data can be str, list or dict
"""
super(DebugWindow, self).__init__()
self.setWindowTitle("debug")
self.setMinimumSize(400, 400)
self.text: str = text
self.data = data
layout = QVBoxLayout()
# Labels & input fields
# debug(pformat(self.text))
self.input_field = QPlainTextEdit(pformat(self.text))
layout.addWidget(self.input_field)
if isinstance(self.data, str):
self.input_field = QPlainTextEdit(pformat(self.data))
layout.addWidget(self.input_field)
elif isinstance(self.data, list):
table = QTableWidget()
table.setRowCount(len(data))
table.setColumnCount(len(data[0]))
for ri, row_data in enumerate(data):
for ci, item in enumerate(row_data):
table.setItem(ri, ci, QTableWidgetItem(str(item)))
layout.addWidget(table)
elif isinstance(self.data, dict):
# FIXME: i wanna grow....woah
try:
table = QTableWidget()
rows = max(len(value) for value in data.keys())
table.setRowCount(rows)
table.setColumnCount(len(data))
table.setHorizontalHeaderLabels(data.keys())
for ci, (key, values) in enumerate(data.items()):
for ri, value in enumerate(values):
table.setItem(ri, ci, QTableWidgetItem(str(value)))
layout.addWidget(table)
except Exception as e:
data = str(self.data)
self.input_field = QPlainTextEdit(pformat(data + "\n\n" + str(e)))
layout.addWidget(self.input_field)
self.setLayout(layout)

View File

@ -128,6 +128,7 @@ class MusicTable(QTableView):
self.database_columns = str(self.config["table"]["columns"]).split(",")
self.vertical_scroll_position = 0
self.selected_song_filepath = ""
self.selected_song_qmodel_index: QModelIndex
self.current_song_filepath = ""
self.current_song_db_id = None
self.current_song_qmodel_index: QModelIndex
@ -356,10 +357,16 @@ class MusicTable(QTableView):
def on_sort(self):
debug("on_sort")
search_col_num = self.table_headers.index("path")
qmodel_index = self.find_qmodel_index_by_value(
selected_qmodel_index = self.find_qmodel_index_by_value(
self.model2, search_col_num, self.selected_song_filepath
)
current_qmodel_index = self.find_qmodel_index_by_value(
self.model2, search_col_num, self.current_song_filepath
)
self.set_qmodel_index(qmodel_index)
# Update the 2 QModelIndexes that we track
self.set_selected_song_qmodel_index(selected_qmodel_index)
self.set_current_song_qmodel_index(current_qmodel_index)
self.jump_to_selected_song()
self.jump_to_current_song()
# ```python
@ -377,8 +384,8 @@ class MusicTable(QTableView):
When a cell is clicked, do some stuff :)
- this func also runs when double click happens, fyi
"""
debug("on_cell_clicked")
self.set_selected_song_filepath()
self.set_selected_song_qmodel_index()
self.viewport().update() # type: ignore
def on_header_resized(self, logicalIndex, oldSize, newSize):
@ -409,7 +416,7 @@ class MusicTable(QTableView):
def on_cell_data_changed(self, topLeft: QModelIndex, bottomRight: QModelIndex):
"""Handles updating ID3 tags when data changes in a cell"""
if isinstance(self.model2, QStandardItemModel):
debug("on_cell_data_changed | doing the normal stuff")
debug("on_cell_data_changed")
# get the ID of the row that was edited
id_index = self.model2.index(topLeft.row(), 0) # ID is column 0, always
# get the db song_id from the row
@ -451,6 +458,7 @@ class MusicTable(QTableView):
# FIXME:
# TODO: make this prettier, show a table in a window instead of raw text probably
_, details = args[0][:2]
details = dict(tuple(details)[0])
if details:
window = DebugWindow(details)
window.exec_()
@ -496,7 +504,6 @@ class MusicTable(QTableView):
def delete_songs(self):
"""Asks to delete the currently selected songs from the db and music table (not the filesystem)"""
# FIXME: need to get indexes based on the proxy model
selected_filepaths = self.get_selected_songs_filepaths()
formatted_selected_filepaths = "\n".join(selected_filepaths)
question_dialog = QuestionBoxDetails(
@ -537,6 +544,15 @@ class MusicTable(QTableView):
window.refreshMusicTableSignal.connect(self.load_music_table)
window.exec_() # Display the preferences window modally
def jump_to_selected_song(self):
"""Moves screen to the selected song, and selects the row"""
debug("jump_to_selected_song")
# get the proxy model index
proxy_index = self.proxymodel.mapFromSource(self.selected_song_qmodel_index)
self.scrollTo(proxy_index)
self.selectRow(proxy_index.row())
def jump_to_current_song(self):
"""Moves screen to the currently playing song, and selects the row"""
debug("jump_to_current_song")
@ -564,7 +580,7 @@ class MusicTable(QTableView):
def show_id3_tags_debug_menu(self):
"""Shows ID3 tags for a specific .mp3 file"""
if self.get_selected_song_filepath() is not None:
window = DebugWindow(str(self.get_selected_song_metadata()))
window = DebugWindow(dict(self.get_selected_song_metadata()))
window.exec_()
def show_lyrics_menu(self):
@ -809,7 +825,7 @@ class MusicTable(QTableView):
def get_selected_songs_filepaths(self) -> list[str]:
"""
Returns a list of the filepaths for the currently selected songs, based on the proxy model
(things could be sorted differently)
(because things could be sorted differently)
"""
selected_rows = self.get_selected_rows()
filepaths = []
@ -861,10 +877,7 @@ class MusicTable(QTableView):
Sets the current song filepath to the value in column 'path' with current selected row index
also stores the QModelIndex for some useful navigation stuff
"""
# map proxy (sortable) model to the original model (used for interactions)
source_index = self.proxymodel.mapToSource(self.currentIndex())
# set the proxy model index
self.set_current_song_qmodel_index(source_index)
self.set_current_song_qmodel_index()
# update the filepath
self.current_song_filepath: str = (
self.current_song_qmodel_index.siblingAtColumn(
@ -872,9 +885,20 @@ class MusicTable(QTableView):
).data()
)
def set_current_song_qmodel_index(self, index: QModelIndex):
def set_current_song_qmodel_index(self, index = None):
if index is None:
# map proxy (sortable) model to the original model (used for interactions)
index = self.proxymodel.mapToSource(self.currentIndex())
# set the proxy model index
self.current_song_qmodel_index: QModelIndex = index
def set_selected_song_qmodel_index(self, index = None):
if index is None:
# map proxy (sortable) model to the original model (used for interactions)
index = self.proxymodel.mapToSource(self.currentIndex())
# set the proxy model index
self.selected_song_qmodel_index: QModelIndex = index
def load_qapp(self, qapp) -> None:
"""Necessary for using members and methods of main application window"""
self.qapp = qapp

View File

@ -30,14 +30,14 @@ class QuestionBoxDetails(QDialog):
layout.addWidget(label)
self.text_field = QPlainTextEdit(self.details)
layout.addWidget(self.text_field)
# cancel
cancel_button = QPushButton("cancel")
cancel_button.clicked.connect(self.cancel)
h_layout.addWidget(cancel_button)
# ok
ok_button = QPushButton("ok")
ok_button.clicked.connect(self.ok)
h_layout.addWidget(ok_button)
# cancel
cancel_button = QPushButton("cancel")
cancel_button.clicked.connect(self.cancel)
h_layout.addWidget(cancel_button)
layout.addLayout(h_layout)
self.setLayout(layout)