Initial commit
Dieser Commit ist enthalten in:
203
views/widgets/language_dropdown.py
Normale Datei
203
views/widgets/language_dropdown.py
Normale Datei
@ -0,0 +1,203 @@
|
||||
# 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)
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren