Recover from git cockup: reimplement template management
This commit is contained in:
parent
a8931e8b2b
commit
68e524594d
@ -73,7 +73,6 @@ class PlaylistsTable(Model):
|
||||
tab: Mapped[Optional[int]] = mapped_column(default=None)
|
||||
open: Mapped[bool] = mapped_column(default=False)
|
||||
is_template: Mapped[bool] = mapped_column(default=False)
|
||||
deleted: Mapped[bool] = mapped_column(default=False)
|
||||
rows: Mapped[List["PlaylistRowsTable"]] = relationship(
|
||||
"PlaylistRowsTable",
|
||||
back_populates="playlist",
|
||||
|
||||
@ -225,10 +225,10 @@ class Playlists(dbtables.PlaylistsTable):
|
||||
|
||||
def delete(self, session: Session) -> None:
|
||||
"""
|
||||
Mark as deleted
|
||||
Delete playlist
|
||||
"""
|
||||
|
||||
self.deleted = True
|
||||
session.execute(delete(Playlists).where(Playlists.id == self.id))
|
||||
session.commit()
|
||||
|
||||
@classmethod
|
||||
|
||||
@ -51,6 +51,7 @@ import stackprinter # type: ignore
|
||||
|
||||
# App imports
|
||||
from classes import (
|
||||
ApplicationError,
|
||||
MusicMusterSignals,
|
||||
TrackInfo,
|
||||
)
|
||||
@ -96,6 +97,64 @@ class Current:
|
||||
)
|
||||
|
||||
|
||||
class EditDeleteDialog(QDialog):
|
||||
def __init__(self, templates: list[tuple[str, int]]) -> None:
|
||||
super().__init__()
|
||||
self.templates = templates
|
||||
self.selection: tuple[str, int] = ("", -1)
|
||||
|
||||
self.init_ui()
|
||||
|
||||
def init_ui(self) -> None:
|
||||
# Create label
|
||||
label = QLabel("Select template:")
|
||||
|
||||
# Create combo box
|
||||
self.combo_box = QComboBox()
|
||||
for text, id_ in self.templates:
|
||||
self.combo_box.addItem(text, id_)
|
||||
|
||||
# Create buttons
|
||||
edit_button = QPushButton("Edit")
|
||||
delete_button = QPushButton("Delete")
|
||||
cancel_button = QPushButton("Cancel")
|
||||
|
||||
# Connect buttons
|
||||
edit_button.clicked.connect(self.edit_clicked)
|
||||
delete_button.clicked.connect(self.delete_clicked)
|
||||
cancel_button.clicked.connect(self.cancel_clicked)
|
||||
|
||||
# Layout setup
|
||||
top_layout = QHBoxLayout()
|
||||
top_layout.addWidget(label)
|
||||
top_layout.addWidget(self.combo_box)
|
||||
|
||||
bottom_layout = QHBoxLayout()
|
||||
bottom_layout.addStretch()
|
||||
bottom_layout.addWidget(edit_button)
|
||||
bottom_layout.addWidget(delete_button)
|
||||
bottom_layout.addWidget(cancel_button)
|
||||
|
||||
main_layout = QVBoxLayout()
|
||||
main_layout.addLayout(top_layout)
|
||||
main_layout.addLayout(bottom_layout)
|
||||
|
||||
self.setLayout(main_layout)
|
||||
self.setWindowTitle("Edit or Delete Template")
|
||||
|
||||
def edit_clicked(self) -> None:
|
||||
self.selection = ("Edit", self.combo_box.currentData())
|
||||
self.accept()
|
||||
|
||||
def delete_clicked(self) -> None:
|
||||
self.selection = ("Delete", self.combo_box.currentData())
|
||||
self.accept()
|
||||
|
||||
def cancel_clicked(self) -> None:
|
||||
self.selection = ("Cancelled", -1)
|
||||
self.reject()
|
||||
|
||||
|
||||
class PreviewManager:
|
||||
"""
|
||||
Manage track preview player
|
||||
@ -803,8 +862,12 @@ class Window(QMainWindow, Ui_MainWindow):
|
||||
dlg.resize(500, 100)
|
||||
ok = dlg.exec()
|
||||
if ok:
|
||||
if self.current.selected_rows:
|
||||
new_row_number = self.current.selected_rows[0]
|
||||
else:
|
||||
new_row_number = self.current.base_model.rowCount()
|
||||
self.current.base_model.insert_row(
|
||||
proposed_row_number=self.current.selected_rows[0],
|
||||
proposed_row_number=new_row_number,
|
||||
note=dlg.textValue(),
|
||||
)
|
||||
|
||||
@ -870,6 +933,46 @@ class Window(QMainWindow, Ui_MainWindow):
|
||||
|
||||
self.signals.search_wikipedia_signal.emit(track_info.title)
|
||||
|
||||
def manage_templates(self) -> None:
|
||||
"""
|
||||
Delete / edit templates
|
||||
"""
|
||||
|
||||
# Build a list of (template-name, playlist-id) tuples
|
||||
template_list: list[tuple[str, int]] = []
|
||||
|
||||
with db.Session() as session:
|
||||
for template in Playlists.get_all_templates(session):
|
||||
template_list.append((template.name, template.id))
|
||||
|
||||
# Get user's selection
|
||||
dlg = EditDeleteDialog(template_list)
|
||||
if not dlg.exec():
|
||||
return # User cancelled
|
||||
|
||||
action, template_id = dlg.selection
|
||||
|
||||
playlist = session.get(Playlists, template_id)
|
||||
if not playlist:
|
||||
log.error(f"Error opening {template_id=}")
|
||||
|
||||
if action == "Edit":
|
||||
# Simply load the template as a playlist. Any changes
|
||||
# made will persist
|
||||
idx = self.create_playlist_tab(playlist)
|
||||
self.tabPlaylist.setCurrentIndex(idx)
|
||||
|
||||
elif action == "Delete":
|
||||
if helpers.ask_yes_no(
|
||||
"Delete template",
|
||||
f"Delete template '{playlist.name}': " "Are you sure?",
|
||||
):
|
||||
if self.close_playlist_tab():
|
||||
playlist.delete(session)
|
||||
session.commit()
|
||||
else:
|
||||
raise ApplicationError(f"Unrecognised action from EditDeleteDialog: {action=}")
|
||||
|
||||
def mark_rows_for_moving(self) -> None:
|
||||
"""
|
||||
Cut rows ready for pasting.
|
||||
|
||||
@ -677,5 +677,5 @@ class Ui_MainWindow(object):
|
||||
self.actionSearch_title_in_Songfacts.setShortcut(_translate("MainWindow", "Ctrl+S"))
|
||||
self.actionSelect_duplicate_rows.setText(_translate("MainWindow", "Select duplicate rows..."))
|
||||
self.actionReplace_files.setText(_translate("MainWindow", "Import files..."))
|
||||
from infotabs import InfoTabs
|
||||
from pyqtgraph import PlotWidget
|
||||
from infotabs import InfoTabs # type: ignore
|
||||
from pyqtgraph import PlotWidget # type: ignore
|
||||
|
||||
@ -0,0 +1,52 @@
|
||||
"""Remove playlists.delete and implement Cascade deletes
|
||||
|
||||
Revision ID: 33c04e3c12c8
|
||||
Revises: 164bd5ef3074
|
||||
Create Date: 2024-12-29 17:56:00.627198
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.dialects import mysql
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '33c04e3c12c8'
|
||||
down_revision = '164bd5ef3074'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade(engine_name: str) -> None:
|
||||
globals()["upgrade_%s" % engine_name]()
|
||||
|
||||
|
||||
def downgrade(engine_name: str) -> None:
|
||||
globals()["downgrade_%s" % engine_name]()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def upgrade_() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
with op.batch_alter_table('playlist_rows', schema=None) as batch_op:
|
||||
batch_op.drop_constraint('playlist_rows_ibfk_3', type_='foreignkey')
|
||||
batch_op.create_foreign_key('playlist_rows_ibfk_3', 'playlists', ['playlist_id'], ['id'], ondelete='CASCADE')
|
||||
|
||||
with op.batch_alter_table('playlists', schema=None) as batch_op:
|
||||
batch_op.drop_column('deleted')
|
||||
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade_() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
with op.batch_alter_table('playlists', schema=None) as batch_op:
|
||||
batch_op.add_column(sa.Column('deleted', mysql.TINYINT(display_width=1), autoincrement=False, nullable=False))
|
||||
|
||||
with op.batch_alter_table('playlist_rows', schema=None) as batch_op:
|
||||
batch_op.drop_constraint(None, type_='foreignkey')
|
||||
batch_op.create_foreign_key(None, 'playlists', ['playlist_id'], ['id'])
|
||||
|
||||
# ### end Alembic commands ###
|
||||
|
||||
Loading…
Reference in New Issue
Block a user