stay on selected song after sort feature
This commit is contained in:
parent
1970235224
commit
b219d0109e
@ -1,6 +1,9 @@
|
|||||||
|
from collections.abc import Iterable
|
||||||
from PyQt5.QtWidgets import (
|
from PyQt5.QtWidgets import (
|
||||||
QDialog,
|
QDialog,
|
||||||
QPlainTextEdit,
|
QPlainTextEdit,
|
||||||
|
QTableWidget,
|
||||||
|
QTableWidgetItem,
|
||||||
QVBoxLayout,
|
QVBoxLayout,
|
||||||
)
|
)
|
||||||
from pprint import pformat
|
from pprint import pformat
|
||||||
@ -8,16 +11,45 @@ from logging import debug
|
|||||||
|
|
||||||
|
|
||||||
class DebugWindow(QDialog):
|
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__()
|
super(DebugWindow, self).__init__()
|
||||||
self.setWindowTitle("debug")
|
self.setWindowTitle("debug")
|
||||||
self.setMinimumSize(400, 400)
|
self.setMinimumSize(400, 400)
|
||||||
self.text: str = text
|
self.data = data
|
||||||
layout = QVBoxLayout()
|
layout = QVBoxLayout()
|
||||||
|
|
||||||
# Labels & input fields
|
# Labels & input fields
|
||||||
# debug(pformat(self.text))
|
# debug(pformat(self.text))
|
||||||
self.input_field = QPlainTextEdit(pformat(self.text))
|
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)
|
layout.addWidget(self.input_field)
|
||||||
|
|
||||||
self.setLayout(layout)
|
self.setLayout(layout)
|
||||||
|
|||||||
@ -128,6 +128,7 @@ class MusicTable(QTableView):
|
|||||||
self.database_columns = str(self.config["table"]["columns"]).split(",")
|
self.database_columns = str(self.config["table"]["columns"]).split(",")
|
||||||
self.vertical_scroll_position = 0
|
self.vertical_scroll_position = 0
|
||||||
self.selected_song_filepath = ""
|
self.selected_song_filepath = ""
|
||||||
|
self.selected_song_qmodel_index: QModelIndex
|
||||||
self.current_song_filepath = ""
|
self.current_song_filepath = ""
|
||||||
self.current_song_db_id = None
|
self.current_song_db_id = None
|
||||||
self.current_song_qmodel_index: QModelIndex
|
self.current_song_qmodel_index: QModelIndex
|
||||||
@ -356,10 +357,16 @@ class MusicTable(QTableView):
|
|||||||
def on_sort(self):
|
def on_sort(self):
|
||||||
debug("on_sort")
|
debug("on_sort")
|
||||||
search_col_num = self.table_headers.index("path")
|
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.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()
|
self.jump_to_current_song()
|
||||||
|
|
||||||
# ```python
|
# ```python
|
||||||
@ -377,8 +384,8 @@ class MusicTable(QTableView):
|
|||||||
When a cell is clicked, do some stuff :)
|
When a cell is clicked, do some stuff :)
|
||||||
- this func also runs when double click happens, fyi
|
- this func also runs when double click happens, fyi
|
||||||
"""
|
"""
|
||||||
debug("on_cell_clicked")
|
|
||||||
self.set_selected_song_filepath()
|
self.set_selected_song_filepath()
|
||||||
|
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, oldSize, newSize):
|
||||||
@ -409,7 +416,7 @@ class MusicTable(QTableView):
|
|||||||
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"""
|
||||||
if isinstance(self.model2, QStandardItemModel):
|
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
|
# get the ID of the row that was edited
|
||||||
id_index = self.model2.index(topLeft.row(), 0) # ID is column 0, always
|
id_index = self.model2.index(topLeft.row(), 0) # ID is column 0, always
|
||||||
# get the db song_id from the row
|
# get the db song_id from the row
|
||||||
@ -451,6 +458,7 @@ class MusicTable(QTableView):
|
|||||||
# FIXME:
|
# FIXME:
|
||||||
# TODO: make this prettier, show a table in a window instead of raw text probably
|
# TODO: make this prettier, show a table in a window instead of raw text probably
|
||||||
_, details = args[0][:2]
|
_, details = args[0][:2]
|
||||||
|
details = dict(tuple(details)[0])
|
||||||
if details:
|
if details:
|
||||||
window = DebugWindow(details)
|
window = DebugWindow(details)
|
||||||
window.exec_()
|
window.exec_()
|
||||||
@ -496,7 +504,6 @@ class MusicTable(QTableView):
|
|||||||
|
|
||||||
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: need to get indexes based on the proxy model
|
|
||||||
selected_filepaths = self.get_selected_songs_filepaths()
|
selected_filepaths = self.get_selected_songs_filepaths()
|
||||||
formatted_selected_filepaths = "\n".join(selected_filepaths)
|
formatted_selected_filepaths = "\n".join(selected_filepaths)
|
||||||
question_dialog = QuestionBoxDetails(
|
question_dialog = QuestionBoxDetails(
|
||||||
@ -537,6 +544,15 @@ class MusicTable(QTableView):
|
|||||||
window.refreshMusicTableSignal.connect(self.load_music_table)
|
window.refreshMusicTableSignal.connect(self.load_music_table)
|
||||||
window.exec_() # Display the preferences window modally
|
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):
|
def jump_to_current_song(self):
|
||||||
"""Moves screen to the currently playing song, and selects the row"""
|
"""Moves screen to the currently playing song, and selects the row"""
|
||||||
debug("jump_to_current_song")
|
debug("jump_to_current_song")
|
||||||
@ -564,7 +580,7 @@ class MusicTable(QTableView):
|
|||||||
def show_id3_tags_debug_menu(self):
|
def show_id3_tags_debug_menu(self):
|
||||||
"""Shows ID3 tags for a specific .mp3 file"""
|
"""Shows ID3 tags for a specific .mp3 file"""
|
||||||
if self.get_selected_song_filepath() is not None:
|
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_()
|
window.exec_()
|
||||||
|
|
||||||
def show_lyrics_menu(self):
|
def show_lyrics_menu(self):
|
||||||
@ -809,7 +825,7 @@ class MusicTable(QTableView):
|
|||||||
def get_selected_songs_filepaths(self) -> list[str]:
|
def get_selected_songs_filepaths(self) -> list[str]:
|
||||||
"""
|
"""
|
||||||
Returns a list of the filepaths for the currently selected songs, based on the proxy model
|
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()
|
selected_rows = self.get_selected_rows()
|
||||||
filepaths = []
|
filepaths = []
|
||||||
@ -861,10 +877,7 @@ class MusicTable(QTableView):
|
|||||||
Sets the current song filepath to the value in column 'path' with current selected row index
|
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
|
also stores the QModelIndex for some useful navigation stuff
|
||||||
"""
|
"""
|
||||||
# map proxy (sortable) model to the original model (used for interactions)
|
self.set_current_song_qmodel_index()
|
||||||
source_index = self.proxymodel.mapToSource(self.currentIndex())
|
|
||||||
# set the proxy model index
|
|
||||||
self.set_current_song_qmodel_index(source_index)
|
|
||||||
# update the filepath
|
# update the filepath
|
||||||
self.current_song_filepath: str = (
|
self.current_song_filepath: str = (
|
||||||
self.current_song_qmodel_index.siblingAtColumn(
|
self.current_song_qmodel_index.siblingAtColumn(
|
||||||
@ -872,9 +885,20 @@ class MusicTable(QTableView):
|
|||||||
).data()
|
).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
|
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:
|
def load_qapp(self, qapp) -> None:
|
||||||
"""Necessary for using members and methods of main application window"""
|
"""Necessary for using members and methods of main application window"""
|
||||||
self.qapp = qapp
|
self.qapp = qapp
|
||||||
|
|||||||
@ -30,14 +30,14 @@ class QuestionBoxDetails(QDialog):
|
|||||||
layout.addWidget(label)
|
layout.addWidget(label)
|
||||||
self.text_field = QPlainTextEdit(self.details)
|
self.text_field = QPlainTextEdit(self.details)
|
||||||
layout.addWidget(self.text_field)
|
layout.addWidget(self.text_field)
|
||||||
# cancel
|
|
||||||
cancel_button = QPushButton("cancel")
|
|
||||||
cancel_button.clicked.connect(self.cancel)
|
|
||||||
h_layout.addWidget(cancel_button)
|
|
||||||
# ok
|
# ok
|
||||||
ok_button = QPushButton("ok")
|
ok_button = QPushButton("ok")
|
||||||
ok_button.clicked.connect(self.ok)
|
ok_button.clicked.connect(self.ok)
|
||||||
h_layout.addWidget(ok_button)
|
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)
|
layout.addLayout(h_layout)
|
||||||
self.setLayout(layout)
|
self.setLayout(layout)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user