Source code for oci_policy_analysis.presentation.qt.settings_panels

"""Focused Qt settings widgets using the desktop/web setting names."""

from PySide6.QtCore import Signal
from PySide6.QtWidgets import (
    QBoxLayout,
    QCheckBox,
    QComboBox,
    QFormLayout,
    QGridLayout,
    QHBoxLayout,
    QPushButton,
    QVBoxLayout,
    QWidget,
)

from oci_policy_analysis.application.core.engine.intelligence_strategies import get_default_intelligence_strategies
from oci_policy_analysis.presentation.qt.preferences import save_preferences
from oci_policy_analysis.presentation.qt.themes import COLOR_THEMES
from oci_policy_analysis.presentation.qt.widgets import label


[docs] class IntelligencePanel(QWidget): """Configure enrichment and registered strategy selection for the next load.""" def __init__(self, settings: dict) -> None: """Use the same strategy registry and risk defaults as desktop/web settings.""" super().__init__() self.settings = settings layout = QVBoxLayout(self) form = QFormLayout() form.setFieldGrowthPolicy(QFormLayout.FieldGrowthPolicy.FieldsStayAtSizeHint) self.profile = QComboBox() self.profile.addItem('Query foundations', 'minimal') self.profile.addItem('Full intelligence', 'full') self.profile.setCurrentIndex(max(0, self.profile.findData(settings.get('qt_post_load_profile', 'minimal')))) form.addRow('After loading', self.profile) self.where_reduction = QComboBox() self.service_reduction = QComboBox() for combo, key in [ (self.where_reduction, 'risk_where_clause_reduction_pct'), (self.service_reduction, 'risk_service_principal_reduction_pct'), ]: combo.addItems(['0%', '25%', '50%', '75%', '90%']) combo.setCurrentText(f'{settings.get(key, 50)}%') layout.addLayout(form) layout.addWidget(label('Risk score reductions', 'eyebrow')) self.risk_row = QHBoxLayout() for title, combo in [('WHERE', self.where_reduction), ('Service principal', self.service_reduction)]: pair = QFormLayout() pair.addRow(title, combo) self.risk_row.addLayout(pair) self.risk_row.addStretch() layout.addLayout(self.risk_row) layout.addWidget(label('Enabled intelligence checks', 'eyebrow')) grid = QGridLayout() self.strategy_grid = grid self.strategy_columns = 2 self.strategies = {} saved = settings.get('enabled_intelligence_checks') or [] for index, strategy in enumerate(get_default_intelligence_strategies()): check = QCheckBox(strategy.display_name) check.setChecked(not saved or strategy.strategy_id in saved) self.strategies[strategy.strategy_id] = check grid.addWidget(check, index // 2, index % 2) layout.addLayout(grid) button = QPushButton('Apply to next load') button.clicked.connect(self.apply_settings) layout.addWidget(button) self.status = label('Strategies and risk settings run with Full intelligence.', 'muted', wrap=True) layout.addWidget(self.status)
[docs] def reflow_columns(self, available: int) -> None: """Use one strategy column when large text exceeds the available width. Args: available: Width of the containing Overview viewport in pixels. """ risk_width = sum(self.risk_row.itemAt(i).sizeHint().width() for i in range(self.risk_row.count())) + 30 self.risk_row.setDirection( QBoxLayout.Direction.TopToBottom if risk_width > available else QBoxLayout.Direction.LeftToRight ) required = 2 * max(check.sizeHint().width() for check in self.strategies.values()) + 30 columns = 1 if required > available else 2 if columns == self.strategy_columns: return self.strategy_columns = columns for index, check in enumerate(self.strategies.values()): self.strategy_grid.removeWidget(check) self.strategy_grid.addWidget(check, index // columns, index % columns)
[docs] def apply_settings(self) -> None: """Store session settings without mutating the currently displayed context.""" enabled = [key for key, check in self.strategies.items() if check.isChecked()] if not enabled: self.status.setText('Select at least one strategy. Use Query foundations to skip the full run.') return self.settings.update( { 'qt_post_load_profile': self.profile.currentData(), 'enabled_intelligence_checks': enabled if len(enabled) < len(self.strategies) else [], 'risk_where_clause_reduction_pct': int(self.where_reduction.currentText().rstrip('%')), 'risk_service_principal_reduction_pct': int(self.service_reduction.currentText().rstrip('%')), } ) try: save_preferences( self.settings, ( 'qt_post_load_profile', 'enabled_intelligence_checks', 'risk_where_clause_reduction_pct', 'risk_service_principal_reduction_pct', ), ) self.status.setText('Saved for future loads and app restarts. Current results are unchanged.') except OSError: self.status.setText('Applied for this session; could not save intelligence preferences.')
[docs] class AppearancePanel(QWidget): """Apply text sizing and table density without rebuilding or reloading data.""" changed = Signal(dict) def __init__(self, settings: dict) -> None: """Build the current session appearance controls.""" super().__init__() self.settings = settings layout = QFormLayout(self) layout.setFieldGrowthPolicy(QFormLayout.FieldGrowthPolicy.FieldsStayAtSizeHint) layout.setRowWrapPolicy(QFormLayout.RowWrapPolicy.WrapLongRows) self.theme = QComboBox() self.theme.addItems(['Light', 'Dark']) self.theme.setCurrentText(settings.get('qt_theme', 'Light')) self.theme.setMinimumWidth(175) layout.addRow('Appearance', self.theme) self.color_theme = QComboBox() self.color_theme.addItems(list(COLOR_THEMES)) self.color_theme.setCurrentText(settings.get('qt_color_theme', 'Forest')) self.color_theme.setMinimumWidth(175) layout.addRow('Color theme', self.color_theme) self.font_size = QComboBox() self.font_size.addItems(['Small', 'Medium', 'Large', 'Extra Large']) self.font_size.setCurrentText(settings.get('font_size', 'Medium')) self.font_size.setMinimumWidth(175) layout.addRow('Text size', self.font_size) self.fixed_width = QCheckBox('Fixed-width font for tables and Overview settings') self.fixed_width.setChecked(settings.get('qt_fixed_width_font', False)) layout.addRow(self.fixed_width) self.compact = QCheckBox('Compact policy rows') self.compact.setChecked(settings.get('qt_compact_rows', False)) layout.addRow(self.compact) button = QPushButton('Apply appearance') button.clicked.connect(self.apply_settings) layout.addRow(button) self.status = label('', 'muted', wrap=True) layout.addRow(self.status)
[docs] def apply_settings(self) -> None: """Publish session appearance values to the window shell.""" self.settings.update( { 'qt_theme': self.theme.currentText(), 'qt_color_theme': self.color_theme.currentText(), 'font_size': self.font_size.currentText(), 'qt_compact_rows': self.compact.isChecked(), 'qt_fixed_width_font': self.fixed_width.isChecked(), } ) self.changed.emit(dict(self.settings)) try: save_preferences( self.settings, ('qt_theme', 'qt_color_theme', 'font_size', 'qt_compact_rows', 'qt_fixed_width_font') ) self.status.setText('Appearance applied and saved.') except OSError as exc: self.status.setText(f'Applied for this session. {exc}')