Kein PW bei Export
Dieser Commit ist enthalten in:
@ -1,38 +1,13 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(curl:*)",
|
||||
"Bash(nslookup:*)",
|
||||
"WebFetch(domain:multilogin.com)",
|
||||
"WebFetch(domain:dicloak.com)",
|
||||
"WebFetch(domain:support.google.com)",
|
||||
"Bash(python3 -m pip list:*)",
|
||||
"Bash(python3:*)",
|
||||
"Bash(grep:*)",
|
||||
"Bash(cat:*)",
|
||||
"Bash(claude config)",
|
||||
"Bash(claude config list:*)",
|
||||
"Bash(claude mcp)",
|
||||
"Bash(claude mcp:*)",
|
||||
"Bash(sqlite3:*)",
|
||||
"Bash(python -m pip install:*)",
|
||||
"Bash(python -m pytest teststest_generator_tab_factory.py -v)",
|
||||
"Bash(python tests:*)",
|
||||
"Bash(python tests/test_generator_tab_factory.py)",
|
||||
"Bash(git push:*)",
|
||||
"Bash(git remote set-url:*)",
|
||||
"WebSearch",
|
||||
"Bash(find:*)",
|
||||
"Bash(mount:*)",
|
||||
"Read(//mnt/a/**)",
|
||||
"Read(//mnt/c/Users/Administrator/AppData/Local/Programs/Python/Python310/**)",
|
||||
"Read(//mnt/c/Users/Administrator/**)",
|
||||
"Bash(/mnt/c/Users/Administrator/AppData/Local/Programs/Python/Python310/python.exe -c \"\nimport sys\nsys.dont_write_bytecode = True # Verhindere .pyc Erstellung\nimport utils.email_handler as eh\nhandler = eh.EmailHandler()\npw = handler.config[''imap_pass'']\nprint(f''Windows Python lädt Passwort: {pw[:4]}...{pw[-4:]}'')\nif ''GZsg'' in pw:\n print(''✅ NEUES Passwort wird geladen!'')\nelse:\n print(''❌ ALTES Passwort wird noch geladen!'')\n\")"
|
||||
"Bash(python3:*)"
|
||||
],
|
||||
"deny": [],
|
||||
"defaultMode": "acceptEdits",
|
||||
"additionalDirectories": [
|
||||
"/mnt/a/GiTea/Styleguide"
|
||||
]
|
||||
],
|
||||
"ask": []
|
||||
}
|
||||
}
|
||||
|
||||
0
CLAUDE.md
Normale Datei
0
CLAUDE.md
Normale Datei
@ -5,9 +5,9 @@
|
||||
## Project Overview
|
||||
|
||||
- **Path**: `A:\GiTea\AccountForger`
|
||||
- **Files**: 1317 files
|
||||
- **Size**: 240.4 MB
|
||||
- **Last Modified**: 2025-11-09 20:55
|
||||
- **Files**: 1393 files
|
||||
- **Size**: 257.7 MB
|
||||
- **Last Modified**: 2025-11-16 22:31
|
||||
|
||||
## Technology Stack
|
||||
|
||||
@ -65,6 +65,7 @@ config/
|
||||
controllers/
|
||||
│ ├── account_controller.py
|
||||
│ ├── main_controller.py
|
||||
│ ├── profile_export_controller.py
|
||||
│ ├── session_controller.py
|
||||
│ ├── settings_controller.py
|
||||
│ └── platform_controllers/
|
||||
@ -360,8 +361,8 @@ utils/
|
||||
│ ├── modal_test.py
|
||||
│ ├── password_generator.py
|
||||
│ ├── performance_monitor.py
|
||||
│ ├── proxy_rotator.py
|
||||
│ └── result_decorators.py
|
||||
│ ├── process_guard.py
|
||||
│ └── profile_export_service.py
|
||||
views/
|
||||
├── about_dialog.py
|
||||
├── main_window.py
|
||||
@ -376,7 +377,9 @@ views/
|
||||
│ └── __init__.py
|
||||
├── dialogs/
|
||||
│ ├── account_creation_result_dialog.py
|
||||
│ ├── export_success_dialog.py
|
||||
│ ├── license_activation_dialog.py
|
||||
│ ├── profile_export_dialog.py
|
||||
│ └── __init__.py
|
||||
├── tabs/
|
||||
│ ├── accounts_tab.py
|
||||
@ -431,3 +434,5 @@ This project is managed with Claude Project Manager. To work with this project:
|
||||
- README updated on 2025-10-08 22:34:43
|
||||
- README updated on 2025-10-18 22:23:22
|
||||
- README updated on 2025-11-09 21:00:06
|
||||
- README updated on 2025-11-16 22:31:39
|
||||
- README updated on 2025-11-16 22:32:35
|
||||
|
||||
@ -71,7 +71,7 @@ class ProfileExportController:
|
||||
logger.info(f"Export-Optionen: Formate={formats}, Passwort={password_protect}")
|
||||
|
||||
# 3. Speicherort wählen
|
||||
save_directory = self._select_save_location(parent_widget, account_data, formats, password_protect)
|
||||
save_directory = self._select_save_location(parent_widget, account_data, formats)
|
||||
|
||||
if not save_directory:
|
||||
logger.info("Kein Speicherort ausgewählt - Export abgebrochen")
|
||||
@ -79,11 +79,11 @@ class ProfileExportController:
|
||||
|
||||
logger.info(f"Speicherort: {save_directory}")
|
||||
|
||||
# 4. Export durchführen
|
||||
files_dict, password = self.export_service.export_account(
|
||||
# 4. Export durchführen (ohne Passwortschutz)
|
||||
files_dict = self.export_service.export_account(
|
||||
account_data,
|
||||
formats,
|
||||
password_protect
|
||||
password_protect=False
|
||||
)
|
||||
|
||||
if not files_dict:
|
||||
@ -117,8 +117,7 @@ class ProfileExportController:
|
||||
show_export_success(
|
||||
parent_widget,
|
||||
saved_files,
|
||||
save_directory,
|
||||
password
|
||||
save_directory
|
||||
)
|
||||
|
||||
logger.info(f"Export erfolgreich: {len(saved_files)} Datei(en) gespeichert")
|
||||
@ -136,12 +135,6 @@ class ProfileExportController:
|
||||
"Bitte installieren Sie die erforderlichen Bibliotheken:\n"
|
||||
"pip install reportlab svglib"
|
||||
)
|
||||
elif "pyzipper" in error_message.lower():
|
||||
error_message = (
|
||||
"Passwortgeschützter Export ist nicht verfügbar.\n\n"
|
||||
"Bitte installieren Sie die erforderliche Bibliothek:\n"
|
||||
"pip install pyzipper"
|
||||
)
|
||||
|
||||
show_error(
|
||||
parent_widget,
|
||||
@ -154,62 +147,30 @@ class ProfileExportController:
|
||||
self,
|
||||
parent_widget,
|
||||
account_data: Dict[str, Any],
|
||||
formats: list,
|
||||
password_protect: bool
|
||||
formats: list
|
||||
) -> Optional[str]:
|
||||
"""
|
||||
Öffnet einen Datei-Dialog zur Auswahl des Speicherorts.
|
||||
Öffnet einen Verzeichnis-Dialog zur Auswahl des Speicherorts.
|
||||
|
||||
Args:
|
||||
parent_widget: Parent-Widget
|
||||
account_data: Account-Daten
|
||||
formats: Liste der Export-Formate
|
||||
password_protect: Ob Passwortschutz aktiviert ist
|
||||
|
||||
Returns:
|
||||
Ausgewähltes Verzeichnis oder None bei Abbruch
|
||||
"""
|
||||
# Standard-Dateiname generieren
|
||||
if password_protect:
|
||||
# Bei Passwortschutz wird eine ZIP erstellt
|
||||
default_filename = self.export_service.generate_filename(
|
||||
account_data,
|
||||
"zip"
|
||||
)
|
||||
else:
|
||||
# Ohne Passwortschutz: Ersten Format als Beispiel nehmen
|
||||
first_format = formats[0] if formats else "csv"
|
||||
default_filename = self.export_service.generate_filename(
|
||||
account_data,
|
||||
first_format
|
||||
)
|
||||
|
||||
# Standard-Speicherort: Benutzer-Downloads-Ordner
|
||||
default_directory = str(Path.home() / "Downloads")
|
||||
|
||||
if password_protect:
|
||||
# Für ZIP: File-Dialog
|
||||
file_path, _ = QFileDialog.getSaveFileName(
|
||||
parent_widget,
|
||||
"Profil exportieren",
|
||||
os.path.join(default_directory, default_filename),
|
||||
"ZIP-Archiv (*.zip)"
|
||||
)
|
||||
# Verzeichnis-Dialog für mehrere Dateien
|
||||
directory = QFileDialog.getExistingDirectory(
|
||||
parent_widget,
|
||||
"Speicherort für Export auswählen",
|
||||
default_directory
|
||||
)
|
||||
|
||||
if not file_path:
|
||||
return None
|
||||
|
||||
# Verzeichnis aus Dateipfad extrahieren
|
||||
return os.path.dirname(file_path)
|
||||
else:
|
||||
# Für mehrere Dateien: Verzeichnis-Dialog
|
||||
directory = QFileDialog.getExistingDirectory(
|
||||
parent_widget,
|
||||
"Speicherort für Export auswählen",
|
||||
default_directory
|
||||
)
|
||||
|
||||
return directory if directory else None
|
||||
return directory if directory else None
|
||||
|
||||
def export_multiple_accounts(self, parent_widget, account_ids: list) -> bool:
|
||||
"""
|
||||
|
||||
@ -1,18 +1,16 @@
|
||||
"""
|
||||
Profil-Export-Service für Account-Daten
|
||||
|
||||
Exportiert Account-Profile in verschiedene Formate (CSV, TXT, PDF)
|
||||
mit optionalem Passwortschutz.
|
||||
Exportiert Account-Profile in verschiedene Formate (CSV, TXT, PDF).
|
||||
"""
|
||||
|
||||
import os
|
||||
import csv
|
||||
import secrets
|
||||
import string
|
||||
import logging
|
||||
from io import BytesIO, StringIO
|
||||
from datetime import datetime
|
||||
from typing import Dict, Any, List, Optional, Tuple
|
||||
from typing import Dict, Any, List
|
||||
from pathlib import Path
|
||||
|
||||
logger = logging.getLogger("profile_export_service")
|
||||
@ -287,88 +285,6 @@ class ProfileExportService:
|
||||
logger.error(f"Fehler beim PDF-Export: {e}")
|
||||
raise
|
||||
|
||||
@staticmethod
|
||||
def generate_password(length: int = 10) -> str:
|
||||
"""
|
||||
Generiert ein sicheres zufälliges Passwort.
|
||||
|
||||
Args:
|
||||
length: Länge des Passworts (Standard: 10)
|
||||
|
||||
Returns:
|
||||
Generiertes Passwort
|
||||
"""
|
||||
# Zeichensatz: Groß- und Kleinbuchstaben, Zahlen, Sonderzeichen
|
||||
alphabet = string.ascii_letters + string.digits + "!@#$%^&*"
|
||||
|
||||
# Sicherstellen dass mindestens ein Zeichen von jedem Typ vorhanden ist
|
||||
password_chars = [
|
||||
secrets.choice(string.ascii_uppercase), # Mindestens ein Großbuchstabe
|
||||
secrets.choice(string.ascii_lowercase), # Mindestens ein Kleinbuchstabe
|
||||
secrets.choice(string.digits), # Mindestens eine Zahl
|
||||
secrets.choice("!@#$%^&*") # Mindestens ein Sonderzeichen
|
||||
]
|
||||
|
||||
# Rest auffüllen
|
||||
for _ in range(length - 4):
|
||||
password_chars.append(secrets.choice(alphabet))
|
||||
|
||||
# Mischen für Zufälligkeit
|
||||
secrets.SystemRandom().shuffle(password_chars)
|
||||
|
||||
password = ''.join(password_chars)
|
||||
logger.info("Passwort generiert")
|
||||
return password
|
||||
|
||||
@staticmethod
|
||||
def create_protected_zip(files_dict: Dict[str, bytes], password: str) -> bytes:
|
||||
"""
|
||||
Erstellt eine passwortgeschützte ZIP-Datei.
|
||||
|
||||
Args:
|
||||
files_dict: Dictionary mit {filename: content} Paaren
|
||||
password: Passwort für die ZIP-Datei
|
||||
|
||||
Returns:
|
||||
ZIP-Daten als bytes
|
||||
"""
|
||||
try:
|
||||
import pyzipper
|
||||
|
||||
# ZIP-Buffer erstellen
|
||||
buffer = BytesIO()
|
||||
|
||||
# ZIP mit AES-Verschlüsselung erstellen
|
||||
with pyzipper.AESZipFile(
|
||||
buffer,
|
||||
'w',
|
||||
compression=pyzipper.ZIP_DEFLATED,
|
||||
encryption=pyzipper.WZ_AES
|
||||
) as zf:
|
||||
# Passwort setzen
|
||||
zf.setpassword(password.encode('utf-8'))
|
||||
|
||||
# Dateien hinzufügen
|
||||
for filename, content in files_dict.items():
|
||||
zf.writestr(filename, content)
|
||||
|
||||
# Buffer-Wert holen
|
||||
zip_content = buffer.getvalue()
|
||||
buffer.close()
|
||||
|
||||
logger.info(f"Passwortgeschützte ZIP erstellt mit {len(files_dict)} Dateien")
|
||||
return zip_content
|
||||
|
||||
except ImportError as e:
|
||||
logger.error(f"pyzipper nicht installiert: {e}")
|
||||
raise Exception(
|
||||
"ZIP mit Passwortschutz erfordert 'pyzipper' Library. "
|
||||
"Bitte installieren Sie: pip install pyzipper"
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Fehler beim Erstellen der geschützten ZIP: {e}")
|
||||
raise
|
||||
|
||||
@staticmethod
|
||||
def generate_filename(
|
||||
account_data: Dict[str, Any],
|
||||
@ -427,19 +343,17 @@ class ProfileExportService:
|
||||
account_data: Dict[str, Any],
|
||||
formats: List[str],
|
||||
password_protect: bool = False
|
||||
) -> Tuple[Dict[str, bytes], Optional[str]]:
|
||||
) -> Dict[str, bytes]:
|
||||
"""
|
||||
Exportiert Account-Daten in angegebene Formate.
|
||||
|
||||
Args:
|
||||
account_data: Account-Daten zum Exportieren
|
||||
formats: Liste von Formaten ["csv", "txt", "pdf"]
|
||||
password_protect: Ob Dateien passwortgeschützt werden sollen
|
||||
password_protect: Wird ignoriert (für Rückwärtskompatibilität)
|
||||
|
||||
Returns:
|
||||
Tuple von (files_dict, password)
|
||||
- files_dict: {filename: content} für alle Formate
|
||||
- password: Generiertes Passwort (None wenn nicht geschützt)
|
||||
Dict mit {filename: content} für alle Formate
|
||||
"""
|
||||
files_dict = {}
|
||||
|
||||
@ -464,16 +378,4 @@ class ProfileExportService:
|
||||
else:
|
||||
logger.warning(f"Unbekanntes Format ignoriert: {fmt}")
|
||||
|
||||
# Passwortschutz wenn gewünscht
|
||||
password = None
|
||||
if password_protect and files_dict:
|
||||
password = ProfileExportService.generate_password()
|
||||
|
||||
# Alle Dateien in ZIP packen
|
||||
zip_filename = ProfileExportService.generate_filename(account_data, "zip")
|
||||
zip_content = ProfileExportService.create_protected_zip(files_dict, password)
|
||||
|
||||
# Nur ZIP zurückgeben
|
||||
files_dict = {zip_filename: zip_content}
|
||||
|
||||
return files_dict, password
|
||||
return files_dict
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
"""
|
||||
Erfolgs-Dialog für Profil-Export
|
||||
|
||||
Zeigt exportierte Dateien und optional das generierte Passwort an.
|
||||
Zeigt exportierte Dateien an.
|
||||
"""
|
||||
|
||||
import os
|
||||
@ -9,11 +9,11 @@ import logging
|
||||
import subprocess
|
||||
import platform
|
||||
from pathlib import Path
|
||||
from typing import List, Optional
|
||||
from typing import List
|
||||
|
||||
from PyQt5.QtWidgets import (
|
||||
QDialog, QVBoxLayout, QHBoxLayout, QLabel, QPushButton,
|
||||
QFrame, QGraphicsDropShadowEffect, QApplication, QScrollArea, QWidget
|
||||
QFrame, QGraphicsDropShadowEffect, QScrollArea, QWidget
|
||||
)
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtGui import QFont, QColor
|
||||
@ -28,8 +28,7 @@ class ExportSuccessDialog(QDialog):
|
||||
self,
|
||||
parent=None,
|
||||
exported_files: List[str] = None,
|
||||
export_directory: str = "",
|
||||
password: Optional[str] = None
|
||||
export_directory: str = ""
|
||||
):
|
||||
"""
|
||||
Initialisiert den Erfolgs-Dialog.
|
||||
@ -38,12 +37,10 @@ class ExportSuccessDialog(QDialog):
|
||||
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):
|
||||
@ -55,10 +52,8 @@ class ExportSuccessDialog(QDialog):
|
||||
self.setAttribute(Qt.WA_TranslucentBackground, True)
|
||||
self.setModal(True)
|
||||
|
||||
# Dynamische Höhe basierend auf Inhalt
|
||||
# Dynamische Höhe basierend auf Anzahl der Dateien
|
||||
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
|
||||
|
||||
@ -153,72 +148,6 @@ class ExportSuccessDialog(QDialog):
|
||||
|
||||
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;")
|
||||
@ -299,30 +228,6 @@ class ExportSuccessDialog(QDialog):
|
||||
# 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):
|
||||
@ -373,8 +278,7 @@ class ExportSuccessDialog(QDialog):
|
||||
def show_export_success(
|
||||
parent,
|
||||
exported_files: List[str],
|
||||
export_directory: str,
|
||||
password: Optional[str] = None
|
||||
export_directory: str
|
||||
):
|
||||
"""
|
||||
Zeigt den Export-Erfolgs-Dialog modal an.
|
||||
@ -383,7 +287,6 @@ def show_export_success(
|
||||
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 = ExportSuccessDialog(parent, exported_files, export_directory)
|
||||
dialog.exec_()
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
"""
|
||||
Export-Dialog für Account-Profile
|
||||
|
||||
Ermöglicht Auswahl von Export-Formaten und Passwortschutz.
|
||||
Ermöglicht Auswahl von Export-Formaten.
|
||||
"""
|
||||
|
||||
import logging
|
||||
@ -153,36 +153,6 @@ class ProfileExportDialog(QDialog):
|
||||
|
||||
container_layout.addWidget(format_group)
|
||||
|
||||
# Passwortschutz-Checkbox
|
||||
self.password_checkbox = QCheckBox("Mit Passwort schützen")
|
||||
self.password_checkbox.setChecked(False)
|
||||
self.password_checkbox.setStyleSheet("""
|
||||
QCheckBox {
|
||||
font-size: 13px;
|
||||
font-family: 'Poppins', sans-serif;
|
||||
font-weight: 500;
|
||||
color: #374151;
|
||||
spacing: 8px;
|
||||
}
|
||||
QCheckBox::indicator {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border-radius: 4px;
|
||||
border: 2px solid #D1D5DB;
|
||||
}
|
||||
QCheckBox::indicator:checked {
|
||||
background-color: #10B981;
|
||||
border-color: #10B981;
|
||||
}
|
||||
""")
|
||||
|
||||
# Info-Text für Passwortschutz
|
||||
password_info = QLabel("(Wird automatisch generiert)")
|
||||
password_info.setStyleSheet("color: #9CA3AF; font-size: 11px; font-family: 'Poppins', sans-serif; margin-left: 26px;")
|
||||
|
||||
container_layout.addWidget(self.password_checkbox)
|
||||
container_layout.addWidget(password_info)
|
||||
|
||||
# Spacer
|
||||
container_layout.addStretch()
|
||||
|
||||
@ -271,8 +241,8 @@ class ProfileExportDialog(QDialog):
|
||||
)
|
||||
return
|
||||
|
||||
# Passwortschutz-Option
|
||||
password_protect = self.password_checkbox.isChecked()
|
||||
# Passwortschutz ist entfernt - immer False
|
||||
password_protect = False
|
||||
|
||||
# Signal emittieren
|
||||
self.export_confirmed.emit(selected_formats, password_protect)
|
||||
@ -295,7 +265,8 @@ class ProfileExportDialog(QDialog):
|
||||
if self.pdf_checkbox.isChecked():
|
||||
formats.append("pdf")
|
||||
|
||||
password_protect = self.password_checkbox.isChecked()
|
||||
# Passwortschutz ist entfernt - immer False
|
||||
password_protect = False
|
||||
|
||||
return formats, password_protect
|
||||
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren