# Path: views/widgets/language_dropdown.py """ Benutzerdefiniertes Dropdown-Widget für die Sprachauswahl mit Flaggen-Icons. """ import os from PyQt5.QtWidgets import (QWidget, QComboBox, QLabel, QHBoxLayout, QVBoxLayout, QFrame, QListWidget, QListWidgetItem, QAbstractItemView, QApplication) from PyQt5.QtCore import Qt, QSize, QEvent, pyqtSignal from PyQt5.QtGui import QIcon, QPainter, QPen, QColor, QCursor class LanguageDropdown(QWidget): """Benutzerdefiniertes Dropdown für die Sprachauswahl mit Flaggen.""" def __init__(self, language_manager): super().__init__() self.language_manager = language_manager self.is_open = False self.languages = {} self.current_language = self.language_manager.get_current_language() # QApplication-Instanz merken, um einen Event-Filter installieren zu können self.app = QApplication.instance() # Verfügbare Sprachen aus dem Manager holen self.available_languages = self.language_manager.get_available_languages() self.init_ui() # Verbinde Signal des Language Managers self.language_manager.language_changed.connect(self.on_language_changed) def init_ui(self): """Initialisiert die Benutzeroberfläche.""" layout = QVBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) # Container für die aktuelle Sprachauswahl self.current_language_container = QFrame() self.current_language_container.setObjectName("languageSelector") self.current_language_container.setCursor(Qt.PointingHandCursor) self.current_language_container.setStyleSheet(""" QFrame#languageSelector { background-color: transparent; border-radius: 4px; } QFrame#languageSelector:hover { background-color: rgba(200, 200, 200, 30); } """) current_layout = QHBoxLayout(self.current_language_container) current_layout.setContentsMargins(5, 5, 5, 5) # Icon der aktuellen Sprache self.current_flag = QLabel() self.current_flag.setFixedSize(24, 16) # Correct flag aspect ratio # Pfad zum Icon icon_path = self.get_language_icon_path(self.current_language) if icon_path: self.current_flag.setPixmap(QIcon(icon_path).pixmap(QSize(24, 16))) current_layout.addWidget(self.current_flag) # Kleiner Pfeil nach unten arrow_label = QLabel("▼") arrow_label.setStyleSheet("font-size: 8px; color: #888888;") current_layout.addWidget(arrow_label) layout.addWidget(self.current_language_container) # Dropdown-Liste (anfangs versteckt) self.dropdown_list = QListWidget() self.dropdown_list.setWindowFlags(Qt.Popup | Qt.FramelessWindowHint) self.dropdown_list.setFocusPolicy(Qt.NoFocus) self.dropdown_list.setMouseTracking(True) self.dropdown_list.setFrameShape(QFrame.NoFrame) self.dropdown_list.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.dropdown_list.setEditTriggers(QAbstractItemView.NoEditTriggers) self.dropdown_list.setSelectionMode(QAbstractItemView.NoSelection) self.dropdown_list.setStyleSheet(""" QListWidget { background-color: white; border: 1px solid #CCCCCC; border-radius: 5px; padding: 5px; } QListWidget::item { padding: 4px; border-radius: 3px; } QListWidget::item:hover { background-color: #F0F0F0; } """) # Sprachen zum Dropdown hinzufügen self.populate_dropdown() # Event-Verbindungen self.current_language_container.mousePressEvent = self.toggle_dropdown self.dropdown_list.itemClicked.connect(self.on_language_selected) # Zugänglichkeit mit Tastaturfokus self.setFocusPolicy(Qt.StrongFocus) self.current_language_container.setFocusPolicy(Qt.StrongFocus) def get_language_icon_path(self, language_code): """Gibt den Pfad zum Icon für den angegebenen Sprachcode zurück.""" # Projektbasis-Verzeichnis ermitteln base_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) icon_path = os.path.join(base_dir, "resources", "icons", f"{language_code}.svg") if os.path.exists(icon_path): return icon_path return None def populate_dropdown(self): """Füllt das Dropdown mit den verfügbaren Sprachen.""" self.dropdown_list.clear() self.languages = {} for code, name in self.available_languages.items(): item = QListWidgetItem(name) # Icon erstellen icon_path = self.get_language_icon_path(code) if icon_path: item.setIcon(QIcon(icon_path)) # Sprach-Code speichern item.setData(Qt.UserRole, code) # Zum Dropdown hinzufügen self.dropdown_list.addItem(item) self.languages[code] = item def toggle_dropdown(self, event): """Öffnet oder schließt das Dropdown-Menü.""" if not self.is_open: # Position des Dropdowns unter dem Button berechnen pos = self.current_language_container.mapToGlobal(self.current_language_container.rect().bottomLeft()) self.dropdown_list.setGeometry(pos.x(), pos.y(), 120, 120) # Größe anpassen self.dropdown_list.show() self.is_open = True if self.app: self.app.installEventFilter(self) else: self.dropdown_list.hide() self.is_open = False if self.app: self.app.removeEventFilter(self) def on_language_selected(self, item): """Wird aufgerufen, wenn eine Sprache im Dropdown ausgewählt wird.""" language_code = item.data(Qt.UserRole) # Sprache wechseln if language_code != self.current_language: self.language_manager.change_language(language_code) # Dropdown schließen self.dropdown_list.hide() self.is_open = False if self.app: self.app.removeEventFilter(self) def on_language_changed(self, language_code): """Wird aufgerufen, wenn sich die Sprache im LanguageManager ändert.""" self.current_language = language_code # Icon aktualisieren icon_path = self.get_language_icon_path(language_code) if icon_path: self.current_flag.setPixmap(QIcon(icon_path).pixmap(QSize(24, 16))) # Texte aktualisieren (falls vorhanden) if hasattr(self.parent(), "update_texts"): self.parent().update_texts() def keyPressEvent(self, event): """Behandelt Tastatureingaben für verbesserte Zugänglichkeit.""" if event.key() == Qt.Key_Space or event.key() == Qt.Key_Return: self.toggle_dropdown(None) else: super().keyPressEvent(event) def eventFilter(self, obj, event): """Schließt das Dropdown, wenn außerhalb geklickt wird.""" if self.is_open and event.type() == QEvent.MouseButtonPress: # Klickposition relativ zum Dropdown ermitteln if not self.dropdown_list.geometry().contains(event.globalPos()) and \ not self.current_language_container.geometry().contains( self.mapFromGlobal(event.globalPos())): self.dropdown_list.hide() self.is_open = False if self.app: self.app.removeEventFilter(self) return super().eventFilter(obj, event)