diff --git a/app/dbtables.py b/app/dbtables.py index e89a3b9..c2da638 100644 --- a/app/dbtables.py +++ b/app/dbtables.py @@ -73,6 +73,7 @@ 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", diff --git a/app/models.py b/app/models.py index a5f0936..1d5f7ea 100644 --- a/app/models.py +++ b/app/models.py @@ -225,10 +225,10 @@ class Playlists(dbtables.PlaylistsTable): def delete(self, session: Session) -> None: """ - Delete playlist + Mark as deleted """ - session.execute(delete(Playlists).where(Playlists.id == self.id)) + self.deleted = True session.commit() @classmethod diff --git a/app/musicmuster.py b/app/musicmuster.py index a9bdc91..8cc75a1 100755 --- a/app/musicmuster.py +++ b/app/musicmuster.py @@ -51,7 +51,6 @@ import stackprinter # type: ignore # App imports from classes import ( - ApplicationError, MusicMusterSignals, TrackInfo, ) @@ -97,64 +96,6 @@ 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 @@ -862,12 +803,8 @@ 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=new_row_number, + proposed_row_number=self.current.selected_rows[0], note=dlg.textValue(), ) @@ -933,46 +870,6 @@ 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. diff --git a/app/ui/main_window_ui.py b/app/ui/main_window_ui.py index a763a63..ddeace6 100644 --- a/app/ui/main_window_ui.py +++ b/app/ui/main_window_ui.py @@ -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 # type: ignore -from pyqtgraph import PlotWidget # type: ignore +from infotabs import InfoTabs +from pyqtgraph import PlotWidget diff --git a/migrations/versions/33c04e3c12c8_remove_playlists_delete_and_implement_.py b/migrations/versions/33c04e3c12c8_remove_playlists_delete_and_implement_.py deleted file mode 100644 index d84c19f..0000000 --- a/migrations/versions/33c04e3c12c8_remove_playlists_delete_and_implement_.py +++ /dev/null @@ -1,52 +0,0 @@ -"""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 ### -