Slideshow blacklist buttons, Ctrl+C copy, fix README code blocks
- BL Tag button in slideshow: opens categorized tag menu - BL Post button in slideshow: blacklists current post - Ctrl+C copies preview image to clipboard - "Copy Image to Clipboard" in grid right-click menu - Fix README code block formatting (missing closing backticks) - Add ffmpeg back to Linux install deps
This commit is contained in:
parent
04ffe5c602
commit
ac2c15be29
@ -91,15 +91,18 @@ Requires Python 3.11+ and pip. Most distros ship Python but you may need to inst
|
|||||||
|
|
||||||
**Arch / CachyOS:**
|
**Arch / CachyOS:**
|
||||||
```sh
|
```sh
|
||||||
sudo pacman -S python python-pip qt6-base qt6-multimedia qt6-multimedia-ffmpeg```
|
sudo pacman -S python python-pip qt6-base qt6-multimedia qt6-multimedia-ffmpeg ffmpeg
|
||||||
|
```
|
||||||
|
|
||||||
**Ubuntu / Debian (24.04+):**
|
**Ubuntu / Debian (24.04+):**
|
||||||
```sh
|
```sh
|
||||||
sudo apt install python3 python3-pip python3-venv libqt6multimedia6 gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-libav```
|
sudo apt install python3 python3-pip python3-venv libqt6multimedia6 gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-libav ffmpeg
|
||||||
|
```
|
||||||
|
|
||||||
**Fedora:**
|
**Fedora:**
|
||||||
```sh
|
```sh
|
||||||
sudo dnf install python3 python3-pip qt6-qtbase qt6-qtmultimedia gstreamer1-plugins-good gstreamer1-plugins-bad-free gstreamer1-libav```
|
sudo dnf install python3 python3-pip qt6-qtbase qt6-qtmultimedia gstreamer1-plugins-good gstreamer1-plugins-bad-free gstreamer1-libav ffmpeg
|
||||||
|
```
|
||||||
|
|
||||||
Then clone and install:
|
Then clone and install:
|
||||||
```sh
|
```sh
|
||||||
|
|||||||
@ -992,6 +992,8 @@ class BooruApp(QMainWindow):
|
|||||||
show = self._stack.currentIndex() != 2
|
show = self._stack.currentIndex() != 2
|
||||||
self._fullscreen_window._bookmark_btn.setVisible(show)
|
self._fullscreen_window._bookmark_btn.setVisible(show)
|
||||||
self._fullscreen_window._save_btn.setVisible(show)
|
self._fullscreen_window._save_btn.setVisible(show)
|
||||||
|
self._fullscreen_window._bl_tag_btn.setVisible(show)
|
||||||
|
self._fullscreen_window._bl_post_btn.setVisible(show)
|
||||||
if show:
|
if show:
|
||||||
self._update_fullscreen_state()
|
self._update_fullscreen_state()
|
||||||
|
|
||||||
@ -1041,6 +1043,7 @@ class BooruApp(QMainWindow):
|
|||||||
if saved:
|
if saved:
|
||||||
break
|
break
|
||||||
self._fullscreen_window.update_state(bookmarked, saved)
|
self._fullscreen_window.update_state(bookmarked, saved)
|
||||||
|
self._fullscreen_window.set_post_tags(post.tag_categories, post.tag_list)
|
||||||
else:
|
else:
|
||||||
self._fullscreen_window.update_state(False, False)
|
self._fullscreen_window.update_state(False, False)
|
||||||
|
|
||||||
@ -1222,6 +1225,31 @@ class BooruApp(QMainWindow):
|
|||||||
else:
|
else:
|
||||||
self._save_from_preview("")
|
self._save_from_preview("")
|
||||||
|
|
||||||
|
def _blacklist_tag_from_slideshow(self, tag: str) -> None:
|
||||||
|
self._db.add_blacklisted_tag(tag)
|
||||||
|
self._db.set_setting("blacklist_enabled", "1")
|
||||||
|
# Clear slideshow if previewed post has this tag
|
||||||
|
idx = self._grid.selected_index
|
||||||
|
if 0 <= idx < len(self._posts) and tag in self._posts[idx].tag_list:
|
||||||
|
self._preview.clear()
|
||||||
|
if self._fullscreen_window:
|
||||||
|
self._fullscreen_window._viewer.clear()
|
||||||
|
self._fullscreen_window._video.stop()
|
||||||
|
self._status.showMessage(f"Blacklisted: {tag}")
|
||||||
|
self._do_search()
|
||||||
|
|
||||||
|
def _blacklist_post_from_slideshow(self) -> None:
|
||||||
|
idx = self._grid.selected_index
|
||||||
|
if 0 <= idx < len(self._posts):
|
||||||
|
post = self._posts[idx]
|
||||||
|
self._db.add_blacklisted_post(post.file_url)
|
||||||
|
self._preview.clear()
|
||||||
|
if self._fullscreen_window:
|
||||||
|
self._fullscreen_window._viewer.clear()
|
||||||
|
self._fullscreen_window._video.stop()
|
||||||
|
self._status.showMessage(f"Post #{post.id} blacklisted")
|
||||||
|
self._do_search()
|
||||||
|
|
||||||
def _open_fullscreen_preview(self) -> None:
|
def _open_fullscreen_preview(self) -> None:
|
||||||
path = self._preview._current_path
|
path = self._preview._current_path
|
||||||
if not path:
|
if not path:
|
||||||
@ -1253,6 +1281,8 @@ class BooruApp(QMainWindow):
|
|||||||
if show_actions:
|
if show_actions:
|
||||||
self._fullscreen_window.bookmark_requested.connect(self._bookmark_from_preview)
|
self._fullscreen_window.bookmark_requested.connect(self._bookmark_from_preview)
|
||||||
self._fullscreen_window.save_toggle_requested.connect(self._save_toggle_from_slideshow)
|
self._fullscreen_window.save_toggle_requested.connect(self._save_toggle_from_slideshow)
|
||||||
|
self._fullscreen_window.blacklist_tag_requested.connect(self._blacklist_tag_from_slideshow)
|
||||||
|
self._fullscreen_window.blacklist_post_requested.connect(self._blacklist_post_from_slideshow)
|
||||||
self._fullscreen_window.closed.connect(self._on_fullscreen_closed)
|
self._fullscreen_window.closed.connect(self._on_fullscreen_closed)
|
||||||
self._fullscreen_window.privacy_requested.connect(self._toggle_privacy)
|
self._fullscreen_window.privacy_requested.connect(self._toggle_privacy)
|
||||||
# Sync video player state from preview to slideshow
|
# Sync video player state from preview to slideshow
|
||||||
@ -1363,6 +1393,7 @@ class BooruApp(QMainWindow):
|
|||||||
save_lib_new = save_lib_menu.addAction("+ New Folder...")
|
save_lib_new = save_lib_menu.addAction("+ New Folder...")
|
||||||
|
|
||||||
unsave_lib = menu.addAction("Unsave from Library")
|
unsave_lib = menu.addAction("Unsave from Library")
|
||||||
|
copy_clipboard = menu.addAction("Copy Image to Clipboard")
|
||||||
copy_url = menu.addAction("Copy Image URL")
|
copy_url = menu.addAction("Copy Image URL")
|
||||||
copy_tags = menu.addAction("Copy Tags")
|
copy_tags = menu.addAction("Copy Tags")
|
||||||
menu.addSeparator()
|
menu.addSeparator()
|
||||||
@ -1415,6 +1446,8 @@ class BooruApp(QMainWindow):
|
|||||||
self._grid._thumbs[index].set_saved_locally(False)
|
self._grid._thumbs[index].set_saved_locally(False)
|
||||||
else:
|
else:
|
||||||
self._status.showMessage(f"#{post.id} not in library")
|
self._status.showMessage(f"#{post.id} not in library")
|
||||||
|
elif action == copy_clipboard:
|
||||||
|
self._copy_preview_to_clipboard()
|
||||||
elif action == copy_url:
|
elif action == copy_url:
|
||||||
QApplication.clipboard().setText(post.file_url)
|
QApplication.clipboard().setText(post.file_url)
|
||||||
self._status.showMessage("URL copied")
|
self._status.showMessage("URL copied")
|
||||||
@ -1848,8 +1881,16 @@ class BooruApp(QMainWindow):
|
|||||||
if self._preview._stack.currentIndex() == 1 and self._preview.underMouse():
|
if self._preview._stack.currentIndex() == 1 and self._preview.underMouse():
|
||||||
self._preview._video_player._toggle_play()
|
self._preview._video_player._toggle_play()
|
||||||
return
|
return
|
||||||
|
elif key == Qt.Key.Key_C and event.modifiers() == Qt.KeyboardModifier.ControlModifier:
|
||||||
|
self._copy_preview_to_clipboard()
|
||||||
|
return
|
||||||
super().keyPressEvent(event)
|
super().keyPressEvent(event)
|
||||||
|
|
||||||
|
def _copy_preview_to_clipboard(self) -> None:
|
||||||
|
if self._preview._image_viewer._pixmap and not self._preview._image_viewer._pixmap.isNull():
|
||||||
|
QApplication.clipboard().setPixmap(self._preview._image_viewer._pixmap)
|
||||||
|
self._status.showMessage("Image copied to clipboard")
|
||||||
|
|
||||||
# -- Bookmarks --
|
# -- Bookmarks --
|
||||||
|
|
||||||
def _toggle_bookmark(self, index: int) -> None:
|
def _toggle_bookmark(self, index: int) -> None:
|
||||||
|
|||||||
@ -28,6 +28,8 @@ class FullscreenPreview(QMainWindow):
|
|||||||
navigate = Signal(int) # direction: -1/+1 for left/right, -cols/+cols for up/down
|
navigate = Signal(int) # direction: -1/+1 for left/right, -cols/+cols for up/down
|
||||||
bookmark_requested = Signal()
|
bookmark_requested = Signal()
|
||||||
save_toggle_requested = Signal() # save or unsave depending on state
|
save_toggle_requested = Signal() # save or unsave depending on state
|
||||||
|
blacklist_tag_requested = Signal(str) # tag name
|
||||||
|
blacklist_post_requested = Signal()
|
||||||
privacy_requested = Signal()
|
privacy_requested = Signal()
|
||||||
closed = Signal()
|
closed = Signal()
|
||||||
|
|
||||||
@ -58,9 +60,23 @@ class FullscreenPreview(QMainWindow):
|
|||||||
toolbar.addWidget(self._save_btn)
|
toolbar.addWidget(self._save_btn)
|
||||||
self._is_saved = False
|
self._is_saved = False
|
||||||
|
|
||||||
|
self._bl_tag_btn = QPushButton("BL Tag")
|
||||||
|
self._bl_tag_btn.setFixedWidth(60)
|
||||||
|
self._bl_tag_btn.setToolTip("Blacklist a tag")
|
||||||
|
self._bl_tag_btn.clicked.connect(self._show_bl_tag_menu)
|
||||||
|
toolbar.addWidget(self._bl_tag_btn)
|
||||||
|
|
||||||
|
self._bl_post_btn = QPushButton("BL Post")
|
||||||
|
self._bl_post_btn.setFixedWidth(65)
|
||||||
|
self._bl_post_btn.setToolTip("Blacklist this post")
|
||||||
|
self._bl_post_btn.clicked.connect(self.blacklist_post_requested)
|
||||||
|
toolbar.addWidget(self._bl_post_btn)
|
||||||
|
|
||||||
if not show_actions:
|
if not show_actions:
|
||||||
self._bookmark_btn.hide()
|
self._bookmark_btn.hide()
|
||||||
self._save_btn.hide()
|
self._save_btn.hide()
|
||||||
|
self._bl_tag_btn.hide()
|
||||||
|
self._bl_post_btn.hide()
|
||||||
|
|
||||||
toolbar.addStretch()
|
toolbar.addStretch()
|
||||||
|
|
||||||
@ -100,6 +116,27 @@ class FullscreenPreview(QMainWindow):
|
|||||||
self.setGeometry(target_screen.geometry())
|
self.setGeometry(target_screen.geometry())
|
||||||
self.showFullScreen()
|
self.showFullScreen()
|
||||||
|
|
||||||
|
_current_tags: dict[str, list[str]] = {}
|
||||||
|
_current_tag_list: list[str] = []
|
||||||
|
|
||||||
|
def set_post_tags(self, tag_categories: dict[str, list[str]], tag_list: list[str]) -> None:
|
||||||
|
self._current_tags = tag_categories
|
||||||
|
self._current_tag_list = tag_list
|
||||||
|
|
||||||
|
def _show_bl_tag_menu(self) -> None:
|
||||||
|
menu = QMenu(self)
|
||||||
|
if self._current_tags:
|
||||||
|
for category, tags in self._current_tags.items():
|
||||||
|
cat_menu = menu.addMenu(category)
|
||||||
|
for tag in tags[:30]:
|
||||||
|
cat_menu.addAction(tag)
|
||||||
|
else:
|
||||||
|
for tag in self._current_tag_list[:30]:
|
||||||
|
menu.addAction(tag)
|
||||||
|
action = menu.exec(self._bl_tag_btn.mapToGlobal(self._bl_tag_btn.rect().bottomLeft()))
|
||||||
|
if action:
|
||||||
|
self.blacklist_tag_requested.emit(action.text())
|
||||||
|
|
||||||
def update_state(self, bookmarked: bool, saved: bool) -> None:
|
def update_state(self, bookmarked: bool, saved: bool) -> None:
|
||||||
self._bookmark_btn.setText("Unbookmark" if bookmarked else "Bookmark")
|
self._bookmark_btn.setText("Unbookmark" if bookmarked else "Bookmark")
|
||||||
self._bookmark_btn.setFixedWidth(90 if bookmarked else 80)
|
self._bookmark_btn.setFixedWidth(90 if bookmarked else 80)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user