Dieser Commit ist enthalten in:
Claude Project Manager
2025-08-01 23:50:28 +02:00
Commit 04585e95b6
290 geänderte Dateien mit 64086 neuen und 0 gelöschten Zeilen

7
views/dialogs/__init__.py Normale Datei
Datei anzeigen

@ -0,0 +1,7 @@
"""
Dialog-Module für die AccountForger Anwendung.
"""
from .license_activation_dialog import LicenseActivationDialog
__all__ = ['LicenseActivationDialog']

Datei anzeigen

@ -0,0 +1,69 @@
"""
Zentralisierte UI-Dialoge für Account-Erstellung
"""
from PyQt5.QtWidgets import QMessageBox
from typing import Dict, Any, Optional
class AccountInfo:
"""Datenklasse für Account-Informationen"""
def __init__(self, username: str, password: str, email: Optional[str] = None, phone: Optional[str] = None):
self.username = username
self.password = password
self.email = email
self.phone = phone
class AccountCreationResultDialog:
"""Kapselt alle UI-Dialoge für Account-Erstellung"""
@staticmethod
def show_success(parent, account_info: AccountInfo):
"""Zeigt Erfolgs-Dialog"""
message = f"Account erfolgreich erstellt!\n\n"
message += f"Benutzername: {account_info.username}\n"
message += f"Passwort: {account_info.password}\n"
if account_info.email:
message += f"E-Mail: {account_info.email}"
elif account_info.phone:
message += f"Telefon: {account_info.phone}"
QMessageBox.information(
parent,
"Erfolg",
message
)
@staticmethod
def show_error(parent, error_message: str):
"""Zeigt Fehler-Dialog"""
QMessageBox.critical(parent, "Fehler", error_message)
@staticmethod
def show_warning(parent, warning_message: str):
"""Zeigt Warnung-Dialog"""
QMessageBox.warning(parent, "Warnung", warning_message)
@staticmethod
def show_account_details(parent, platform: str, account_data: Dict[str, Any]):
"""Zeigt detaillierte Account-Informationen"""
username = account_data.get('username', '')
password = account_data.get('password', '')
email = account_data.get('email')
phone = account_data.get('phone')
account_info = AccountInfo(username, password, email, phone)
AccountCreationResultDialog.show_success(parent, account_info)
@staticmethod
def confirm_cancel(parent) -> bool:
"""Zeigt Bestätigungs-Dialog für Abbruch"""
reply = QMessageBox.question(
parent,
"Abbrechen bestätigen",
"Möchten Sie die Account-Erstellung wirklich abbrechen?",
QMessageBox.Yes | QMessageBox.No,
QMessageBox.No
)
return reply == QMessageBox.Yes

Datei anzeigen

@ -0,0 +1,262 @@
"""
License Activation Dialog für die Lizenz-Eingabe beim Start.
"""
from PyQt5.QtWidgets import (
QDialog, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit,
QPushButton, QTextEdit, QGroupBox, QSizePolicy
)
from PyQt5.QtCore import Qt, pyqtSignal, QThread
from PyQt5.QtGui import QFont, QPixmap
import logging
import os
logger = logging.getLogger(__name__)
class ActivationWorker(QThread):
"""Worker Thread für die Lizenz-Aktivierung."""
finished = pyqtSignal(dict)
progress = pyqtSignal(str)
def __init__(self, license_manager, license_key):
super().__init__()
self.license_manager = license_manager
self.license_key = license_key
def run(self):
"""Führt die Aktivierung im Hintergrund aus."""
try:
self.progress.emit("Verbinde mit License Server...")
result = self.license_manager.activate_license(self.license_key)
self.finished.emit(result)
except Exception as e:
logger.error(f"Fehler bei der Aktivierung: {e}")
self.finished.emit({
"success": False,
"error": f"Unerwarteter Fehler: {str(e)}"
})
class LicenseActivationDialog(QDialog):
"""Dialog für die Lizenz-Aktivierung beim Start."""
activation_successful = pyqtSignal()
def __init__(self, license_manager, parent=None):
super().__init__(parent)
self.license_manager = license_manager
self.worker = None
self.init_ui()
def init_ui(self):
"""Initialisiert die UI."""
self.setWindowTitle("Lizenz-Aktivierung")
self.setModal(True)
self.setMinimumWidth(500)
self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint)
# Main Layout
layout = QVBoxLayout()
layout.setSpacing(20)
# Header mit Logo/Icon
header_layout = QHBoxLayout()
# App Icon
icon_label = QLabel()
icon_path = os.path.join("resources", "icons", "app_icon.png")
if os.path.exists(icon_path):
pixmap = QPixmap(icon_path).scaled(64, 64, Qt.KeepAspectRatio, Qt.SmoothTransformation)
icon_label.setPixmap(pixmap)
else:
icon_label.setText("🔐")
icon_label.setStyleSheet("font-size: 48px;")
# Title
title_layout = QVBoxLayout()
title_label = QLabel("Account Forger")
title_label.setStyleSheet("font-size: 24px; font-weight: bold;")
subtitle_label = QLabel("Bitte geben Sie Ihren Lizenzschlüssel ein")
subtitle_label.setStyleSheet("color: #666;")
title_layout.addWidget(title_label)
title_layout.addWidget(subtitle_label)
header_layout.addWidget(icon_label)
header_layout.addSpacing(20)
header_layout.addLayout(title_layout)
header_layout.addStretch()
layout.addLayout(header_layout)
# License Key Input
key_group = QGroupBox("Lizenzschlüssel")
key_layout = QVBoxLayout()
self.key_input = QLineEdit()
self.key_input.setPlaceholderText("XXXX-XXXX-XXXX-XXXX")
self.key_input.setStyleSheet("""
QLineEdit {
padding: 10px;
font-size: 16px;
font-family: monospace;
letter-spacing: 2px;
}
""")
# Format helper
format_label = QLabel("Format: AF-F-202506-XXXX-XXXX-XXXX")
format_label.setStyleSheet("color: #999; font-size: 12px;")
key_layout.addWidget(self.key_input)
key_layout.addWidget(format_label)
key_group.setLayout(key_layout)
layout.addWidget(key_group)
# Status/Error Display
self.status_text = QTextEdit()
self.status_text.setReadOnly(True)
self.status_text.setMaximumHeight(100)
self.status_text.hide()
self.status_text.setStyleSheet("""
QTextEdit {
border: 1px solid #ddd;
border-radius: 4px;
padding: 8px;
background-color: #f8f8f8;
}
""")
layout.addWidget(self.status_text)
# Buttons
button_layout = QHBoxLayout()
self.activate_button = QPushButton("Aktivieren")
self.activate_button.setDefault(True)
self.activate_button.setStyleSheet("""
QPushButton {
padding: 10px 30px;
font-size: 14px;
font-weight: bold;
background-color: #2196F3;
color: white;
border: none;
border-radius: 4px;
}
QPushButton:hover {
background-color: #1976D2;
}
QPushButton:disabled {
background-color: #ccc;
}
""")
self.activate_button.clicked.connect(self.activate_license)
self.exit_button = QPushButton("Beenden")
self.exit_button.setStyleSheet("""
QPushButton {
padding: 10px 30px;
font-size: 14px;
}
""")
self.exit_button.clicked.connect(self.reject)
button_layout.addStretch()
button_layout.addWidget(self.exit_button)
button_layout.addWidget(self.activate_button)
layout.addLayout(button_layout)
# Info Text
info_label = QLabel(
"Sie benötigen einen gültigen Lizenzschlüssel, um diese Software zu nutzen.\n"
"Kontaktieren Sie den Support, falls Sie noch keinen Lizenzschlüssel haben."
)
info_label.setWordWrap(True)
info_label.setStyleSheet("color: #666; font-size: 12px; padding: 10px;")
info_label.setAlignment(Qt.AlignCenter)
layout.addWidget(info_label)
self.setLayout(layout)
# Focus auf Input
self.key_input.setFocus()
# Enter zum Aktivieren
self.key_input.returnPressed.connect(self.activate_license)
def activate_license(self):
"""Startet die Lizenz-Aktivierung."""
license_key = self.key_input.text().strip()
if not license_key:
self.show_error("Bitte geben Sie einen Lizenzschlüssel ein.")
return
# UI für Aktivierung vorbereiten
self.activate_button.setEnabled(False)
self.key_input.setEnabled(False)
self.status_text.clear()
self.status_text.show()
self.status_text.append("🔄 Aktivierung läuft...")
# Worker Thread starten
self.worker = ActivationWorker(self.license_manager, license_key)
self.worker.progress.connect(self.update_status)
self.worker.finished.connect(self.activation_finished)
self.worker.start()
def update_status(self, message):
"""Aktualisiert den Status-Text."""
self.status_text.append(f"📡 {message}")
def activation_finished(self, result):
"""Verarbeitet das Ergebnis der Aktivierung."""
self.activate_button.setEnabled(True)
self.key_input.setEnabled(True)
if result.get("success"):
self.status_text.append("✅ Lizenz erfolgreich aktiviert!")
# Update Info anzeigen
if result.get("update_available"):
self.status_text.append(
f" Update verfügbar: Version {result.get('latest_version')}"
)
# Signal senden und Dialog schließen
self.activation_successful.emit()
self.accept()
else:
error = result.get("error", "Unbekannter Fehler")
self.show_error(error)
self.key_input.setFocus()
self.key_input.selectAll()
def show_error(self, error):
"""Zeigt eine Fehlermeldung an."""
self.status_text.show()
self.status_text.clear()
self.status_text.append(f"❌ Fehler: {error}")
self.status_text.setStyleSheet("""
QTextEdit {
border: 1px solid #f44336;
border-radius: 4px;
padding: 8px;
background-color: #ffebee;
color: #c62828;
}
""")
def closeEvent(self, event):
"""Verhindert das Schließen während der Aktivierung."""
if self.worker and self.worker.isRunning():
event.ignore()
else:
event.accept()