Files
AccountForger-neuerUpload/views/dialogs/export_success_dialog.py
2025-11-10 03:43:02 +01:00

390 Zeilen
13 KiB
Python

"""
Erfolgs-Dialog für Profil-Export
Zeigt exportierte Dateien und optional das generierte Passwort an.
"""
import os
import logging
import subprocess
import platform
from pathlib import Path
from typing import List, Optional
from PyQt5.QtWidgets import (
QDialog, QVBoxLayout, QHBoxLayout, QLabel, QPushButton,
QFrame, QGraphicsDropShadowEffect, QApplication, QScrollArea, QWidget
)
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QFont, QColor
logger = logging.getLogger("export_success_dialog")
class ExportSuccessDialog(QDialog):
"""Dialog zur Anzeige von Export-Erfolg"""
def __init__(
self,
parent=None,
exported_files: List[str] = None,
export_directory: str = "",
password: Optional[str] = None
):
"""
Initialisiert den Erfolgs-Dialog.
Args:
parent: Parent-Widget
exported_files: Liste der exportierten Dateinamen
export_directory: Verzeichnis wo Dateien gespeichert wurden
password: Optional generiertes Passwort (nur bei Passwortschutz)
"""
super().__init__(parent)
self.exported_files = exported_files or []
self.export_directory = export_directory
self.password = password
self.init_ui()
def init_ui(self):
"""Initialisiert die UI"""
# Dialog-Eigenschaften
self.setWindowTitle("Export erfolgreich")
self.setWindowFlags(Qt.Dialog | Qt.FramelessWindowHint)
self.setAttribute(Qt.WA_TranslucentBackground, True)
self.setModal(True)
# Dynamische Höhe basierend auf Inhalt
base_height = 280
if self.password:
base_height += 80 # Extra Platz für Passwort-Anzeige
if len(self.exported_files) > 2:
base_height += 20 * (len(self.exported_files) - 2) # Extra für mehr Dateien
self.setFixedSize(500, min(base_height, 500))
# Hauptlayout
main_layout = QVBoxLayout(self)
main_layout.setContentsMargins(20, 20, 20, 20)
# Container mit modernem Design
self.container = QFrame()
self.container.setObjectName("exportSuccessContainer")
self.container.setStyleSheet("""
#exportSuccessContainer {
background-color: white;
border-radius: 12px;
border: 1px solid #E5E7EB;
}
""")
# Schatten-Effekt
shadow = QGraphicsDropShadowEffect()
shadow.setBlurRadius(30)
shadow.setXOffset(0)
shadow.setYOffset(10)
shadow.setColor(QColor(0, 0, 0, 80))
self.container.setGraphicsEffect(shadow)
# Container-Layout
container_layout = QVBoxLayout(self.container)
container_layout.setSpacing(18)
container_layout.setContentsMargins(30, 25, 30, 25)
# Header mit Icon und Titel
header_layout = QHBoxLayout()
header_layout.setSpacing(15)
# Erfolgs-Icon
icon_label = QLabel("")
icon_label.setStyleSheet("font-size: 32px;")
icon_label.setFixedSize(40, 40)
icon_label.setAlignment(Qt.AlignCenter)
# Titel
title_label = QLabel("Profil exportiert!")
title_font = QFont("Poppins", 16)
title_font.setWeight(QFont.DemiBold)
title_label.setFont(title_font)
title_label.setStyleSheet("color: #1F2937;")
header_layout.addWidget(icon_label)
header_layout.addWidget(title_label, 1)
container_layout.addLayout(header_layout)
# Dateien-Liste
files_label = QLabel("Dateien:")
files_label.setStyleSheet("color: #6B7280; font-size: 13px; font-weight: 600;")
container_layout.addWidget(files_label)
# Scrollbare Liste für Dateien
scroll_area = QScrollArea()
scroll_area.setWidgetResizable(True)
scroll_area.setFrameShape(QFrame.NoFrame)
scroll_area.setStyleSheet("""
QScrollArea {
background-color: #F9FAFB;
border-radius: 6px;
border: 1px solid #E5E7EB;
}
""")
files_widget = QWidget()
files_layout = QVBoxLayout(files_widget)
files_layout.setSpacing(4)
files_layout.setContentsMargins(10, 10, 10, 10)
for filename in self.exported_files:
file_label = QLabel(f"{filename}")
file_label.setStyleSheet("""
color: #374151;
font-size: 12px;
font-family: 'Courier New', monospace;
padding: 2px;
""")
file_label.setWordWrap(True)
files_layout.addWidget(file_label)
files_layout.addStretch()
scroll_area.setWidget(files_widget)
scroll_area.setMaximumHeight(120)
container_layout.addWidget(scroll_area)
# Passwort-Anzeige (nur wenn Passwort vorhanden)
if self.password:
password_frame = QFrame()
password_frame.setStyleSheet("""
QFrame {
background-color: #FEF3C7;
border: 1px solid #FCD34D;
border-radius: 6px;
padding: 12px;
}
""")
password_layout = QVBoxLayout(password_frame)
password_layout.setSpacing(8)
# Warnung
warning_label = QLabel("⚠ Bitte Passwort speichern!")
warning_label.setStyleSheet("""
color: #92400E;
font-size: 13px;
font-weight: 600;
""")
# Passwort mit Copy-Button
password_row = QHBoxLayout()
password_row.setSpacing(10)
password_label = QLabel(f"🔒 Passwort: {self.password}")
password_label.setStyleSheet("""
color: #78350F;
font-size: 13px;
font-family: 'Courier New', monospace;
font-weight: 600;
""")
password_label.setTextInteractionFlags(Qt.TextSelectableByMouse)
copy_button = QPushButton("Kopieren")
copy_button.setMaximumWidth(80)
copy_button.setMinimumHeight(28)
copy_button.setCursor(Qt.PointingHandCursor)
copy_button.setStyleSheet("""
QPushButton {
background-color: #F59E0B;
color: white;
border: none;
border-radius: 4px;
font-size: 12px;
font-weight: 600;
padding: 4px 8px;
}
QPushButton:hover {
background-color: #D97706;
}
QPushButton:pressed {
background-color: #B45309;
}
""")
copy_button.clicked.connect(self.copy_password)
password_row.addWidget(password_label, 1)
password_row.addWidget(copy_button)
password_layout.addWidget(warning_label)
password_layout.addLayout(password_row)
container_layout.addWidget(password_frame)
# Speicherort
location_label = QLabel(f"Gespeichert in:")
location_label.setStyleSheet("color: #6B7280; font-size: 12px;")
path_label = QLabel(self._format_path(self.export_directory))
path_label.setStyleSheet("""
color: #4B5563;
font-size: 11px;
font-family: 'Courier New', monospace;
""")
path_label.setWordWrap(True)
path_label.setTextInteractionFlags(Qt.TextSelectableByMouse)
container_layout.addWidget(location_label)
container_layout.addWidget(path_label)
# Spacer
container_layout.addStretch()
# Button-Layout
button_layout = QHBoxLayout()
button_layout.setSpacing(10)
button_layout.addStretch()
# Ordner öffnen Button
self.open_folder_button = QPushButton("Ordner öffnen")
self.open_folder_button.setMinimumHeight(38)
self.open_folder_button.setMinimumWidth(120)
self.open_folder_button.setCursor(Qt.PointingHandCursor)
self.open_folder_button.setStyleSheet("""
QPushButton {
background-color: #F3F4F6;
color: #374151;
border: none;
border-radius: 6px;
font-size: 13px;
font-weight: 600;
padding: 8px 16px;
}
QPushButton:hover {
background-color: #E5E7EB;
}
QPushButton:pressed {
background-color: #D1D5DB;
}
""")
self.open_folder_button.clicked.connect(self.open_folder)
# OK Button
self.ok_button = QPushButton("OK")
self.ok_button.setMinimumHeight(38)
self.ok_button.setMinimumWidth(100)
self.ok_button.setCursor(Qt.PointingHandCursor)
self.ok_button.setStyleSheet("""
QPushButton {
background-color: #10B981;
color: white;
border: none;
border-radius: 6px;
font-size: 13px;
font-weight: 600;
padding: 8px 16px;
}
QPushButton:hover {
background-color: #059669;
}
QPushButton:pressed {
background-color: #047857;
}
""")
self.ok_button.clicked.connect(self.accept)
button_layout.addWidget(self.open_folder_button)
button_layout.addWidget(self.ok_button)
container_layout.addLayout(button_layout)
# Container zum Hauptlayout hinzufügen
main_layout.addWidget(self.container)
def copy_password(self):
"""Kopiert das Passwort in die Zwischenablage"""
if self.password:
clipboard = QApplication.clipboard()
clipboard.setText(self.password)
logger.info("Passwort in Zwischenablage kopiert")
# Kurzes visuelles Feedback
sender = self.sender()
if sender:
original_text = sender.text()
sender.setText("✓ Kopiert!")
sender.setStyleSheet(sender.styleSheet().replace("#F59E0B", "#10B981"))
# Nach 2 Sekunden zurücksetzen
from PyQt5.QtCore import QTimer
QTimer.singleShot(2000, lambda: self._reset_copy_button(sender, original_text))
def _reset_copy_button(self, button, original_text):
"""Setzt den Copy-Button zurück"""
if button:
button.setText(original_text)
button.setStyleSheet(button.styleSheet().replace("#10B981", "#F59E0B"))
def open_folder(self):
"""Öffnet den Export-Ordner im Datei-Explorer"""
if not self.export_directory or not os.path.exists(self.export_directory):
logger.warning(f"Export-Verzeichnis existiert nicht: {self.export_directory}")
return
try:
system = platform.system()
if system == "Windows":
# Windows Explorer
os.startfile(self.export_directory)
elif system == "Darwin":
# macOS Finder
subprocess.run(["open", self.export_directory])
elif system == "Linux":
# Linux File Manager
subprocess.run(["xdg-open", self.export_directory])
else:
logger.warning(f"Unbekanntes Betriebssystem: {system}")
logger.info(f"Ordner geöffnet: {self.export_directory}")
except Exception as e:
logger.error(f"Fehler beim Öffnen des Ordners: {e}")
def _format_path(self, path: str) -> str:
"""
Formatiert den Pfad für die Anzeige.
Kürzt zu lange Pfade.
"""
if not path:
return ""
max_length = 60
if len(path) <= max_length:
return path
# Pfad kürzen: Anfang ... Ende
start_length = 25
end_length = max_length - start_length - 3
return f"{path[:start_length]}...{path[-end_length:]}"
# Helper-Funktion für einfache Verwendung
def show_export_success(
parent,
exported_files: List[str],
export_directory: str,
password: Optional[str] = None
):
"""
Zeigt den Export-Erfolgs-Dialog modal an.
Args:
parent: Parent-Widget
exported_files: Liste der exportierten Dateinamen
export_directory: Verzeichnis wo Dateien gespeichert wurden
password: Optional generiertes Passwort
"""
dialog = ExportSuccessDialog(parent, exported_files, export_directory, password)
dialog.exec_()