""" QSS Generator - Dynamically generates Qt Stylesheets from Theme Configuration """ from themes.theme_config import ThemeConfig class QSSGenerator: """ Generates complete QSS stylesheets from theme configuration. This ensures all styling is consistent and centralized. """ @staticmethod def generate(theme_name: str) -> str: """ Generate complete QSS for the specified theme. Args: theme_name: 'light' or 'dark' Returns: Complete QSS stylesheet as string """ theme = ThemeConfig.get_theme(theme_name) fonts = ThemeConfig.FONTS sizes = ThemeConfig.FONT_SIZES weights = ThemeConfig.FONT_WEIGHTS spacing = ThemeConfig.SPACING radius = ThemeConfig.RADIUS qss = f""" /* ==================== AUTO-GENERATED THEME: {theme_name.upper()} ==================== */ /* Generated from themes/theme_config.py - DO NOT EDIT DIRECTLY */ /* ==================== MAIN WINDOW ==================== */ QMainWindow {{ background-color: {theme['bg_primary']}; color: {theme['text_primary']}; }} /* ==================== BASE WIDGETS ==================== */ QWidget {{ background-color: {theme['bg_primary']}; color: {theme['text_primary']}; font-family: {fonts['secondary']}; font-size: {sizes['base']}; }} /* Content Stack - Main content area */ QStackedWidget#content_stack {{ background-color: {theme['bg_secondary']}; }} /* ==================== LABELS ==================== */ QLabel {{ color: {theme['text_primary']}; background-color: transparent; padding: 2px; }} /* Platform Title */ QLabel#platform_title {{ font-family: {fonts['primary']}; font-size: {sizes['3xl']}; font-weight: {weights['bold']}; color: {theme['text_accent']}; padding: {spacing['md']}; letter-spacing: 1px; }} /* Secondary Labels */ QLabel#secondary_text {{ color: {theme['text_secondary']}; }} /* Platform Name Labels */ QLabel#platform_name_label {{ color: {theme['platform_label']}; font-family: {fonts['primary']}; font-weight: {weights['semibold']}; letter-spacing: 0.5px; }} /* ==================== PLATFORM BUTTONS ==================== */ PlatformButton {{ background-color: transparent; }} QPushButton#platform_icon_button {{ background-color: {theme['platform_bg']}; border: 1px solid {theme['platform_border']}; border-radius: {radius['xl']}; padding: {spacing['xl']}; }} QPushButton#platform_icon_button:hover {{ background-color: {theme['platform_hover']}; border: 1px solid {theme['platform_border_hover']}; }} QPushButton#platform_icon_button:pressed {{ background-color: {theme['platform_pressed']}; border: 1px solid {theme['platform_border_hover']}; }} QPushButton#platform_icon_button:disabled {{ background-color: {theme['bg_tertiary']}; opacity: 0.5; }} /* ==================== BUTTONS ==================== */ QPushButton {{ background-color: {theme['btn_primary_bg']}; color: {theme['btn_primary_text']}; border: none; border-radius: {radius['round']}; padding: 0 {spacing['xl']}; font-family: {fonts['primary']}; font-size: {sizes['base']}; font-weight: {weights['semibold']}; min-height: 48px; text-transform: uppercase; letter-spacing: 0.5px; }} QPushButton:hover {{ background-color: {theme['accent_hover']}; }} QPushButton:pressed {{ background-color: {theme['accent_pressed']}; }} QPushButton:disabled {{ background-color: {theme['bg_tertiary']}; color: {theme['text_tertiary']}; opacity: 0.5; }} /* Secondary Buttons */ QPushButton#secondary_button {{ background-color: {theme['btn_secondary_bg']}; color: {theme['btn_secondary_text']}; border: 1px solid {theme['btn_secondary_border']}; }} QPushButton#secondary_button:hover {{ background-color: {theme['bg_hover']}; }} /* Danger Buttons */ QPushButton#danger_button {{ background-color: {theme['btn_danger_bg']}; color: {theme['btn_danger_text']}; }} QPushButton#danger_button:hover {{ background-color: {theme['error']}; }} /* ==================== TAB NAVIGATION ==================== */ TabNavigation, QWidget#tab_navigation {{ background-color: {theme['nav_bg']}; border-bottom: 1px solid {theme['nav_border']}; }} TabNavigation QPushButton {{ background-color: {theme['nav_item']}; color: {theme['nav_text']}; border: none; border-radius: 0; padding: 6px {spacing['lg']} {spacing['sm']}; font-weight: {weights['medium']}; min-height: 48px; text-transform: none; }} TabNavigation QPushButton:hover {{ background-color: {theme['nav_item_hover']}; color: {theme['text_primary']}; }} TabNavigation QPushButton:checked {{ background-color: {theme['nav_item_active']}; color: {theme['nav_text_active']}; border-bottom: 2px solid {theme['accent']}; }} /* Tab Badge */ TabNavigation QLabel#badge {{ background-color: {theme['accent']}; color: {theme['btn_primary_text']}; padding: 2px 6px; border-radius: 10px; font-size: {sizes['xs']}; font-weight: {weights['semibold']}; }} /* ==================== ACCOUNTS OVERVIEW ==================== */ AccountsOverviewView, QWidget#accounts_overview {{ background-color: {theme['bg_secondary']}; }} /* Filter Sidebar */ QWidget#filter_sidebar {{ background-color: {theme['surface_sidebar']}; border-right: 1px solid {theme['border_default']}; }} /* Filter Buttons */ QPushButton#filter_button {{ background-color: transparent; color: {theme['text_secondary']}; border: none; padding: {spacing['sm']} {spacing['md']}; text-align: left; font-size: {sizes['base']}; }} QPushButton#filter_button:hover {{ background-color: {theme['bg_hover']}; color: {theme['text_primary']}; }} QPushButton#filter_button[selected="true"] {{ background-color: {theme['bg_selected']}; color: {theme['text_accent']}; border-left: 3px solid {theme['accent']}; }} /* Content Area */ QWidget#accounts_content {{ background-color: {theme['bg_secondary']}; }} /* ==================== ACCOUNT CARDS ==================== */ AccountCard, QFrame#account_card {{ background-color: {theme['surface_card']}; border: 1px solid {theme['border_subtle']}; border-radius: {radius['lg']}; padding: {spacing['md']}; }} AccountCard:hover, QFrame#account_card:hover {{ border: 1px solid {theme['accent']}; }} /* Account Card Buttons */ QPushButton#login_button {{ background-color: {theme['accent']}; color: {theme['btn_primary_text']}; border-radius: {radius['md']}; padding: {spacing['sm']} {spacing['md']}; font-size: {sizes['sm']}; min-height: 36px; }} QPushButton#login_button:hover {{ background-color: {theme['accent_hover']}; }} QPushButton#export_button {{ background-color: {theme['success']}; color: #FFFFFF; border-radius: {radius['md']}; padding: {spacing['sm']} {spacing['md']}; font-size: {sizes['sm']}; min-height: 36px; }} QPushButton#delete_button {{ background-color: {theme['btn_danger_bg']}; color: {theme['btn_danger_text']}; border-radius: {radius['md']}; padding: {spacing['sm']} {spacing['md']}; font-size: {sizes['sm']}; min-height: 36px; }} /* ==================== INPUT FIELDS ==================== */ QLineEdit, QSpinBox, QTextEdit, QPlainTextEdit {{ background-color: {theme['input_bg']}; color: {theme['text_primary']}; border: 1px solid {theme['input_border']}; border-radius: {radius['md']}; padding: {spacing['sm']} {spacing['md']}; font-size: {sizes['base']}; }} QLineEdit:focus, QSpinBox:focus, QTextEdit:focus, QPlainTextEdit:focus {{ background-color: {theme['input_focus_bg']}; border: 2px solid {theme['input_focus_border']}; outline: none; }} QLineEdit:disabled, QSpinBox:disabled, QTextEdit:disabled {{ background-color: {theme['bg_tertiary']}; color: {theme['text_tertiary']}; }} /* ==================== COMBOBOX ==================== */ QComboBox {{ background-color: {theme['input_bg']}; color: {theme['text_primary']}; border: 1px solid {theme['input_border']}; border-radius: {radius['md']}; padding: {spacing['sm']} {spacing['md']}; min-height: 32px; }} QComboBox:hover {{ border: 1px solid {theme['accent']}; }} QComboBox:focus {{ border: 2px solid {theme['input_focus_border']}; }} QComboBox::drop-down {{ border: none; width: 20px; background-color: transparent; }} QComboBox::down-arrow {{ image: none; border-left: 5px solid transparent; border-right: 5px solid transparent; border-top: 5px solid {theme['accent']}; width: 0; height: 0; margin-right: 5px; }} QComboBox QAbstractItemView {{ background-color: {theme['surface_card']}; border: 1px solid {theme['border_default']}; border-radius: {radius['md']}; selection-background-color: {theme['bg_selected']}; selection-color: {theme['text_accent']}; color: {theme['text_primary']}; }} /* ==================== TABLES ==================== */ QTableWidget {{ background-color: {theme['surface_card']}; alternate-background-color: {theme['bg_secondary']}; gridline-color: {theme['border_subtle']}; border: none; color: {theme['text_primary']}; }} QTableWidget::item {{ padding: {spacing['sm']} {spacing['md']}; color: {theme['text_primary']}; }} QTableWidget::item:selected {{ background-color: {theme['bg_selected']}; color: {theme['text_accent']}; }} QHeaderView::section {{ background-color: {theme['bg_tertiary']}; color: {theme['text_primary']}; padding: {spacing['sm']} {spacing['md']}; border: none; font-weight: {weights['semibold']}; text-transform: uppercase; font-size: {sizes['sm']}; letter-spacing: 0.5px; }} /* ==================== SCROLL AREAS ==================== */ QScrollArea {{ background-color: {theme['bg_primary']}; border: none; }} QScrollArea > QWidget > QWidget {{ background-color: {theme['bg_primary']}; }} /* ==================== SCROLLBARS ==================== */ QScrollBar:vertical {{ background-color: {theme['scrollbar_bg']}; width: 8px; border-radius: 4px; }} QScrollBar::handle:vertical {{ background-color: {theme['scrollbar_handle']}; min-height: 20px; border-radius: 4px; }} QScrollBar::handle:vertical:hover {{ background-color: {theme['scrollbar_handle_hover']}; }} QScrollBar:horizontal {{ background-color: {theme['scrollbar_bg']}; height: 8px; border-radius: 4px; }} QScrollBar::handle:horizontal {{ background-color: {theme['scrollbar_handle']}; min-width: 20px; border-radius: 4px; }} QScrollBar::handle:horizontal:hover {{ background-color: {theme['scrollbar_handle_hover']}; }} QScrollBar::add-line, QScrollBar::sub-line {{ border: none; background: none; }} /* ==================== PROGRESS BAR ==================== */ QProgressBar {{ background-color: {theme['bg_tertiary']}; border: none; border-radius: 4px; height: 8px; text-align: center; }} QProgressBar::chunk {{ background-color: {theme['accent']}; border-radius: 4px; }} /* ==================== TOOLTIPS ==================== */ QToolTip {{ background-color: {theme['bg_tertiary']}; color: {theme['text_primary']}; border: 1px solid {theme['border_default']}; border-radius: {radius['md']}; padding: {spacing['sm']} {spacing['sm']}; font-size: {sizes['sm']}; }} /* ==================== MESSAGE BOXES ==================== */ QMessageBox {{ background-color: {theme['bg_primary']}; }} QMessageBox QLabel {{ color: {theme['text_primary']}; }} QMessageBox QPushButton {{ background-color: {theme['bg_tertiary']}; color: {theme['text_primary']}; border: 1px solid {theme['border_default']}; border-radius: 4px; padding: 6px 20px; min-width: 80px; min-height: 26px; font-weight: {weights['medium']}; text-transform: none; }} QMessageBox QPushButton:hover {{ background-color: {theme['bg_hover']}; border-color: {theme['accent']}; }} /* Delete Buttons in Message Boxes */ QMessageBox QPushButton[text="Löschen"], QMessageBox QPushButton[text="Delete"] {{ background-color: {theme['btn_danger_bg']}; color: {theme['btn_danger_text']}; border: none; }} /* ==================== STATUS BAR ==================== */ QStatusBar {{ background-color: {theme['bg_secondary']}; color: {theme['text_secondary']}; font-size: {sizes['sm']}; padding: {spacing['sm']}; border-top: 1px solid {theme['border_subtle']}; }} /* ==================== MENU BAR ==================== */ QMenuBar {{ background-color: {theme['bg_primary']}; color: {theme['text_primary']}; padding: 4px; }} QMenuBar::item {{ padding: {spacing['sm']} {spacing['md']}; background-color: transparent; color: {theme['text_primary']}; }} QMenuBar::item:selected {{ background-color: {theme['bg_hover']}; color: {theme['text_accent']}; }} /* Logo button in menu bar */ QPushButton#logo_button {{ background-color: transparent; border: none; padding: 5px; }} QPushButton#logo_button:hover {{ background-color: {theme['bg_hover']}; border-radius: {radius['sm']}; }} QWidget#menubar_right_container {{ background: transparent; }} /* ==================== CHECKBOXES & RADIO BUTTONS ==================== */ QCheckBox, QRadioButton {{ spacing: 8px; color: {theme['text_primary']}; }} QCheckBox::indicator, QRadioButton::indicator {{ width: 20px; height: 20px; border: 2px solid {theme['border_strong']}; background-color: {theme['input_bg']}; }} QCheckBox::indicator {{ border-radius: 4px; }} QRadioButton::indicator {{ border-radius: 10px; }} QCheckBox::indicator:checked, QRadioButton::indicator:checked {{ background-color: {theme['accent']}; border-color: {theme['accent']}; }} /* ==================== GROUP BOXES ==================== */ QGroupBox {{ background-color: {theme['surface_card']}; border: 1px solid {theme['border_default']}; border-radius: {radius['xl']}; padding: {spacing['xl']}; margin-top: {spacing['md']}; font-family: {fonts['primary']}; font-weight: {weights['semibold']}; color: {theme['text_primary']}; }} QGroupBox::title {{ color: {theme['text_accent']}; font-size: {sizes['lg']}; subcontrol-origin: margin; left: {spacing['md']}; padding: 0 {spacing['sm']}; background-color: {theme['surface_card']}; }} /* ==================== TABS ==================== */ QTabWidget::pane {{ background-color: {theme['bg_secondary']}; border: none; }} QTabBar::tab {{ background-color: transparent; color: {theme['text_secondary']}; padding: {spacing['sm']} {spacing['lg']}; font-size: {sizes['base']}; font-weight: {weights['medium']}; border: none; }} QTabBar::tab:hover {{ background-color: {theme['bg_hover']}; color: {theme['text_primary']}; }} QTabBar::tab:selected {{ color: {theme['text_accent']}; background-color: transparent; border-bottom: 2px solid {theme['accent']}; font-weight: {weights['semibold']}; }} /* ==================== DIALOGS ==================== */ QDialog {{ background-color: {theme['surface_modal']}; color: {theme['text_primary']}; }} /* ==================== LOG OUTPUT ==================== */ QTextEdit#log_output {{ background-color: {theme['bg_tertiary']}; color: {theme['text_primary']}; font-family: {fonts['monospace']}; font-size: {sizes['sm']}; border: none; border-radius: {radius['md']}; padding: {spacing['md']}; }} /* ==================== BADGES ==================== */ QLabel#badge {{ background-color: {theme['bg_tertiary']}; color: {theme['text_primary']}; padding: 4px 12px; border-radius: 12px; font-size: {sizes['xs']}; font-weight: {weights['semibold']}; text-transform: uppercase; letter-spacing: 0.5px; }} QLabel#badge_primary {{ background-color: {theme['accent']}; color: {theme['btn_primary_text']}; }} QLabel#badge_success {{ background-color: {theme['success']}; color: #FFFFFF; }} QLabel#badge_warning {{ background-color: {theme['warning']}; color: #000000; }} QLabel#badge_error {{ background-color: {theme['error']}; color: #FFFFFF; }} /* ==================== ACCOUNTS OVERVIEW SPECIFIC ==================== */ QLabel#platform_header {{ color: {theme['text_primary']}; padding: 8px 0; font-family: {fonts['primary']}; font-size: {sizes['lg']}; font-weight: {weights['semibold']}; }} QPushButton#delete_confirm_button {{ background-color: {theme['error']}; color: #FFFFFF; border: 1px solid {theme['error']}; border-radius: {radius['sm']}; padding: 6px 20px; min-width: 80px; min-height: 26px; font-weight: {weights['medium']}; }} QPushButton#delete_confirm_button:hover {{ background-color: {theme['error_dark']}; border-color: {theme['error_dark']}; }} QPushButton#delete_confirm_button:pressed {{ background-color: {theme['error_dark']}; }} /* ==================== ACCOUNT CARD ==================== */ QFrame#accountCard {{ background-color: {theme['surface_card']}; border: 2px solid {theme['border_default']}; border-radius: {radius['md']}; padding: 16px; }} QFrame#accountCard:hover {{ border: 2px solid {theme['accent']}; }} QFrame#accountCard[status="active"] {{ background-color: {theme['success_bg']}; border: 2px solid {theme['success']}; }} QFrame#accountCard[status="active"]:hover {{ border: 2px solid {theme['success']}; }} QFrame#accountCard[status="inactive"] {{ background-color: {theme['error_bg']}; border: 2px solid {theme['error']}; }} QFrame#accountCard[status="inactive"]:hover {{ border: 2px solid {theme['error_dark']}; }} QLabel#account_username {{ color: {theme['text_primary']}; font-family: {fonts['primary']}; font-size: 16px; font-weight: {weights['semibold']}; }} QLabel#account_detail_text {{ color: {theme['text_secondary']}; font-size: {sizes['sm']}; font-family: {fonts['primary']}; }} QLabel#account_date_text {{ color: {theme['text_tertiary']}; font-size: {sizes['xs']}; font-family: {fonts['primary']}; }} QPushButton#account_icon_btn {{ background: transparent; border: none; padding: 2px; min-width: 20px; max-width: 20px; min-height: 20px; max-height: 20px; }} QPushButton#account_icon_btn:hover {{ background-color: {theme['bg_hover']}; border-radius: {radius['sm']}; }} QPushButton#account_login_btn {{ background-color: {theme['accent']}; color: {theme['btn_primary_text']}; border: none; border-radius: {radius['sm']}; padding: 6px 16px; font-size: {sizes['xs']}; font-weight: {weights['medium']}; font-family: {fonts['primary']}; min-width: 60px; }} QPushButton#account_login_btn:hover {{ background-color: {theme['accent_hover']}; }} QPushButton#account_login_btn:pressed {{ background-color: {theme['accent_pressed']}; }} QPushButton#account_export_btn {{ background-color: {theme['success']}; color: #FFFFFF; border: none; border-radius: {radius['sm']}; padding: 4px 12px; font-size: {sizes['xs']}; font-weight: {weights['medium']}; font-family: {fonts['primary']}; min-width: 120px; min-height: 36px; text-align: center; }} QPushButton#account_export_btn:hover {{ background-color: {theme['success']}; opacity: 0.9; }} QPushButton#account_export_btn:pressed {{ background-color: {theme['success']}; opacity: 0.8; }} QPushButton#account_delete_btn {{ background-color: {theme['error']}; color: #FFFFFF; border: none; border-radius: {radius['sm']}; padding: 8px 16px; font-size: {sizes['xs']}; font-weight: {weights['medium']}; font-family: {fonts['primary']}; min-width: 90px; }} QPushButton#account_delete_btn:hover {{ background-color: {theme['error_dark']}; }} QPushButton#account_delete_btn:pressed {{ background-color: {theme['error_dark']}; opacity: 0.9; }} """ return qss