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."""
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
"""
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)