Source code for arthropod_describer.tag_filter_widget

import typing

import PySide2
from PySide2.QtCore import Qt, Signal
from PySide2.QtGui import QCursor
from PySide2.QtWidgets import QWidget, QLineEdit, QHBoxLayout, QLabel, QPushButton, QSizePolicy, QVBoxLayout

from arthropod_describer.common.state import State
from arthropod_describer.common.utils import is_cursor_inside
from arthropod_describer.tags_widget import TagsWidget


[docs]class ActiveTagsList(QLineEdit): hovered = Signal() def __init__(self): QLineEdit.__init__(self, None) self._active_tags: typing.List[str] = [] self.setReadOnly(True) self.setPlaceholderText('no filtering active')
[docs] def enterEvent(self, event:PySide2.QtCore.QEvent): self.hovered.emit() super().enterEvent(event)
[docs]class TagFilterWidget(QWidget): def __init__(self, state: State, parent: typing.Optional[PySide2.QtWidgets.QWidget] = None, f: PySide2.QtCore.Qt.WindowFlags = Qt.WindowFlags()): super().__init__(parent, f) self._state = state self._container = QVBoxLayout() self._main_layout = QHBoxLayout() self._label = QLabel(text='Tag filter:') self._main_layout.addWidget(self._label) self._tags_list = ActiveTagsList() self._tags_list.hovered.connect(self.show_tags_panel_popup) self._tags_list.setReadOnly(True) self._main_layout.addWidget(self._tags_list) self._btn_clear = QPushButton(text='Clear') self._btn_clear.setToolTip("Clear the current tag filter") self._btn_clear.clicked.connect(self._state.clear_tag_filter) self._main_layout.addWidget(self._btn_clear) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self._container.addLayout(self._main_layout) self._lblPhotoCount = QLabel("") self._container.addWidget(self._lblPhotoCount) self.setLayout(self._container) self.tags_widget = TagsWidget(self._state, parent=self, title="Tags to filter") self.tags_widget.hide() self.tags_widget.widget_left.connect(lambda: self.tags_widget.hide()) self._state.tags_filter_changed.connect(self.handle_active_tags_changed) # self._state.tags_filter_changed.connect()
[docs] def initialize(self): self.tags_widget.storage = self._state.storage self._state.storage.storage_update.connect(self.handle_storage_update) self.tags_widget.populate() self.handle_active_tags_changed(self._state.active_tags_filter)
[docs] def handle_active_tags_changed(self, active_tags: typing.List[str]): self.tags_widget.update_tag_states() self._tags_list.setText(', '.join(active_tags)) self._tags_list.setToolTip(self._tags_list.text()) self._update_photo_count_message()
[docs] def handle_storage_update(self, _: typing.Dict[str, typing.Any]): self.tags_widget.populate() self.tags_widget.update_tag_states() self._update_photo_count_message()
def _update_photo_count_message(self): hidden_count = self._state.hidden_photos_count shown_count = self._state.storage.image_count - hidden_count self._lblPhotoCount.setText(f'Showing {shown_count} photo{"s" if shown_count != 1 else ""}{"" if hidden_count == 0 else f" ({hidden_count} hidden)"}.')
[docs] def handle_tags_filter_changed(self, _: typing.List[str]): self._tags_list.setText(', '.join(self._state.active_tags_filter))
[docs] def show_tags_panel_popup(self): if not self.isEnabled(): return pos = self._tags_list.mapToGlobal(self._tags_list.rect().topRight()) self.tags_widget.move(pos) self.tags_widget.show()
[docs] def enterEvent(self, event:PySide2.QtCore.QEvent): super(TagFilterWidget, self).enterEvent(event)
[docs] def leaveEvent(self, event:PySide2.QtCore.QEvent): super(TagFilterWidget, self).leaveEvent(event) # cursor_pos = QCursor.pos() # tag_list_rect = self.tags_widget.rect().translated(self.tags_widget.pos()) # if tag_list_rect.contains(cursor_pos): # return if is_cursor_inside(self.tags_widget): return self.tags_widget.close()