diff --git a/tagstudio/src/core/library/alchemy/library.py b/tagstudio/src/core/library/alchemy/library.py index 447b5d69..7c21c9cd 100644 --- a/tagstudio/src/core/library/alchemy/library.py +++ b/tagstudio/src/core/library/alchemy/library.py @@ -420,7 +420,7 @@ class Library: return entry def get_entry_full(self, entry_id: int) -> Entry | None: - """Load entry an join with all joins and all tags.""" + """Load entry and join with all joins and all tags.""" with Session(self.engine) as session: statement = select(Entry).where(Entry.id == entry_id) statement = ( @@ -454,7 +454,9 @@ class Library: if with_joins: # load Entry with all joins and all tags stmt = ( - stmt.outerjoin(Entry.text_fields).outerjoin(Entry.datetime_fields) + stmt.outerjoin(Entry.text_fields) + .outerjoin(Entry.datetime_fields) + .outerjoin(Entry.tags) # .outerjoin(Entry.tag_box_fields) ) stmt = stmt.options( @@ -935,6 +937,7 @@ class Library: return None def add_tags_to_entry(self, entry_id: int, tag_ids: int | list[int] | set[int]) -> bool: + """Add one or more tags to an entry.""" tag_ids_ = [tag_ids] if isinstance(tag_ids, int) else tag_ids with Session(self.engine, expire_on_commit=False) as session: try: @@ -943,6 +946,30 @@ class Library: session.flush() session.commit() return True + except IntegrityError as e: + logger.warning("[add_tags_to_entry]", warning=e) + session.rollback() + return False + + def remove_tags_from_entry(self, entry_id: int, tag_ids: int | list[int] | set[int]) -> bool: + """Remove one or more tags from an entry.""" + tag_ids_ = [tag_ids] if isinstance(tag_ids, int) else tag_ids + with Session(self.engine, expire_on_commit=False) as session: + try: + for tag_id in tag_ids_: + tag_entry = session.scalars( + select(TagEntry).where( + and_( + TagEntry.tag_id == tag_id, + TagEntry.entry_id == entry_id, + ) + ) + ).first() + if tag_entry: + session.delete(tag_entry) + session.commit() + session.commit() + return True except IntegrityError as e: logger.exception(e) session.rollback() diff --git a/tagstudio/src/core/library/alchemy/models.py b/tagstudio/src/core/library/alchemy/models.py index a56e8b4c..7213cec3 100644 --- a/tagstudio/src/core/library/alchemy/models.py +++ b/tagstudio/src/core/library/alchemy/models.py @@ -146,7 +146,7 @@ class Entry(Base): return fields @property - def is_favorited(self) -> bool: + def is_favorite(self) -> bool: return any(tag.id == TAG_FAVORITE for tag in self.tags) @property diff --git a/tagstudio/src/qt/ts_qt.py b/tagstudio/src/qt/ts_qt.py index c035b587..f32e8793 100644 --- a/tagstudio/src/qt/ts_qt.py +++ b/tagstudio/src/qt/ts_qt.py @@ -16,7 +16,6 @@ import sys import time import webbrowser from collections.abc import Sequence -from itertools import zip_longest from pathlib import Path from queue import Queue @@ -53,8 +52,6 @@ from PySide6.QtWidgets import ( QWidget, ) from src.core.constants import ( - TAG_ARCHIVED, - TAG_FAVORITE, VERSION, VERSION_BRANCH, ) @@ -137,7 +134,7 @@ class QtDriver(DriverMixin, QObject): self.rm: ResourceManager = ResourceManager() self.args = args self.filter = FilterState.show_all() - self.frame_content: list[Entry] = [] + self.frame_content: list[int] = [] # List of Entry IDs on the current page self.pages_count = 0 self.scrollbar_pos = 0 @@ -151,9 +148,7 @@ class QtDriver(DriverMixin, QObject): self.thumb_job_queue: Queue = Queue() self.thumb_threads: list[Consumer] = [] self.thumb_cutoff: float = time.time() - - # grid indexes of selected items - self.selected: list[int] = [] + self.selected: list[int] = [] # Selected Entry IDs self.SIGTERM.connect(self.handle_sigterm) @@ -589,11 +584,13 @@ class QtDriver(DriverMixin, QObject): self.preview_panel.update_widgets() def toggle_libs_list(self, value: bool): - if value: - self.preview_panel.libs_flow_container.show() - else: - self.preview_panel.libs_flow_container.hide() - self.preview_panel.update() + # TODO: Reimplement or remove + # if value: + # self.preview_panel.libs_flow_container.show() + # else: + # self.preview_panel.libs_flow_container.hide() + # self.preview_panel.update() + pass def show_grid_filenames(self, value: bool): for thumb in self.item_thumbs: @@ -695,10 +692,12 @@ class QtDriver(DriverMixin, QObject): self.modal.show() def select_all_action_callback(self): - self.selected = list(range(0, len(self.frame_content))) - - for grid_idx in self.selected: - self.item_thumbs[grid_idx].thumb_button.set_selected(True) + """Set the selection to all visible items.""" + self.selected.clear() + for item in self.item_thumbs: + if item.mode and item.item_id not in self.selected: + self.selected.append(item.item_id) + item.thumb_button.set_selected(True) self.set_macro_menu_viability() self.preview_panel.update_widgets() @@ -829,14 +828,14 @@ class QtDriver(DriverMixin, QObject): # sleep(5) # pb.deleteLater() - def run_macros(self, name: MacroID, grid_idx: list[int]): + def run_macros(self, name: MacroID, entry_ids: list[int]): """Run a specific Macro on a group of given entry_ids.""" - for gid in grid_idx: - self.run_macro(name, gid) + for entry_id in entry_ids: + self.run_macro(name, entry_id) - def run_macro(self, name: MacroID, grid_idx: int): + def run_macro(self, name: MacroID, entry_id: int): """Run a specific Macro on an Entry given a Macro name.""" - entry: Entry = self.frame_content[grid_idx] + entry: Entry = self.lib.get_entry(entry_id) full_path = self.lib.library_dir / entry.path source = "" if entry.path.parent == Path(".") else entry.path.parts[0].lower() @@ -845,14 +844,14 @@ class QtDriver(DriverMixin, QObject): source=source, macro=name, entry_id=entry.id, - grid_idx=grid_idx, + grid_idx=entry_id, ) if name == MacroID.AUTOFILL: for macro_id in MacroID: if macro_id == MacroID.AUTOFILL: continue - self.run_macro(macro_id, grid_idx) + self.run_macro(macro_id, entry_id) elif name == MacroID.SIDECAR: parsed_items = TagStudioCore.get_gdl_sidecar(full_path, source) @@ -949,13 +948,12 @@ class QtDriver(DriverMixin, QObject): layout.setAlignment(Qt.AlignmentFlag.AlignCenter) # TODO - init after library is loaded, it can have different page_size - for grid_idx in range(self.filter.page_size): + for _ in range(self.filter.page_size): item_thumb = ItemThumb( None, self.lib, self, (self.thumb_size, self.thumb_size), - grid_idx, bool( self.settings.value(SettingItems.SHOW_FILENAMES, defaultValue=True, type=bool) ), @@ -972,44 +970,55 @@ class QtDriver(DriverMixin, QObject): sa.setWidgetResizable(True) sa.setWidget(self.flow_container) - def select_item(self, grid_index: int, append: bool, bridge: bool): + def select_item(self, item_id: int, append: bool, bridge: bool): """Select one or more items in the Thumbnail Grid.""" - logger.info("selecting item", grid_index=grid_index, append=append, bridge=bridge) + logger.info("[QtDriver] Selecting Items:", item_id=item_id, append=append, bridge=bridge) if append: - if grid_index not in self.selected: - self.selected.append(grid_index) - self.item_thumbs[grid_index].thumb_button.set_selected(True) + if item_id not in self.selected: + self.selected.append(item_id) + for it in self.item_thumbs: + if it.item_id == item_id: + it.thumb_button.set_selected(True) else: - self.selected.remove(grid_index) - self.item_thumbs[grid_index].thumb_button.set_selected(False) + self.selected.remove(item_id) + for it in self.item_thumbs: + if it.item_id == item_id: + it.thumb_button.set_selected(False) elif bridge and self.selected: - select_from = min(self.selected) - select_to = max(self.selected) + contents = self.frame_content + last_index = self.frame_content.index(self.selected[-1]) + current_index = self.frame_content.index(item_id) + index_range: list = contents[ + min(last_index, current_index) : max(last_index, current_index) + 1 + ] + # Preserve bridge direction for correct appending order. + if last_index < current_index: + index_range.reverse() + for entry_id in index_range: + for it in self.item_thumbs: + if it.item_id == entry_id: + it.thumb_button.set_selected(True) + if entry_id not in self.selected: + self.selected.append(entry_id) - if select_to < grid_index: - index_range = range(select_from, grid_index + 1) - else: - index_range = range(grid_index, select_to + 1) - - self.selected = list(index_range) - - for selected_idx in self.selected: - self.item_thumbs[selected_idx].thumb_button.set_selected(True) else: - self.selected = [grid_index] - for thumb_idx, item_thumb in enumerate(self.item_thumbs): - item_matched = thumb_idx == grid_index - item_thumb.thumb_button.set_selected(item_matched) - - # NOTE: By using the preview panel's "set_tags_updated_slot" method, - # only the last of multiple identical item selections are connected. - # If attaching the slot to multiple duplicate selections is needed, - # just bypass the method and manually disconnect and connect the slots. - if len(self.selected) == 1: + self.selected.clear() + self.selected.append(item_id) for it in self.item_thumbs: - if it.item_id == id: - self.preview_panel.set_tags_updated_slot(it.refresh_badge) + if it.item_id == item_id: + it.thumb_button.set_selected(True) + else: + it.thumb_button.set_selected(False) + + # # NOTE: By using the preview panel's "set_tags_updated_slot" method, + # # only the last of multiple identical item selections are connected. + # # If attaching the slot to multiple duplicate selections is needed, + # # just bypass the method and manually disconnect and connect the slots. + # if len(self.selected) == 1: + # for it in self.item_thumbs: + # if it.item_id == item_id: + # self.preview_panel.set_tags_updated_slot(it.refresh_badge) self.set_macro_menu_viability() self.preview_panel.update_widgets() @@ -1106,18 +1115,26 @@ class QtDriver(DriverMixin, QObject): self.main_window.update() is_grid_thumb = True - # Show loading placeholder icons - for entry, item_thumb in zip_longest(self.frame_content, self.item_thumbs): - if not entry: + logger.info("[QtDriver] Loading Entries...") + # TODO: Grab all entries at once + entries: list[Entry] = [self.lib.get_entry_full(e_id) for e_id in self.frame_content] + logger.info("[QtDriver] Building Filenames...") + filenames: list[Path] = [self.lib.library_dir / e.path for e in entries] + logger.info("[QtDriver] Done! Processing ItemThumbs...") + for index, item_thumb in enumerate(self.item_thumbs, start=0): + entry = None + try: + entry = entries[index] + except IndexError: item_thumb.hide() continue - + if not entry: + continue item_thumb.set_mode(ItemType.ENTRY) - item_thumb.set_item_id(entry) + item_thumb.set_item_id(entry.id) # TODO - show after item is rendered item_thumb.show() - is_loading = True self.thumb_job_queue.put( ( @@ -1127,29 +1144,29 @@ class QtDriver(DriverMixin, QObject): ) # Show rendered thumbnails - for idx, (entry, item_thumb) in enumerate( - zip_longest(self.frame_content, self.item_thumbs) - ): + for index, item_thumb in enumerate(self.item_thumbs, start=0): + entry = None + try: + entry = entries[index] + except IndexError: + item_thumb.hide() + continue if not entry: continue - filepath = self.lib.library_dir / entry.path is_loading = False - self.thumb_job_queue.put( ( item_thumb.renderer.render, - (time.time(), filepath, base_size, ratio, is_loading, is_grid_thumb), + (time.time(), filenames[index], base_size, ratio, is_loading, is_grid_thumb), ) ) - - entry_tag_ids = {tag.id for tag in entry.tags} - item_thumb.assign_badge(BadgeType.ARCHIVED, TAG_ARCHIVED in entry_tag_ids) - item_thumb.assign_badge(BadgeType.FAVORITE, TAG_FAVORITE in entry_tag_ids) + item_thumb.assign_badge(BadgeType.ARCHIVED, entry.is_archived) + item_thumb.assign_badge(BadgeType.FAVORITE, entry.is_favorite) item_thumb.update_clickable( clickable=( - lambda checked=False, index=idx: self.select_item( - index, + lambda checked=False, item_id=entry.id: self.select_item( + item_id, append=( QGuiApplication.keyboardModifiers() == Qt.KeyboardModifier.ControlModifier @@ -1165,24 +1182,15 @@ class QtDriver(DriverMixin, QObject): is_selected = (item_thumb.mode, item_thumb.item_id) in self.selected item_thumb.thumb_button.set_selected(is_selected) - self.thumb_job_queue.put( - ( - item_thumb.renderer.render, - (time.time(), filepath, base_size, ratio, False, True), - ) - ) - - def update_badges(self, grid_item_ids: Sequence[int] = None): - if not grid_item_ids: + def update_badges(self, item_ids: Sequence[int] = None): + if not item_ids: # no items passed, update all items in grid - grid_item_ids = range(min(len(self.item_thumbs), len(self.frame_content))) + item_ids = range(min(len(self.item_thumbs), len(self.frame_content))) - logger.info("updating badges for items", grid_item_ids=grid_item_ids) - - for grid_idx in grid_item_ids: - # get the entry from grid to avoid loading from db again - entry = self.frame_content[grid_idx] - self.item_thumbs[grid_idx].refresh_badge(entry) + item_ids_ = set(item_ids) + for it in self.item_thumbs: + if it.item_id in item_ids_: + it.refresh_badge() def filter_items(self, filter: FilterState | None = None) -> None: if not self.lib.library_dir: @@ -1217,7 +1225,7 @@ class QtDriver(DriverMixin, QObject): ) # update page content - self.frame_content = results.items + self.frame_content = [item.id for item in results.items] self.update_thumbs() # update pagination diff --git a/tagstudio/src/qt/widgets/item_thumb.py b/tagstudio/src/qt/widgets/item_thumb.py index 31144349..20dacfc7 100644 --- a/tagstudio/src/qt/widgets/item_thumb.py +++ b/tagstudio/src/qt/widgets/item_thumb.py @@ -24,7 +24,7 @@ from src.core.constants import ( TAG_ARCHIVED, TAG_FAVORITE, ) -from src.core.library import Entry, ItemType, Library +from src.core.library import ItemType, Library from src.core.media_types import MediaCategories, MediaType from src.qt.flowlayout import FlowWidget from src.qt.helpers.file_opener import FileOpenerHelper @@ -118,11 +118,9 @@ class ItemThumb(FlowWidget): library: Library, driver: "QtDriver", thumb_size: tuple[int, int], - grid_idx: int, show_filename_label: bool = False, ): super().__init__() - self.grid_idx = grid_idx self.lib = library self.mode: ItemType = mode self.driver = driver @@ -205,10 +203,10 @@ class ItemThumb(FlowWidget): self.thumb_button = ThumbButton(self.thumb_container, thumb_size) self.renderer = ThumbRenderer() self.renderer.updated.connect( - lambda ts, i, s, fn, ext: ( - self.update_thumb(ts, image=i), - self.update_size(ts, size=s), - self.set_filename_text(fn), + lambda timestamp, image, size, filename, ext: ( + self.update_thumb(timestamp, image=image), + self.update_size(timestamp, size=size), + self.set_filename_text(filename), self.set_extension(ext), ) ) @@ -399,6 +397,7 @@ class ItemThumb(FlowWidget): self.count_badge.setHidden(True) def set_filename_text(self, filename: Path | str | None): + self.set_item_path(filename) self.file_label.setText(str(filename)) def set_filename_visibility(self, set_visible: bool): @@ -444,24 +443,19 @@ class ItemThumb(FlowWidget): self.thumb_button.pressed.connect(clickable) self.thumb_button.is_connected = True - def refresh_badge(self, entry: Entry | None = None): + def refresh_badge(self, entry_id: int | None = None): + entry = self.lib.get_entry_full(self.item_id) if not entry: - if not self.item_id: - logger.error("missing both entry and item_id") - return None - - entry = self.lib.get_entry(self.item_id) - if not entry: - logger.error("Entry not found", item_id=self.item_id) - return - + return self.assign_badge(BadgeType.ARCHIVED, entry.is_archived) - self.assign_badge(BadgeType.FAVORITE, entry.is_favorited) + self.assign_badge(BadgeType.FAVORITE, entry.is_favorite) - def set_item_id(self, entry: Entry): - filepath = self.lib.library_dir / entry.path - self.opener.set_filepath(filepath) - self.item_id = entry.id + def set_item_id(self, item_id: int): + self.item_id = item_id + + def set_item_path(self, path: Path | str | None): + """Set the absolute filepath for the item. Used for locating on disk.""" + self.opener.set_filepath(path) def assign_badge(self, badge_type: BadgeType, value: bool) -> None: mode = self.mode @@ -500,18 +494,15 @@ class ItemThumb(FlowWidget): tag_id = BADGE_TAGS[badge_type] # check if current item is selected. if so, update all selected items - if self.grid_idx in self.driver.selected: - update_items = self.driver.selected + if self.item_id in self.driver.selected: + items_to_update = self.driver.selected else: - update_items = [self.grid_idx] + items_to_update = [self.item_id] - for idx in update_items: - entry = self.driver.frame_content[idx] - self.toggle_item_tag(entry.id, toggle_value, tag_id) - # update the entry - self.driver.frame_content[idx] = self.lib.get_entry_full(entry.id) + for item_id in items_to_update: + self.toggle_item_tag(item_id, toggle_value, tag_id) - self.driver.update_badges(update_items) + self.driver.update_badges(items_to_update) def toggle_item_tag( self, @@ -524,8 +515,7 @@ class ItemThumb(FlowWidget): if toggle_value: self.lib.add_tags_to_entry(entry_id, tag_id) else: - # TODO: Implement - self.lib.remove_tag_from_entry(entry_id, tag_id) + self.lib.remove_tags_from_entry(entry_id, tag_id) if self.driver.preview_panel.is_open: self.driver.preview_panel.update_widgets() @@ -538,13 +528,13 @@ class ItemThumb(FlowWidget): paths = [] mimedata = QMimeData() - selected_idxs = self.driver.selected - if self.grid_idx not in selected_idxs: - selected_idxs = [self.grid_idx] + selected_ids = self.driver.selected + if self.item_id not in selected_ids: + selected_ids = [self.item_id] - for grid_idx in selected_idxs: - id = self.driver.item_thumbs[grid_idx].item_id - entry = self.lib.get_entry(id) + for selected_id in selected_ids: + item_id = self.driver.item_thumbs[selected_id].item_id + entry = self.lib.get_entry(item_id) if not entry: continue @@ -554,4 +544,4 @@ class ItemThumb(FlowWidget): mimedata.setUrls(paths) drag.setMimeData(mimedata) drag.exec(Qt.DropAction.CopyAction) - logger.info("dragged files to external program", thumbnail_indexs=selected_idxs) + logger.info("dragged files to external program", thumbnail_indexs=selected_ids) diff --git a/tagstudio/src/qt/widgets/preview/field_containers.py b/tagstudio/src/qt/widgets/preview/field_containers.py index 5415f42a..c69eeac2 100644 --- a/tagstudio/src/qt/widgets/preview/field_containers.py +++ b/tagstudio/src/qt/widgets/preview/field_containers.py @@ -119,7 +119,7 @@ class FieldContainers(QWidget): def update_from_entry(self, entry: Entry): """Update tags and fields from a single Entry source.""" - self.selected = [entry] + self.selected = [self.lib.get_entry_full(entry.id)] logger.info( "[Field Containers] Updating Selection", entry=entry, @@ -127,33 +127,17 @@ class FieldContainers(QWidget): tags=entry.tags, ) - # # reload entry and fill it into the grid again - # # TODO - do this more granular - # # TODO - Entry reload is maybe not necessary - # for grid_idx in self.driver.selected: - # entry = self.driver.frame_content[grid_idx] - # results = self.lib.search_library(FilterState(id=entry.id)) - # logger.info( - # "found item", - # entries=len(results.items), - # grid_idx=grid_idx, - # lookup_id=entry.id, - # ) - # self.driver.frame_content[grid_idx] = results[0] - - # for index in self.driver.selected: - # self.driver.frame_content[index] = self.lib.get_entry(self.selected[0].id) - - for idx, field in enumerate(entry.fields): + entry_ = self.selected[0] + for idx, field in enumerate(entry_.fields): self.write_container(idx, field, is_mixed=False) - if entry.tags: + if entry_.tags: # TODO: Display the tag categories pass # Hide leftover containers - if len(self.containers) > len(entry.fields): + if len(self.containers) > len(entry_.fields): for i, c in enumerate(self.containers): - if i > (len(entry.fields) - 1): + if i > (len(entry_.fields) - 1): c.setHidden(True) self.add_field_button.setHidden(False) @@ -170,17 +154,16 @@ class FieldContainers(QWidget): if self.add_field_button.is_connected: self.add_field_button.clicked.disconnect() - # self.add_field_modal.done.connect( - # lambda f: (self.add_field_to_selected(f), self.update_widgets()) - # ) + self.add_field_modal.done.connect( + lambda f: (self.add_field_to_selected(f), self.update_from_entry(self.selected[0])) + ) self.add_field_modal.is_connected = True self.add_field_button.clicked.connect(self.add_field_modal.show) def add_field_to_selected(self, field_list: list): """Add list of entry fields to one or more selected items.""" logger.info("add_field_to_selected", selected=self.selected, fields=field_list) - for grid_idx in self.selected: - entry = self.driver.frame_content[grid_idx] + for entry in self.selected: for field_item in field_list: self.lib.add_entry_field_type( entry.id, @@ -393,12 +376,7 @@ class FieldContainers(QWidget): def remove_field(self, field: BaseField): """Remove a field from all selected Entries.""" logger.info("removing field", field=field, selected=self.selected) - entry_ids = [] - - for grid_idx in self.selected: - entry = self.driver.frame_content[grid_idx] - entry_ids.append(entry.id) - + entry_ids = [e.id for e in self.selected] self.lib.remove_entry_field(field, entry_ids) # # if the field is meta tags, update the badges @@ -412,12 +390,7 @@ class FieldContainers(QWidget): (TextField, DatetimeField), # , TagBoxField) ), f"instance: {type(field)}" - entry_ids = [] - # for grid_idx in self.selected: - # entry = self.driver.frame_content[grid_idx] - # entry_ids.append(entry.id) - for entry in self.selected: - entry_ids.append(entry.id) + entry_ids = [e.id for e in self.selected] assert entry_ids, "No entries selected" self.lib.update_entry_field( diff --git a/tagstudio/src/qt/widgets/preview/file_attributes.py b/tagstudio/src/qt/widgets/preview/file_attributes.py index 96151abc..ed572750 100644 --- a/tagstudio/src/qt/widgets/preview/file_attributes.py +++ b/tagstudio/src/qt/widgets/preview/file_attributes.py @@ -200,7 +200,6 @@ class FileAttributes(QWidget): # Format and display any stat variables def add_newline(stats_label_text: str) -> str: - logger.info(stats_label_text[-2:]) if stats_label_text and stats_label_text[-2:] != "\n": return stats_label_text + "\n" return stats_label_text diff --git a/tagstudio/src/qt/widgets/preview_panel.py b/tagstudio/src/qt/widgets/preview_panel.py index fc07b8cd..a34c7bcf 100644 --- a/tagstudio/src/qt/widgets/preview_panel.py +++ b/tagstudio/src/qt/widgets/preview_panel.py @@ -8,7 +8,7 @@ from pathlib import Path import structlog from PySide6.QtCore import Qt, Signal -from PySide6.QtWidgets import QHBoxLayout, QSplitter, QWidget +from PySide6.QtWidgets import QHBoxLayout, QSplitter, QVBoxLayout, QWidget from src.core.library.alchemy.library import Library from src.core.library.alchemy.models import Entry from src.qt.widgets.preview.field_containers import FieldContainers @@ -40,13 +40,15 @@ class PreviewPanel(QWidget): self.file_attrs = FileAttributes(library, driver) self.fields = FieldContainers(library, driver) - # info_section = QWidget() - # info_layout = QVBoxLayout(info_section) - # info_layout.setContentsMargins(0, 0, 0, 0) - # info_layout.setSpacing(6) + preview_section = QWidget() + preview_layout = QVBoxLayout(preview_section) + preview_layout.setContentsMargins(0, 0, 0, 0) + preview_layout.setSpacing(6) - # info_layout.addWidget(self.file_attrs) - # info_layout.addWidget(self.fields.scroll_area) + info_section = QWidget() + info_layout = QVBoxLayout(info_section) + info_layout.setContentsMargins(0, 0, 0, 0) + info_layout.setSpacing(6) splitter = QSplitter() splitter.setOrientation(Qt.Orientation.Vertical) @@ -59,35 +61,24 @@ class PreviewPanel(QWidget): # ) # ) # ) + preview_layout.addWidget(self.thumb) + preview_layout.addWidget(self.thumb.media_player) + info_layout.addWidget(self.file_attrs) + info_layout.addWidget(self.fields) - # splitter.addWidget(self.thumb.image_container) - # splitter.addWidget(self.thumb.media_player) - splitter.addWidget(self.thumb) - splitter.addWidget(self.thumb.media_player) - splitter.addWidget(self.file_attrs) - splitter.addWidget(self.fields) + splitter.addWidget(preview_section) + splitter.addWidget(info_section) # splitter.addWidget(self.libs_flow_container) - splitter.setStretchFactor(3, 2) + splitter.setStretchFactor(1, 2) root_layout = QHBoxLayout(self) root_layout.setContentsMargins(0, 0, 0, 0) root_layout.addWidget(splitter) - def update_selected_entry(self, driver: "QtDriver"): - for grid_idx in driver.selected: - entry = driver.frame_content[grid_idx] - result = self.lib.get_entry_full(entry.id) - logger.info( - "found item", - grid_idx=grid_idx, - lookup_id=entry.id, - ) - self.driver.frame_content[grid_idx] = result - def update_widgets(self) -> bool: """Render the panel widgets with the newest data from the Library.""" # No Items Selected - items: list[Entry] = [self.driver.frame_content[x] for x in self.driver.selected] + # items: list[Entry] = [self.driver.frame_content[x] for x in self.driver.selected] if len(self.driver.selected) == 0: # TODO: Clear everything to default # self.file_attrs.update_blank() @@ -96,7 +87,7 @@ class PreviewPanel(QWidget): # One Item Selected elif len(self.driver.selected) == 1: - entry: Entry = items[0] + entry: Entry = self.lib.get_entry_full(self.driver.selected[0]) filepath: Path = self.lib.library_dir / entry.path ext: str = filepath.suffix.lower()