Source code for widgets.custom_qwidgets

######################################################################################################################
# Copyright (C) 2017 - 2019 Spine project consortium
# This file is part of Spine Toolbox.
# Spine Toolbox is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General
# Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option)
# any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
# Public License for more details. You should have received a copy of the GNU Lesser General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
######################################################################################################################

"""
Custom QWidgets for Filtering and Zooming.

:author: P. Vennström (VTT)
:date:   4.12.2018
"""

from PySide2.QtWidgets import (
    QWidget,
    QVBoxLayout,
    QHBoxLayout,
    QMenu,
    QAction,
    QStyle,
    QToolBar,
    QStyleOptionMenuItem,
    QListView,
    QLineEdit,
    QDialogButtonBox,
)
from PySide2.QtCore import QTimer, Signal
from PySide2.QtGui import QPainter
from tabularview_models import FilterCheckboxListModel


[docs]class FilterWidget(QWidget): """Filter widget class."""
[docs] okPressed = Signal()
[docs] cancelPressed = Signal()
def __init__(self, parent=None, show_empty=True): """Init class.""" super().__init__(parent) # parameters self._filter_state = set() self._filter_empty_state = False self._search_text = '' self.search_delay = 200 # create ui elements self._ui_vertical_layout = QVBoxLayout(self) self._ui_list = QListView() self._ui_edit = QLineEdit() self._ui_edit.setPlaceholderText('Search') self._ui_edit.setClearButtonEnabled(True) self._ui_buttons = QDialogButtonBox(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) self._ui_vertical_layout.addWidget(self._ui_edit) self._ui_vertical_layout.addWidget(self._ui_list) self._ui_vertical_layout.addWidget(self._ui_buttons) # add models self._search_timer = QTimer() # Used to limit search so it doesn't search when typing self._search_timer.setSingleShot(True) self._filter_model = FilterCheckboxListModel(show_empty=show_empty) self._filter_model.set_list(self._filter_state) self._ui_list.setModel(self._filter_model) # connect signals self._ui_list.clicked.connect(self._filter_model.click_index) self._search_timer.timeout.connect(self._filter_list) self._ui_edit.textChanged.connect(self._text_edited) self._ui_buttons.button(QDialogButtonBox.Ok).clicked.connect(self._apply_filter) self._ui_buttons.button(QDialogButtonBox.Cancel).clicked.connect(self._cancel_filter)
[docs] def save_state(self): """Saves the state of the FilterCheckboxListModel.""" self._filter_state = self._filter_model.get_selected() if self._filter_model._show_empty: self._filter_empty_state = self._filter_model._empty_selected else: self._filter_empty_state = False
[docs] def reset_state(self): """Sets the state of the FilterCheckboxListModel to saved state.""" self._filter_model.set_selected(self._filter_state, self._filter_empty_state)
[docs] def clear_filter(self): """Selects all items in FilterCheckBoxListModel.""" self._filter_model.reset_selection() self.save_state()
[docs] def has_filter(self): """Returns true if any item is filtered in FilterCheckboxListModel false otherwise.""" return not self._filter_model._all_selected
[docs] def set_filter_list(self, data): """Sets the list of items to filter.""" self._filter_state = set(data) if self._filter_model._show_empty: self._filter_empty_state = True else: self._filter_empty_state = False self._filter_model.set_list(self._filter_state)
[docs] def _apply_filter(self): """Apply current filter and save state.""" self._filter_model.apply_filter() self.save_state() self._ui_edit.setText('') self.okPressed.emit()
[docs] def _cancel_filter(self): """Cancel current edit of filter and set the state to the stored state.""" self._filter_model.remove_filter() self.reset_state() self._ui_edit.setText('') self.cancelPressed.emit()
[docs] def _filter_list(self): """Filter list with current text.""" self._filter_model.set_filter(self._search_text)
[docs] def _text_edited(self, new_text): """Callback for edit text, starts/restarts timer. Start timer after text is edited, restart timer if text is edited before last time out. """ self._search_text = new_text self._search_timer.start(self.search_delay)
[docs]class ZoomWidget(QWidget): """A widget for a QWidgetAction providing zoom actions for a graph view. Attributes parent (QWidget): the widget's parent """
[docs] minus_pressed = Signal(name="minus_pressed")
[docs] plus_pressed = Signal(name="plus_pressed")
[docs] reset_pressed = Signal(name="reset_pressed")
def __init__(self, parent=None): """Init class.""" super().__init__(parent) self.option = QStyleOptionMenuItem() zoom_action = QAction("Zoom") QMenu(parent).initStyleOption(self.option, zoom_action) layout = QHBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) tool_bar = QToolBar(self) tool_bar.setFixedHeight(self.option.rect.height()) minus_action = tool_bar.addAction("-") reset_action = tool_bar.addAction("Reset") plus_action = tool_bar.addAction("+") layout.addSpacing(self.option.rect.width()) layout.addWidget(tool_bar) minus_action.setToolTip("Zoom out") reset_action.setToolTip("Reset zoom") plus_action.setToolTip("Zoom in") minus_action.triggered.connect(lambda x: self.minus_pressed.emit()) plus_action.triggered.connect(lambda x: self.plus_pressed.emit()) reset_action.triggered.connect(lambda x: self.reset_pressed.emit())
[docs] def paintEvent(self, event): """Overridden method.""" painter = QPainter(self) self.style().drawControl(QStyle.CE_MenuItem, self.option, painter) super().paintEvent(event)