420 Zeilen
15 KiB
Python
420 Zeilen
15 KiB
Python
"""
|
|
Account Card Widget - Kompakte Account-Karte nach Styleguide
|
|
"""
|
|
|
|
from PyQt5.QtWidgets import (
|
|
QFrame, QVBoxLayout, QHBoxLayout, QLabel, QPushButton,
|
|
QGridLayout, QWidget, QApplication
|
|
)
|
|
from PyQt5.QtCore import Qt, pyqtSignal, QSize, QTimer
|
|
from PyQt5.QtGui import QFont, QPixmap
|
|
import os
|
|
|
|
from views.widgets.icon_factory import IconFactory
|
|
|
|
|
|
class AccountCard(QFrame):
|
|
"""
|
|
Kompakte Account-Karte nach Styleguide für Light Mode
|
|
"""
|
|
|
|
# Signals
|
|
login_requested = pyqtSignal(dict) # Account-Daten
|
|
export_requested = pyqtSignal(dict) # Account-Daten
|
|
delete_requested = pyqtSignal(dict) # Account-Daten
|
|
|
|
def __init__(self, account_data, language_manager=None):
|
|
super().__init__()
|
|
self.account_data = account_data
|
|
self.language_manager = language_manager
|
|
self.password_visible = False
|
|
|
|
# Timer für Icon-Animation
|
|
self.email_copy_timer = QTimer()
|
|
self.email_copy_timer.timeout.connect(self._restore_email_copy_icon)
|
|
self.password_copy_timer = QTimer()
|
|
self.password_copy_timer.timeout.connect(self._restore_password_copy_icon)
|
|
|
|
# Original Icons speichern
|
|
self.copy_icon = None
|
|
self.check_icon = None
|
|
|
|
self.init_ui()
|
|
|
|
if self.language_manager:
|
|
self.language_manager.language_changed.connect(self.update_texts)
|
|
self.update_texts()
|
|
|
|
def _on_login_clicked(self):
|
|
"""Handler für Login-Button"""
|
|
self.login_requested.emit(self.account_data)
|
|
|
|
def init_ui(self):
|
|
"""Initialisiert die UI nach Styleguide"""
|
|
self.setObjectName("accountCard")
|
|
|
|
# Status-basiertes Styling anwenden
|
|
self._apply_status_styling()
|
|
|
|
# Setze feste Breite für die Karte
|
|
self.setFixedWidth(360)
|
|
|
|
# Hauptlayout
|
|
layout = QVBoxLayout(self)
|
|
layout.setContentsMargins(16, 16, 16, 16)
|
|
layout.setSpacing(12)
|
|
|
|
# Header Zeile
|
|
header_layout = QHBoxLayout()
|
|
|
|
# Platform Icon + Username
|
|
info_layout = QHBoxLayout()
|
|
info_layout.setSpacing(8)
|
|
|
|
# Status wird jetzt über Karten-Hintergrund und Umrandung angezeigt
|
|
|
|
# Platform Icon
|
|
platform_icon = IconFactory.create_icon_label(
|
|
self.account_data.get("platform", "").lower(),
|
|
size=18
|
|
)
|
|
info_layout.addWidget(platform_icon)
|
|
|
|
# Username
|
|
username_label = QLabel(self.account_data.get("username", ""))
|
|
username_font = QFont("Poppins", 16)
|
|
username_font.setWeight(QFont.DemiBold)
|
|
username_label.setFont(username_font)
|
|
username_label.setStyleSheet("""
|
|
color: #1A365D;
|
|
font-family: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
""")
|
|
info_layout.addWidget(username_label)
|
|
info_layout.addStretch()
|
|
|
|
header_layout.addLayout(info_layout)
|
|
|
|
# Login Button
|
|
self.login_btn = QPushButton("Login")
|
|
self.login_btn.setCursor(Qt.PointingHandCursor)
|
|
self.login_btn.setStyleSheet("""
|
|
QPushButton {
|
|
background-color: #3182CE;
|
|
color: #FFFFFF;
|
|
border: none;
|
|
border-radius: 6px;
|
|
padding: 6px 16px;
|
|
font-size: 12px;
|
|
font-weight: 500;
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
min-width: 60px;
|
|
}
|
|
QPushButton:hover {
|
|
background-color: #2563EB;
|
|
}
|
|
QPushButton:pressed {
|
|
background-color: #1D4ED8;
|
|
}
|
|
""")
|
|
self.login_btn.clicked.connect(lambda: self._on_login_clicked())
|
|
header_layout.addWidget(self.login_btn)
|
|
|
|
layout.addLayout(header_layout)
|
|
|
|
# Details Grid
|
|
details_grid = QGridLayout()
|
|
details_grid.setSpacing(8)
|
|
|
|
# Email
|
|
email_icon = IconFactory.create_icon_label("mail", size=14)
|
|
details_grid.addWidget(email_icon, 0, 0)
|
|
|
|
# Email container with copy button
|
|
email_container = QWidget()
|
|
email_layout = QHBoxLayout(email_container)
|
|
email_layout.setContentsMargins(0, 0, 0, 0)
|
|
email_layout.setSpacing(8)
|
|
|
|
email_label = QLabel(self.account_data.get("email", ""))
|
|
email_label.setStyleSheet("""
|
|
color: #4A5568;
|
|
font-size: 13px;
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
""")
|
|
email_layout.addWidget(email_label)
|
|
|
|
# Email Copy Button
|
|
email_copy_btn = QPushButton()
|
|
email_copy_btn.setToolTip("E-Mail kopieren")
|
|
email_copy_btn.setCursor(Qt.PointingHandCursor)
|
|
email_copy_btn.setStyleSheet("""
|
|
QPushButton {
|
|
background: transparent;
|
|
border: none;
|
|
padding: 2px;
|
|
min-width: 20px;
|
|
max-width: 20px;
|
|
min-height: 20px;
|
|
max-height: 20px;
|
|
}
|
|
QPushButton:hover {
|
|
background-color: #F7FAFC;
|
|
border-radius: 4px;
|
|
}
|
|
""")
|
|
self.copy_icon = IconFactory.get_icon("copy", size=16)
|
|
self.check_icon = IconFactory.get_icon("check", size=16, color="#10B981")
|
|
self.email_copy_btn = email_copy_btn
|
|
self.email_copy_btn.setIcon(self.copy_icon)
|
|
self.email_copy_btn.setIconSize(QSize(16, 16))
|
|
email_copy_btn.clicked.connect(self._copy_email)
|
|
email_layout.addWidget(email_copy_btn)
|
|
|
|
email_layout.addStretch()
|
|
details_grid.addWidget(email_container, 0, 1)
|
|
|
|
# Password
|
|
pass_icon = IconFactory.create_icon_label("key", size=14)
|
|
details_grid.addWidget(pass_icon, 1, 0)
|
|
|
|
pass_container = QWidget()
|
|
pass_layout = QHBoxLayout(pass_container)
|
|
pass_layout.setContentsMargins(0, 0, 0, 0)
|
|
pass_layout.setSpacing(8)
|
|
|
|
self.password_label = QLabel("••••••••")
|
|
self.password_label.setStyleSheet("""
|
|
color: #4A5568;
|
|
font-size: 13px;
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
""")
|
|
pass_layout.addWidget(self.password_label)
|
|
|
|
# Copy Button
|
|
copy_btn = QPushButton()
|
|
copy_btn.setToolTip("Passwort kopieren")
|
|
copy_btn.setCursor(Qt.PointingHandCursor)
|
|
copy_btn.setStyleSheet("""
|
|
QPushButton {
|
|
background: transparent;
|
|
border: none;
|
|
padding: 2px;
|
|
min-width: 20px;
|
|
max-width: 20px;
|
|
min-height: 20px;
|
|
max-height: 20px;
|
|
}
|
|
QPushButton:hover {
|
|
background-color: #F7FAFC;
|
|
border-radius: 4px;
|
|
}
|
|
""")
|
|
self.password_copy_btn = copy_btn
|
|
self.password_copy_btn.setIcon(self.copy_icon)
|
|
self.password_copy_btn.setIconSize(QSize(16, 16))
|
|
copy_btn.clicked.connect(self._copy_password)
|
|
pass_layout.addWidget(copy_btn)
|
|
|
|
# Show/Hide Button
|
|
self.visibility_btn = QPushButton()
|
|
self.visibility_btn.setToolTip("Passwort anzeigen")
|
|
self.visibility_btn.setCursor(Qt.PointingHandCursor)
|
|
self.visibility_btn.setStyleSheet("""
|
|
QPushButton {
|
|
background: transparent;
|
|
border: none;
|
|
padding: 2px;
|
|
min-width: 20px;
|
|
max-width: 20px;
|
|
min-height: 20px;
|
|
max-height: 20px;
|
|
}
|
|
QPushButton:hover {
|
|
background-color: #F7FAFC;
|
|
border-radius: 4px;
|
|
}
|
|
""")
|
|
self.eye_icon = IconFactory.get_icon("eye", size=16)
|
|
self.eye_slash_icon = IconFactory.get_icon("eye-slash", size=16)
|
|
self.visibility_btn.setIcon(self.eye_icon)
|
|
self.visibility_btn.setIconSize(QSize(16, 16))
|
|
self.visibility_btn.clicked.connect(self._toggle_password)
|
|
pass_layout.addWidget(self.visibility_btn)
|
|
|
|
pass_layout.addStretch()
|
|
details_grid.addWidget(pass_container, 1, 1)
|
|
|
|
# Created Date
|
|
date_icon = IconFactory.create_icon_label("calendar", size=14)
|
|
details_grid.addWidget(date_icon, 2, 0)
|
|
|
|
date_label = QLabel(self.account_data.get("created_at", ""))
|
|
date_label.setStyleSheet("""
|
|
color: #A0AEC0;
|
|
font-size: 12px;
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
""")
|
|
details_grid.addWidget(date_label, 2, 1)
|
|
|
|
layout.addLayout(details_grid)
|
|
|
|
# Action buttons
|
|
actions_layout = QHBoxLayout()
|
|
actions_layout.setSpacing(8)
|
|
|
|
# Export Button
|
|
self.export_btn = QPushButton("Profil\nexportieren")
|
|
self.export_btn.setCursor(Qt.PointingHandCursor)
|
|
self.export_btn.setStyleSheet("""
|
|
QPushButton {
|
|
background-color: #10B981;
|
|
color: #FFFFFF;
|
|
border: none;
|
|
border-radius: 6px;
|
|
padding: 4px 12px;
|
|
font-size: 12px;
|
|
font-weight: 500;
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
min-width: 120px;
|
|
min-height: 36px;
|
|
text-align: center;
|
|
}
|
|
QPushButton:hover {
|
|
background-color: #059669;
|
|
}
|
|
QPushButton:pressed {
|
|
background-color: #047857;
|
|
}
|
|
""")
|
|
self.export_btn.clicked.connect(lambda: self.export_requested.emit(self.account_data))
|
|
actions_layout.addWidget(self.export_btn)
|
|
|
|
actions_layout.addStretch()
|
|
|
|
# Delete Button
|
|
self.delete_btn = QPushButton("Löschen")
|
|
self.delete_btn.setCursor(Qt.PointingHandCursor)
|
|
self.delete_btn.setStyleSheet("""
|
|
QPushButton {
|
|
background-color: #DC2626;
|
|
color: #FFFFFF;
|
|
border: none;
|
|
border-radius: 6px;
|
|
padding: 8px 16px;
|
|
font-size: 12px;
|
|
font-weight: 500;
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
min-width: 90px;
|
|
}
|
|
QPushButton:hover {
|
|
background-color: #B91C1C;
|
|
}
|
|
QPushButton:pressed {
|
|
background-color: #991B1B;
|
|
}
|
|
""")
|
|
self.delete_btn.clicked.connect(lambda: self.delete_requested.emit(self.account_data))
|
|
actions_layout.addWidget(self.delete_btn)
|
|
|
|
layout.addLayout(actions_layout)
|
|
|
|
def _toggle_password(self):
|
|
"""Zeigt/Versteckt das Passwort"""
|
|
self.password_visible = not self.password_visible
|
|
|
|
if self.password_visible:
|
|
self.password_label.setText(self.account_data.get("password", ""))
|
|
self.visibility_btn.setIcon(self.eye_slash_icon)
|
|
else:
|
|
self.password_label.setText("••••••••")
|
|
self.visibility_btn.setIcon(self.eye_icon)
|
|
|
|
def _copy_password(self):
|
|
"""Kopiert das Passwort in die Zwischenablage"""
|
|
clipboard = QApplication.clipboard()
|
|
clipboard.setText(self.account_data.get("password", ""))
|
|
|
|
# Icon zu Check wechseln
|
|
self.password_copy_btn.setIcon(self.check_icon)
|
|
|
|
# Timer starten um nach 2 Sekunden zurückzuwechseln
|
|
self.password_copy_timer.stop()
|
|
self.password_copy_timer.start(2000)
|
|
|
|
def _copy_email(self):
|
|
"""Kopiert die E-Mail in die Zwischenablage"""
|
|
clipboard = QApplication.clipboard()
|
|
clipboard.setText(self.account_data.get("email", ""))
|
|
|
|
# Icon zu Check wechseln
|
|
self.email_copy_btn.setIcon(self.check_icon)
|
|
|
|
# Timer starten um nach 2 Sekunden zurückzuwechseln
|
|
self.email_copy_timer.stop()
|
|
self.email_copy_timer.start(2000)
|
|
|
|
def update_texts(self):
|
|
"""Aktualisiert die Texte gemäß der aktuellen Sprache"""
|
|
if not self.language_manager:
|
|
return
|
|
|
|
self.login_btn.setText(
|
|
self.language_manager.get_text("account_card.login", "Login")
|
|
)
|
|
self.export_btn.setText(
|
|
self.language_manager.get_text("account_card.export", "Profil\nexportieren")
|
|
)
|
|
self.delete_btn.setText(
|
|
self.language_manager.get_text("account_card.delete", "Löschen")
|
|
)
|
|
|
|
def _restore_email_copy_icon(self):
|
|
"""Stellt das ursprüngliche Copy Icon für Email wieder her"""
|
|
self.email_copy_btn.setIcon(self.copy_icon)
|
|
self.email_copy_timer.stop()
|
|
|
|
def _restore_password_copy_icon(self):
|
|
"""Stellt das ursprüngliche Copy Icon für Passwort wieder her"""
|
|
self.password_copy_btn.setIcon(self.copy_icon)
|
|
self.password_copy_timer.stop()
|
|
|
|
def _apply_status_styling(self):
|
|
"""Wendet Status-basiertes Styling mit Pastel-Hintergrund und farbiger Umrandung an"""
|
|
# Status aus Account-Daten lesen - Standard ist "active" (grün)
|
|
status = self.account_data.get("status", "active")
|
|
|
|
# Status-Farben definieren (nur Grün/Rot)
|
|
status_styles = {
|
|
"active": {
|
|
"background": "#F0FDF4", # Sehr helles Mintgrün
|
|
"border": "#10B981", # Kräftiges Grün
|
|
"hover_border": "#059669" # Dunkleres Grün beim Hover
|
|
},
|
|
"inactive": {
|
|
"background": "#FEF2F2", # Sehr helles Rosa
|
|
"border": "#EF4444", # Kräftiges Rot
|
|
"hover_border": "#DC2626" # Dunkleres Rot beim Hover
|
|
}
|
|
}
|
|
|
|
# Aktueller Status oder Fallback auf active (grün)
|
|
current_style = status_styles.get(status, status_styles["active"])
|
|
|
|
# CSS-Styling anwenden
|
|
self.setStyleSheet(f"""
|
|
QFrame#accountCard {{
|
|
background-color: {current_style["background"]};
|
|
border: 2px solid {current_style["border"]};
|
|
border-radius: 8px;
|
|
padding: 16px;
|
|
}}
|
|
QFrame#accountCard:hover {{
|
|
border: 2px solid {current_style["hover_border"]};
|
|
background-color: {current_style["background"]};
|
|
}}
|
|
""")
|
|
|
|
def update_status(self, new_status: str):
|
|
"""Aktualisiert den Status der Account-Karte und das Styling"""
|
|
self.account_data["status"] = new_status
|
|
self._apply_status_styling() |