Skip to content

Commit

Permalink
ComboEnumCriteria: Generalize into ComboBoxWidget.
Browse files Browse the repository at this point in the history
This will make it easy to support other combo box contents.

Signed-off-by: Chris PeBenito <pebenito@ieee.org>
  • Loading branch information
pebenito committed Nov 16, 2023
1 parent 72d5252 commit 6d0e659
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 49 deletions.
63 changes: 63 additions & 0 deletions setoolsgui/widgets/criteria/combobox.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@

from contextlib import suppress

from PyQt6 import QtWidgets
import setools

from .criteria import CriteriaWidget

__all__ = ("ComboBoxWidget",)


class ComboBoxWidget(CriteriaWidget):

"""Criteria selection widget presenting options as a QComboBox."""

def __init__(self, title: str, query: setools.PolicyQuery, attrname: str, /, *,
enable_any: bool = True, parent: QtWidgets.QWidget | None = None) -> None:

super().__init__(title, query, attrname, parent=parent)
self.top_layout = QtWidgets.QHBoxLayout(self)

self.criteria = QtWidgets.QComboBox(self)
self.criteria.setEditable(False)
self.criteria.setSizePolicy(QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum,
QtWidgets.QSizePolicy.Policy.Fixed))
self.criteria.currentIndexChanged.connect(self._update_query)
self.top_layout.addWidget(self.criteria)

if enable_any:
self.criteria.addItem("[Any]", None)

# add spacer so that the combo box is left-aligned
spacerItem = QtWidgets.QSpacerItem(40, 20,
QtWidgets.QSizePolicy.Policy.Expanding,
QtWidgets.QSizePolicy.Policy.Minimum)
self.top_layout.addItem(spacerItem)

@property
def has_errors(self) -> bool:
"""Get error state of this widget."""
return False

def _update_query(self, idx: int) -> None:
"""Update the query based on the combo box."""
value = self.criteria.itemText(idx)
if value:
# get enum value from combo box
value = self.criteria.itemData(idx)

self.log.debug(f"Setting {self.attrname} to {value!r}")
setattr(self.query, self.attrname, value)

#
# Workspace methods
#

def save(self, settings: dict) -> None:
settings[self.attrname] = self.criteria.currentText()

def load(self, settings: dict) -> None:
with suppress(AttributeError, KeyError):
idx = self.criteria.findText(settings[self.attrname])
self.criteria.setCurrentIndex(idx)
53 changes: 4 additions & 49 deletions setoolsgui/widgets/criteria/comboenum.py
Original file line number Diff line number Diff line change
@@ -1,76 +1,31 @@
# SPDX-License-Identifier: LGPL-2.1-only

from contextlib import suppress
import enum
import typing

from PyQt6 import QtWidgets
import setools

from .criteria import CriteriaWidget
from .combobox import ComboBoxWidget

E = typing.TypeVar("E", bound=enum.Enum)

__all__ = ('ComboEnumCriteria',)


class ComboEnumCriteria(CriteriaWidget, typing.Generic[E]):
class ComboEnumCriteria(ComboBoxWidget, typing.Generic[E]):

"""Criteria selection widget presenting possible options a QComboxBox."""

def __init__(self, title: str, query: setools.PolicyQuery, attrname: str, enum_class: type[E],
parent: QtWidgets.QWidget | None = None) -> None:
enable_any: bool = True, parent: QtWidgets.QWidget | None = None) -> None:

super().__init__(title, query, attrname, parent=parent)

self.enum_class: typing.Final[type[E]] = enum_class
self.top_layout = QtWidgets.QHBoxLayout(self)

self.criteria = QtWidgets.QComboBox(self)
self.criteria.setEditable(False)
self.criteria.setSizePolicy(QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum,
QtWidgets.QSizePolicy.Policy.Fixed))
self.criteria.currentIndexChanged.connect(self._update_query)
self.top_layout.addWidget(self.criteria)
super().__init__(title, query, attrname, enable_any=enable_any, parent=parent)

enu: E
self.criteria.addItem("") # Add entry for "match any"
for enu in sorted(enum_class, key=lambda e: e.name):
self.criteria.addItem(enu.name, enu)

# add spacer so that the combo box is left-aligned
spacerItem = QtWidgets.QSpacerItem(40, 20,
QtWidgets.QSizePolicy.Policy.Expanding,
QtWidgets.QSizePolicy.Policy.Minimum)
self.top_layout.addItem(spacerItem)

@property
def has_errors(self) -> bool:
"""Get error state of this widget."""
return False

def _update_query(self, idx: int) -> None:
"""Update the query based on the combo box."""
value = self.criteria.itemText(idx)
if value:
# get enum value from combo box
value = self.criteria.itemData(idx)

self.log.debug(f"Setting {self.attrname} to {value!r}")
setattr(self.query, self.attrname, value)

#
# Workspace methods
#

def save(self, settings: dict) -> None:
settings[self.attrname] = self.criteria.currentText()

def load(self, settings: dict) -> None:
with suppress(AttributeError, KeyError):
idx = self.criteria.findText(settings[self.attrname])
self.criteria.setCurrentIndex(idx)


if __name__ == '__main__':
import sys
Expand Down

0 comments on commit 6d0e659

Please sign in to comment.