Skip to content

refactor(preview_panel): mvc split #952

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ qt_api = "pyside6"

[tool.pyright]
ignore = [".venv/**"]
include = ["src/tagstudio/**"]
include = ["src/tagstudio", "tests"]
extraPaths = ["src/tagstudio", "tests"]
reportAny = false
reportIgnoreCommentWithoutRule = false
reportImplicitStringConcatenation = false
Expand Down
2 changes: 1 addition & 1 deletion src/tagstudio/core/library/alchemy/library.py
Original file line number Diff line number Diff line change
Expand Up @@ -674,7 +674,7 @@ def get_entry_full(
start_time = time.time()
entry = session.scalar(entry_stmt)
if with_tags:
tags = set(session.scalars(tag_stmt)) # pyright: ignore [reportPossiblyUnboundVariable]
tags = set(session.scalars(tag_stmt)) # pyright: ignore[reportPossiblyUnboundVariable]
end_time = time.time()
logger.info(
f"[Library] Time it took to get entry: "
Expand Down
44 changes: 44 additions & 0 deletions src/tagstudio/qt/controller/widgets/preview_panel_controller.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import typing
from warnings import catch_warnings

from PySide6.QtWidgets import QListWidgetItem

from tagstudio.core.library.alchemy.library import Library
from tagstudio.qt.modals.add_field import AddFieldModal
from tagstudio.qt.modals.tag_search import TagSearchModal
from tagstudio.qt.view.widgets.preview_panel_view import PreviewPanelView

if typing.TYPE_CHECKING:
from tagstudio.qt.ts_qt import QtDriver


class PreviewPanel(PreviewPanelView):
def __init__(self, library: Library, driver: "QtDriver"):
super().__init__(library, driver)

self.__add_field_modal = AddFieldModal(self.lib)
self.__add_tag_modal = TagSearchModal(self.lib, is_tag_chooser=True)

def _add_field_button_callback(self):
self.__add_field_modal.show()

def _add_tag_button_callback(self):
self.__add_tag_modal.show()

def _set_selection_callback(self):
with catch_warnings(record=True):
self.__add_field_modal.done.disconnect()
self.__add_tag_modal.tsp.tag_chosen.disconnect()

self.__add_field_modal.done.connect(self._add_field_to_selected)
self.__add_tag_modal.tsp.tag_chosen.connect(self._add_tag_to_selected)

def _add_field_to_selected(self, field_list: list[QListWidgetItem]):
self._fields.add_field_to_selected(field_list)
if len(self._selected) == 1:
self._fields.update_from_entry(self._selected[0])

def _add_tag_to_selected(self, tag_id: int):
self._fields.add_tags_to_selected(tag_id)
if len(self._selected) == 1:
self._fields.update_from_entry(self._selected[0])
2 changes: 1 addition & 1 deletion src/tagstudio/qt/main_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@

from tagstudio.core.enums import ShowFilepathOption
from tagstudio.core.library.alchemy.enums import SortingModeEnum
from tagstudio.qt.controller.widgets.preview_panel_controller import PreviewPanel
from tagstudio.qt.flowlayout import FlowLayout
from tagstudio.qt.pagination import Pagination
from tagstudio.qt.platform_strings import trash_term
from tagstudio.qt.translations import Translations
from tagstudio.qt.widgets.landing import LandingWidget
from tagstudio.qt.widgets.preview_panel import PreviewPanel

# Only import for type checking/autocompletion, will not be imported at runtime.
if typing.TYPE_CHECKING:
Expand Down
9 changes: 3 additions & 6 deletions src/tagstudio/qt/modals/build_tag.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
from tagstudio.core.library.alchemy.models import Tag, TagColorGroup
from tagstudio.core.palette import ColorType, UiColor, get_tag_color, get_ui_color
from tagstudio.qt.modals.tag_color_selection import TagColorSelection
from tagstudio.qt.modals.tag_search import TagSearchPanel
from tagstudio.qt.modals.tag_search import TagSearchModal
from tagstudio.qt.translations import Translations
from tagstudio.qt.widgets.panel import PanelModal, PanelWidget
from tagstudio.qt.widgets.tag import (
Expand Down Expand Up @@ -166,11 +166,8 @@ def __init__(self, library: Library, tag: Tag | None = None) -> None:
if tag is not None:
exclude_ids.append(tag.id)

tsp = TagSearchPanel(self.lib, exclude_ids)
tsp.tag_chosen.connect(lambda x: self.add_parent_tag_callback(x))
self.add_tag_modal = PanelModal(tsp)
self.add_tag_modal.setTitle(Translations["tag.parent_tags.add"])
self.add_tag_modal.setWindowTitle(Translations["tag.parent_tags.add"])
self.add_tag_modal = TagSearchModal(self.lib, exclude_ids)
self.add_tag_modal.tsp.tag_chosen.connect(lambda x: self.add_parent_tag_callback(x))
self.parent_tags_add_button.clicked.connect(self.add_tag_modal.show)

# Color ----------------------------------------------------------------
Expand Down
4 changes: 3 additions & 1 deletion src/tagstudio/qt/modals/folders_to_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,9 @@ def __init__(self, library: "Library", driver: "QtDriver"):
def on_apply(self, event):
folders_to_tags(self.library)
self.close()
self.driver.main_window.preview_panel.update_widgets(update_preview=False)
self.driver.main_window.preview_panel.set_selection(
self.driver.selected, update_preview=False
)

def on_open(self, event):
for i in reversed(range(self.scroll_layout.count())):
Expand Down
2 changes: 1 addition & 1 deletion src/tagstudio/qt/modals/mirror_entities.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def displayed_text(x):
pw.from_iterable_function(
self.mirror_entries_runnable,
displayed_text,
self.driver.main_window.preview_panel.update_widgets,
lambda s=self.driver.selected: self.driver.main_window.preview_panel.set_selection(s),
self.done.emit,
)

Expand Down
2 changes: 1 addition & 1 deletion src/tagstudio/qt/modals/settings_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ def update_settings(self, driver: "QtDriver"):
# Apply changes
# Show File Path
driver.update_recent_lib_menu()
driver.main_window.preview_panel.update_widgets()
driver.main_window.preview_panel.set_selection(self.driver.selected)
library_directory = driver.lib.library_dir
if settings["show_filepath"] == ShowFilepathOption.SHOW_FULL_PATHS:
display_path = library_directory or ""
Expand Down
4 changes: 2 additions & 2 deletions src/tagstudio/qt/modals/tag_color_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def setup_color_groups(self):
self.setup_color_groups(),
()
if len(self.driver.selected) < 1
else self.driver.main_window.preview_panel.fields.update_from_entry(
else self.driver.main_window.preview_panel.field_containers_widget.update_from_entry( # noqa: E501
self.driver.selected[0], update_badges=False
),
)
Expand All @@ -141,7 +141,7 @@ def setup_color_groups(self):
self.setup_color_groups(),
()
if len(self.driver.selected) < 1
else self.driver.main_window.preview_panel.fields.update_from_entry(
else self.driver.main_window.preview_panel.field_containers_widget.update_from_entry( # noqa: E501
self.driver.selected[0], update_badges=False
),
),
Expand Down
41 changes: 33 additions & 8 deletions src/tagstudio/qt/modals/tag_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@


import contextlib
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, Union
from warnings import catch_warnings

import structlog
Expand Down Expand Up @@ -39,10 +39,33 @@
from tagstudio.qt.ts_qt import QtDriver


class TagSearchModal(PanelModal):
tsp: "TagSearchPanel"

def __init__(
self,
library: Library,
exclude: list[int] | None = None,
is_tag_chooser: bool = True,
done_callback=None,
save_callback=None,
has_save=False,
):
self.tsp = TagSearchPanel(library, exclude, is_tag_chooser)
super().__init__(
self.tsp,
Translations["tag.add.plural"],
Translations["tag.add.plural"],
done_callback,
save_callback,
has_save,
)


class TagSearchPanel(PanelWidget):
tag_chosen = Signal(int)
lib: Library
driver: "QtDriver"
driver: Union["QtDriver", None]
is_initialized: bool = False
first_tag_id: int | None = None
is_tag_chooser: bool
Expand All @@ -56,7 +79,7 @@ class TagSearchPanel(PanelWidget):
def __init__(
self,
library: Library,
exclude: list[int] = None,
exclude: list[int] | None = None,
is_tag_chooser: bool = True,
):
super().__init__()
Expand Down Expand Up @@ -194,6 +217,7 @@ def update_tags(self, query: str | None = None):
create_button: QPushButton | None = None
if self.create_button_in_layout and self.scroll_layout.count():
create_button = self.scroll_layout.takeAt(self.scroll_layout.count() - 1).widget() # type: ignore
assert create_button is not None
create_button.deleteLater()
self.create_button_in_layout = False

Expand Down Expand Up @@ -264,7 +288,8 @@ def set_tag_widget(self, tag: Tag | None, index: int):
self.scroll_layout.addWidget(new_tw)

# Assign the tag to the widget at the given index.
tag_widget: TagWidget = self.scroll_layout.itemAt(index).widget()
tag_widget: TagWidget = self.scroll_layout.itemAt(index).widget() # pyright: ignore[reportAssignmentType]
assert isinstance(tag_widget, TagWidget)
tag_widget.set_tag(tag)

# Set tag widget viability and potentially return early
Expand All @@ -288,11 +313,11 @@ def set_tag_widget(self, tag: Tag | None, index: int):
tag_widget.on_remove.connect(lambda t=tag: self.delete_tag(t))
tag_widget.bg_button.clicked.connect(lambda: self.tag_chosen.emit(tag_id))

if self.driver:
if self.driver is not None:
tag_widget.search_for_tag_action.triggered.connect(
lambda checked=False, tag_id=tag.id: (
self.driver.main_window.search_field.setText(f"tag_id:{tag_id}"),
self.driver.update_browsing_state(BrowsingState.from_tag_id(tag_id)),
lambda checked=False, tag_id=tag.id, driver=self.driver: (
driver.main_window.search_field.setText(f"tag_id:{tag_id}"),
driver.update_browsing_state(BrowsingState.from_tag_id(tag_id)),
)
)
tag_widget.search_for_tag_action.setEnabled(True)
Expand Down
46 changes: 20 additions & 26 deletions src/tagstudio/qt/ts_qt.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
from tagstudio.qt.modals.settings_panel import SettingsPanel
from tagstudio.qt.modals.tag_color_manager import TagColorManager
from tagstudio.qt.modals.tag_database import TagDatabasePanel
from tagstudio.qt.modals.tag_search import TagSearchPanel
from tagstudio.qt.modals.tag_search import TagSearchModal
from tagstudio.qt.platform_strings import trash_term
from tagstudio.qt.resource_manager import ResourceManager
from tagstudio.qt.splash import Splash
Expand Down Expand Up @@ -174,7 +174,6 @@ class QtDriver(DriverMixin, QObject):
tag_manager_panel: PanelModal | None = None
color_manager_panel: TagColorManager | None = None
file_extension_panel: PanelModal | None = None
tag_search_panel: TagSearchPanel | None = None
add_tag_modal: PanelModal | None = None
folders_modal: FoldersToTagsModal
about_modal: AboutModal
Expand Down Expand Up @@ -366,8 +365,8 @@ def start(self) -> None:
# Initialize the Tag Manager panel
self.tag_manager_panel = PanelModal(
widget=TagDatabasePanel(self, self.lib),
done_callback=lambda: self.main_window.preview_panel.update_widgets(
update_preview=False
done_callback=lambda s=self.selected: self.main_window.preview_panel.set_selection(
s, update_preview=False
),
has_save=False,
)
Expand All @@ -378,17 +377,12 @@ def start(self) -> None:
self.color_manager_panel = TagColorManager(self)

# Initialize the Tag Search panel
self.tag_search_panel = TagSearchPanel(self.lib, is_tag_chooser=True)
self.tag_search_panel.set_driver(self)
self.add_tag_modal = PanelModal(
widget=self.tag_search_panel,
title=Translations["tag.add.plural"],
window_title=Translations["tag.add.plural"],
)
self.tag_search_panel.tag_chosen.connect(
lambda t: (
self.add_tag_modal = TagSearchModal(self.lib, is_tag_chooser=True)
self.add_tag_modal.tsp.set_driver(self)
self.add_tag_modal.tsp.tag_chosen.connect(
lambda t, s=self.selected: (
self.add_tags_to_selected_callback(t),
self.main_window.preview_panel.update_widgets(),
self.main_window.preview_panel.set_selection(s),
)
)

Expand Down Expand Up @@ -541,12 +535,12 @@ def create_about_modal():

self.main_window.search_field.textChanged.connect(self.update_completions_list)

self.main_window.preview_panel.fields.archived_updated.connect(
self.main_window.preview_panel.field_containers_widget.archived_updated.connect(
lambda hidden: self.update_badges(
{BadgeType.ARCHIVED: hidden}, origin_id=0, add_tags=False
)
)
self.main_window.preview_panel.fields.favorite_updated.connect(
self.main_window.preview_panel.field_containers_widget.favorite_updated.connect(
lambda hidden: self.update_badges(
{BadgeType.FAVORITE: hidden}, origin_id=0, add_tags=False
)
Expand Down Expand Up @@ -715,7 +709,7 @@ def close_library(self, is_shutdown: bool = False):
self.cached_values.sync()

# Reset library state
self.main_window.preview_panel.update_widgets()
self.main_window.preview_panel.set_selection(self.selected)
self.main_window.search_field.setText("")
scrollbar: QScrollArea = self.main_window.entry_scroll_area
scrollbar.verticalScrollBar().setValue(0)
Expand All @@ -739,7 +733,7 @@ def close_library(self, is_shutdown: bool = False):
self.set_clipboard_menu_viability()
self.set_select_actions_visibility()

self.main_window.preview_panel.update_widgets()
self.main_window.preview_panel.set_selection(self.selected)
self.main_window.toggle_landing_page(enabled=True)
self.main_window.pagination.setHidden(True)
try:
Expand Down Expand Up @@ -817,7 +811,7 @@ def select_all_action_callback(self):
self.set_clipboard_menu_viability()
self.set_select_actions_visibility()

self.main_window.preview_panel.update_widgets(update_preview=False)
self.main_window.preview_panel.set_selection(self.selected, update_preview=False)

def select_inverse_action_callback(self):
"""Invert the selection of all visible items."""
Expand All @@ -836,7 +830,7 @@ def select_inverse_action_callback(self):
self.set_clipboard_menu_viability()
self.set_select_actions_visibility()

self.main_window.preview_panel.update_widgets(update_preview=False)
self.main_window.preview_panel.set_selection(self.selected, update_preview=False)

def clear_select_action_callback(self):
self.selected.clear()
Expand All @@ -845,7 +839,7 @@ def clear_select_action_callback(self):
item.thumb_button.set_selected(False)

self.set_clipboard_menu_viability()
self.main_window.preview_panel.update_widgets()
self.main_window.preview_panel.set_selection(self.selected)

def add_tags_to_selected_callback(self, tag_ids: list[int]):
self.lib.add_tags_to_entries(self.selected, tag_ids)
Expand Down Expand Up @@ -890,7 +884,7 @@ def delete_files_callback(self, origin_path: str | Path, origin_id: int | None =
for i, tup in enumerate(pending):
e_id, f = tup
if (origin_path == f) or (not origin_path):
self.main_window.preview_panel.thumb.media_player.stop()
self.main_window.preview_panel.thumb_media_player_stop()
if delete_file(self.lib.library_dir / f):
self.main_window.status_bar.showMessage(
Translations.format(
Expand All @@ -905,7 +899,7 @@ def delete_files_callback(self, origin_path: str | Path, origin_id: int | None =

if deleted_count > 0:
self.update_browsing_state()
self.main_window.preview_panel.update_widgets()
self.main_window.preview_panel.set_selection(self.selected)

if len(self.selected) <= 1 and deleted_count == 0:
self.main_window.status_bar.showMessage(Translations["status.deleted_none"])
Expand Down Expand Up @@ -1230,7 +1224,7 @@ def paste_fields_action_callback(self):
if TAG_FAVORITE in self.copy_buffer["tags"]:
self.update_badges({BadgeType.FAVORITE: True}, origin_id=0, add_tags=False)
else:
self.main_window.preview_panel.update_widgets()
self.main_window.preview_panel.set_selection(self.selected)

def toggle_item_selection(self, item_id: int, append: bool, bridge: bool):
"""Toggle the selection of an item in the Thumbnail Grid.
Expand Down Expand Up @@ -1304,7 +1298,7 @@ def toggle_item_selection(self, item_id: int, append: bool, bridge: bool):
self.set_clipboard_menu_viability()
self.set_select_actions_visibility()

self.main_window.preview_panel.update_widgets()
self.main_window.preview_panel.set_selection(self.selected)

def set_clipboard_menu_viability(self):
if len(self.selected) == 1:
Expand Down Expand Up @@ -1748,7 +1742,7 @@ def _init_library(self, path: Path, open_status: LibraryStatus):
self.main_window.menu_bar.clear_thumb_cache_action.setEnabled(True)
self.main_window.menu_bar.folders_to_tags_action.setEnabled(True)

self.main_window.preview_panel.update_widgets()
self.main_window.preview_panel.set_selection(self.selected)

# page (re)rendering, extract eventually
self.update_browsing_state()
Expand Down
Loading