diff --git a/tagstudio/src/qt/helpers/file_deleter.py b/tagstudio/src/qt/helpers/file_deleter.py new file mode 100644 index 000000000..3e99b6963 --- /dev/null +++ b/tagstudio/src/qt/helpers/file_deleter.py @@ -0,0 +1,38 @@ +import logging +import traceback +from pathlib import Path +from collections.abc import Callable + +ERROR = f"[ERROR]" +WARNING = f"[WARNING]" +INFO = f"[INFO]" + +logging.basicConfig(format="%(message)s", level=logging.INFO) + + +def delete_file(path: str | Path, callback: Callable): + _path = str(path) + _file = Path(_path) + logging.info(f"Deleting file: {_path}") + if not _file.exists(): + logging.error(f"File not found: {_path}") + return + try: + _file.unlink() + callback() + except Exception as exception: + logging.exception(exception) + + +class FileDeleterHelper: + def __init__(self, filepath: str | Path): + self.filepath = filepath + + def set_filepath(self, filepath: str | Path): + self.filepath = filepath + + def set_delete_callback(self, callback: Callable): + self.delete_callback = callback + + def delete_file(self): + delete_file(self.filepath, self.delete_callback) diff --git a/tagstudio/src/qt/widgets/item_thumb.py b/tagstudio/src/qt/widgets/item_thumb.py index fdeb6739e..e7b3223e7 100644 --- a/tagstudio/src/qt/widgets/item_thumb.py +++ b/tagstudio/src/qt/widgets/item_thumb.py @@ -30,6 +30,7 @@ from src.core.media_types import MediaCategories, MediaType from src.qt.flowlayout import FlowWidget from src.qt.helpers.file_opener import FileOpenerHelper +from src.qt.helpers.file_deleter import FileDeleterHelper from src.qt.widgets.thumb_renderer import ThumbRenderer from src.qt.widgets.thumb_button import ThumbButton @@ -191,12 +192,16 @@ def __init__( self.thumb_button.setContextMenuPolicy(Qt.ContextMenuPolicy.ActionsContextMenu) self.opener = FileOpenerHelper("") + self.deleter = FileDeleterHelper("") open_file_action = QAction("Open file", self) open_file_action.triggered.connect(self.opener.open_file) open_explorer_action = QAction("Open file in explorer", self) open_explorer_action.triggered.connect(self.opener.open_explorer) + delete_action = QAction("Delete", self) + delete_action.triggered.connect(self.deleter.delete_file) self.thumb_button.addAction(open_file_action) self.thumb_button.addAction(open_explorer_action) + self.thumb_button.addAction(delete_action) # Static Badges ======================================================== @@ -435,6 +440,8 @@ def set_item_id(self, id: int): entry = self.lib.get_entry(self.item_id) filepath = self.lib.library_dir / entry.path / entry.filename self.opener.set_filepath(filepath) + self.deleter.set_filepath(filepath) + self.deleter.set_delete_callback(self._on_delete) def assign_favorite(self, value: bool): # Switching mode to None to bypass mode-specific operations when the @@ -513,6 +520,12 @@ def toggle_tag(entry: Entry): self.panel.update_widgets() self.panel.driver.update_badges() + def _on_delete(self): + entry = self.lib.get_entry(self.item_id) + self.lib.remove_entry(self.item_id) + self.panel.driver.purge_item_from_navigation(entry.type, self.item_id) + self.panel.driver.filter_items() + def mouseMoveEvent(self, event): if event.buttons() is not Qt.MouseButton.LeftButton: return