Batch-Export geht jetzt
Dieser Commit ist enthalten in:
@ -176,9 +176,6 @@ class ProfileExportController:
|
||||
"""
|
||||
Exportiert mehrere Accounts gleichzeitig.
|
||||
|
||||
HINWEIS: Diese Funktion ist vorbereitet für zukünftige Erweiterung,
|
||||
wird aber gemäß ROADMAP.md vorerst NICHT implementiert (YAGNI).
|
||||
|
||||
Args:
|
||||
parent_widget: Parent-Widget
|
||||
account_ids: Liste von Account-IDs
|
||||
@ -186,10 +183,154 @@ class ProfileExportController:
|
||||
Returns:
|
||||
True bei Erfolg, False bei Fehler
|
||||
"""
|
||||
show_warning(
|
||||
parent_widget,
|
||||
"Nicht verfügbar",
|
||||
"Mehrfach-Export ist derzeit nicht verfügbar.\n"
|
||||
"Bitte exportieren Sie Accounts einzeln."
|
||||
)
|
||||
return False
|
||||
try:
|
||||
if not account_ids:
|
||||
logger.warning("Keine Account-IDs zum Export übergeben")
|
||||
return False
|
||||
|
||||
logger.info(f"Starte Batch-Export für {len(account_ids)} Accounts")
|
||||
|
||||
# 1. Alle Account-Daten laden
|
||||
accounts_data = []
|
||||
for account_id in account_ids:
|
||||
account_data = self.db_manager.get_account(account_id)
|
||||
if account_data:
|
||||
accounts_data.append(account_data)
|
||||
else:
|
||||
logger.warning(f"Account ID {account_id} nicht gefunden")
|
||||
|
||||
if not accounts_data:
|
||||
show_error(
|
||||
parent_widget,
|
||||
"Keine Accounts gefunden",
|
||||
"Keiner der ausgewählten Accounts konnte geladen werden."
|
||||
)
|
||||
return False
|
||||
|
||||
logger.info(f"{len(accounts_data)} Accounts erfolgreich geladen")
|
||||
|
||||
# 2. Export-Dialog anzeigen
|
||||
accepted, formats, _ = show_export_dialog(parent_widget, f"{len(accounts_data)} Accounts")
|
||||
|
||||
if not accepted:
|
||||
logger.info("Batch-Export abgebrochen durch Nutzer")
|
||||
return False
|
||||
|
||||
logger.info(f"Batch-Export-Optionen: Formate={formats}")
|
||||
|
||||
# 3. Hauptordner wählen
|
||||
from datetime import datetime
|
||||
timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M")
|
||||
suggested_folder_name = f"AccountForge_Export_{timestamp}"
|
||||
|
||||
save_directory = QFileDialog.getExistingDirectory(
|
||||
parent_widget,
|
||||
"Hauptordner für Batch-Export auswählen",
|
||||
str(Path.home() / "Downloads" / suggested_folder_name)
|
||||
)
|
||||
|
||||
if not save_directory:
|
||||
logger.info("Kein Speicherort ausgewählt - Export abgebrochen")
|
||||
return False
|
||||
|
||||
# Hauptordner erstellen falls nicht vorhanden
|
||||
os.makedirs(save_directory, exist_ok=True)
|
||||
logger.info(f"Batch-Export-Ordner: {save_directory}")
|
||||
|
||||
# 4. Für jeden Account exportieren
|
||||
exported_files = []
|
||||
failed_accounts = []
|
||||
|
||||
for account_data in accounts_data:
|
||||
username = account_data.get("username", "unknown")
|
||||
platform = account_data.get("platform", "unknown").lower()
|
||||
|
||||
try:
|
||||
# Plattform-Unterordner erstellen
|
||||
platform_dir = os.path.join(save_directory, platform)
|
||||
os.makedirs(platform_dir, exist_ok=True)
|
||||
|
||||
# Export durchführen
|
||||
files_dict = self.export_service.export_account(
|
||||
account_data,
|
||||
formats,
|
||||
password_protect=False
|
||||
)
|
||||
|
||||
# Dateien mit vereinfachten Namen speichern (ohne Timestamp)
|
||||
for filename, content in files_dict.items():
|
||||
# Vereinfachter Name: username.extension
|
||||
ext = filename.split('.')[-1]
|
||||
simple_filename = f"{username}.{ext}"
|
||||
file_path = os.path.join(platform_dir, simple_filename)
|
||||
|
||||
with open(file_path, 'wb') as f:
|
||||
f.write(content)
|
||||
|
||||
exported_files.append(f"{platform}/{simple_filename}")
|
||||
logger.info(f"Exportiert: {platform}/{simple_filename}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Fehler beim Export von {username}: {e}")
|
||||
failed_accounts.append(username)
|
||||
|
||||
# 5. Summary-Datei erstellen
|
||||
summary_path = os.path.join(save_directory, "export_summary.txt")
|
||||
with open(summary_path, 'w', encoding='utf-8') as f:
|
||||
f.write(f"AccountForge Batch-Export\n")
|
||||
f.write(f"="*50 + "\n\n")
|
||||
f.write(f"Exportiert am: {datetime.now().strftime('%d.%m.%Y %H:%M:%S')}\n")
|
||||
f.write(f"Anzahl Accounts: {len(accounts_data)}\n")
|
||||
f.write(f"Erfolgreich: {len(accounts_data) - len(failed_accounts)}\n")
|
||||
if failed_accounts:
|
||||
f.write(f"Fehlgeschlagen: {len(failed_accounts)}\n")
|
||||
f.write(f"\nFormate: {', '.join(formats).upper()}\n")
|
||||
f.write(f"\n" + "="*50 + "\n\n")
|
||||
|
||||
# Gruppiere nach Plattform
|
||||
platforms = {}
|
||||
for account_data in accounts_data:
|
||||
platform = account_data.get("platform", "unknown").lower()
|
||||
if platform not in platforms:
|
||||
platforms[platform] = []
|
||||
platforms[platform].append(account_data.get("username", ""))
|
||||
|
||||
for platform, usernames in sorted(platforms.items()):
|
||||
f.write(f"{platform.capitalize()}:\n")
|
||||
for username in usernames:
|
||||
if username in failed_accounts:
|
||||
f.write(f" ✗ {username} (FEHLER)\n")
|
||||
else:
|
||||
f.write(f" ✓ {username}\n")
|
||||
f.write(f"\n")
|
||||
|
||||
exported_files.append("export_summary.txt")
|
||||
logger.info("Summary-Datei erstellt")
|
||||
|
||||
# 6. Erfolgs-Dialog anzeigen
|
||||
show_export_success(
|
||||
parent_widget,
|
||||
exported_files,
|
||||
save_directory
|
||||
)
|
||||
|
||||
if failed_accounts:
|
||||
show_warning(
|
||||
parent_widget,
|
||||
"Teilweise erfolgreich",
|
||||
f"Export abgeschlossen, aber {len(failed_accounts)} Account(s) fehlgeschlagen:\n" +
|
||||
"\n".join(f"- {name}" for name in failed_accounts[:5]) +
|
||||
(f"\n... und {len(failed_accounts)-5} weitere" if len(failed_accounts) > 5 else "")
|
||||
)
|
||||
|
||||
logger.info(f"Batch-Export erfolgreich: {len(exported_files)} Datei(en)")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Fehler beim Batch-Export: {e}", exc_info=True)
|
||||
show_error(
|
||||
parent_widget,
|
||||
"Batch-Export fehlgeschlagen",
|
||||
f"Beim Batch-Export ist ein Fehler aufgetreten:\n\n{str(e)}"
|
||||
)
|
||||
return False
|
||||
|
||||
@ -5,7 +5,7 @@ Accounts Overview View - Account-Übersicht im Mockup-Style
|
||||
import logging
|
||||
from PyQt5.QtWidgets import (
|
||||
QWidget, QHBoxLayout, QVBoxLayout, QLabel, QPushButton,
|
||||
QScrollArea, QGridLayout, QFrame, QMessageBox
|
||||
QScrollArea, QGridLayout, QFrame, QMessageBox, QCheckBox
|
||||
)
|
||||
from PyQt5.QtCore import Qt, pyqtSignal
|
||||
from PyQt5.QtGui import QFont
|
||||
@ -106,20 +106,25 @@ class AccountsOverviewView(QWidget):
|
||||
Account-Übersicht im Mockup-Style mit:
|
||||
- Sidebar-Filter
|
||||
- Grid-Layout mit Account-Karten
|
||||
- Batch-Export mit Checkbox-Auswahl
|
||||
"""
|
||||
|
||||
|
||||
# Signals
|
||||
account_login_requested = pyqtSignal(dict)
|
||||
account_export_requested = pyqtSignal(dict)
|
||||
account_delete_requested = pyqtSignal(dict)
|
||||
export_requested = pyqtSignal() # Für Kompatibilität
|
||||
|
||||
bulk_export_requested = pyqtSignal(list) # List[int] - account_ids
|
||||
|
||||
def __init__(self, db_manager=None, language_manager=None):
|
||||
super().__init__()
|
||||
self.db_manager = db_manager
|
||||
self.language_manager = language_manager
|
||||
self.current_filter = "all"
|
||||
self.accounts = []
|
||||
self.selected_account_ids = set() # Set of selected account IDs
|
||||
self.account_cards = [] # List of AccountCard widgets
|
||||
self._updating_selection = False # Flag to prevent selection loops
|
||||
self.init_ui()
|
||||
|
||||
if self.language_manager:
|
||||
@ -156,11 +161,145 @@ class AccountsOverviewView(QWidget):
|
||||
self.title.setFont(title_font)
|
||||
self.title.setObjectName("section_title") # For QSS targeting
|
||||
header_layout.addWidget(self.title)
|
||||
|
||||
|
||||
header_layout.addStretch()
|
||||
|
||||
|
||||
# Selection Mode Button
|
||||
self.selection_mode_btn = QPushButton("Exportieren")
|
||||
self.selection_mode_btn.setCursor(Qt.PointingHandCursor)
|
||||
self.selection_mode_btn.setStyleSheet("""
|
||||
QPushButton {
|
||||
background-color: #10B981;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
font-family: 'Poppins', sans-serif;
|
||||
padding: 8px 16px;
|
||||
min-width: 100px;
|
||||
}
|
||||
QPushButton:hover {
|
||||
background-color: #059669;
|
||||
}
|
||||
QPushButton:pressed {
|
||||
background-color: #047857;
|
||||
}
|
||||
""")
|
||||
self.selection_mode_btn.clicked.connect(self._enable_selection_mode)
|
||||
header_layout.addWidget(self.selection_mode_btn)
|
||||
|
||||
content_layout.addLayout(header_layout)
|
||||
|
||||
|
||||
# Selection Toolbar (initially hidden)
|
||||
self.toolbar = QFrame()
|
||||
self.toolbar.setObjectName("selection_toolbar")
|
||||
self.toolbar.setVisible(False)
|
||||
self.toolbar.setStyleSheet("""
|
||||
#selection_toolbar {
|
||||
background-color: #F3F4F6;
|
||||
border-radius: 8px;
|
||||
padding: 12px 16px;
|
||||
}
|
||||
""")
|
||||
|
||||
toolbar_layout = QHBoxLayout(self.toolbar)
|
||||
toolbar_layout.setContentsMargins(0, 0, 0, 0)
|
||||
toolbar_layout.setSpacing(16)
|
||||
|
||||
# "Alle auswählen" Checkbox
|
||||
self.select_all_checkbox = QCheckBox("Alle auswählen")
|
||||
self.select_all_checkbox.setTristate(True)
|
||||
self.select_all_checkbox.setStyleSheet("""
|
||||
QCheckBox {
|
||||
font-size: 13px;
|
||||
font-family: 'Poppins', sans-serif;
|
||||
font-weight: 500;
|
||||
color: #374151;
|
||||
}
|
||||
QCheckBox::indicator {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border-radius: 4px;
|
||||
border: 2px solid #D1D5DB;
|
||||
}
|
||||
QCheckBox::indicator:checked {
|
||||
background-color: #0099CC;
|
||||
border-color: #0099CC;
|
||||
}
|
||||
QCheckBox::indicator:indeterminate {
|
||||
background-color: #0099CC;
|
||||
border-color: #0099CC;
|
||||
opacity: 0.6;
|
||||
}
|
||||
""")
|
||||
self.select_all_checkbox.stateChanged.connect(self._on_select_all_changed)
|
||||
toolbar_layout.addWidget(self.select_all_checkbox)
|
||||
|
||||
# Selection count label
|
||||
self.selection_count_label = QLabel("0 ausgewählt")
|
||||
self.selection_count_label.setStyleSheet("""
|
||||
color: #6B7280;
|
||||
font-size: 13px;
|
||||
font-family: 'Poppins', sans-serif;
|
||||
""")
|
||||
toolbar_layout.addWidget(self.selection_count_label)
|
||||
|
||||
toolbar_layout.addStretch()
|
||||
|
||||
# Export button
|
||||
self.bulk_export_btn = QPushButton("Exportieren")
|
||||
self.bulk_export_btn.setEnabled(False)
|
||||
self.bulk_export_btn.setCursor(Qt.PointingHandCursor)
|
||||
self.bulk_export_btn.setStyleSheet("""
|
||||
QPushButton {
|
||||
background-color: #0099CC;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
font-family: 'Poppins', sans-serif;
|
||||
padding: 8px 16px;
|
||||
min-width: 100px;
|
||||
}
|
||||
QPushButton:hover {
|
||||
background-color: #0078A3;
|
||||
}
|
||||
QPushButton:pressed {
|
||||
background-color: #005C7A;
|
||||
}
|
||||
QPushButton:disabled {
|
||||
background-color: #D1D5DB;
|
||||
color: #9CA3AF;
|
||||
}
|
||||
""")
|
||||
self.bulk_export_btn.clicked.connect(self._on_bulk_export_clicked)
|
||||
toolbar_layout.addWidget(self.bulk_export_btn)
|
||||
|
||||
# Close selection mode button
|
||||
close_btn = QPushButton("✕")
|
||||
close_btn.setToolTip("Auswahl beenden")
|
||||
close_btn.setCursor(Qt.PointingHandCursor)
|
||||
close_btn.setStyleSheet("""
|
||||
QPushButton {
|
||||
background-color: transparent;
|
||||
color: #6B7280;
|
||||
border: none;
|
||||
font-size: 18px;
|
||||
padding: 4px;
|
||||
min-width: 24px;
|
||||
max-width: 24px;
|
||||
}
|
||||
QPushButton:hover {
|
||||
color: #374151;
|
||||
}
|
||||
""")
|
||||
close_btn.clicked.connect(self._disable_selection_mode)
|
||||
toolbar_layout.addWidget(close_btn)
|
||||
|
||||
content_layout.addWidget(self.toolbar)
|
||||
|
||||
# Scroll Area für Accounts
|
||||
self.scroll = QScrollArea()
|
||||
self.scroll.setWidgetResizable(True)
|
||||
@ -202,7 +341,8 @@ class AccountsOverviewView(QWidget):
|
||||
|
||||
def _update_display(self):
|
||||
"""Aktualisiert die Anzeige basierend auf dem aktuellen Filter"""
|
||||
# Clear existing widgets
|
||||
# Clear existing widgets and account_cards list
|
||||
self.account_cards = []
|
||||
while self.grid_layout.count():
|
||||
child = self.grid_layout.takeAt(0)
|
||||
if child.widget():
|
||||
@ -287,12 +427,16 @@ class AccountsOverviewView(QWidget):
|
||||
def _create_account_card(self, account_data):
|
||||
"""Erstellt eine Account-Karte"""
|
||||
card = AccountCard(account_data, self.language_manager)
|
||||
|
||||
|
||||
# Verbinde Signals
|
||||
card.login_requested.connect(self.account_login_requested.emit)
|
||||
card.export_requested.connect(self.account_export_requested.emit)
|
||||
card.delete_requested.connect(self._on_delete_requested)
|
||||
|
||||
card.selection_changed.connect(self._on_card_selection_changed)
|
||||
|
||||
# Zu Liste hinzufügen für Batch-Operations
|
||||
self.account_cards.append(card)
|
||||
|
||||
return card
|
||||
|
||||
def _on_delete_requested(self, account_data):
|
||||
@ -376,4 +520,91 @@ class AccountsOverviewView(QWidget):
|
||||
Session-Status-Update deaktiviert (Session-Funktionalität entfernt).
|
||||
"""
|
||||
# Session-Funktionalität wurde entfernt - diese Methode macht nichts mehr
|
||||
pass
|
||||
pass
|
||||
|
||||
# ========== Selection Mode Methods ==========
|
||||
|
||||
def _enable_selection_mode(self):
|
||||
"""Aktiviert den Selection-Modus"""
|
||||
# Show toolbar, hide selection button
|
||||
self.toolbar.setVisible(True)
|
||||
self.selection_mode_btn.setVisible(False)
|
||||
|
||||
# Enable selection mode on all cards
|
||||
for card in self.account_cards:
|
||||
card.set_selection_mode(True)
|
||||
|
||||
# Reset selection state
|
||||
self.selected_account_ids.clear()
|
||||
self._update_selection_ui()
|
||||
|
||||
def _disable_selection_mode(self):
|
||||
"""Deaktiviert den Selection-Modus"""
|
||||
# Hide toolbar, show selection button
|
||||
self.toolbar.setVisible(False)
|
||||
self.selection_mode_btn.setVisible(True)
|
||||
|
||||
# Disable selection mode on all cards
|
||||
for card in self.account_cards:
|
||||
card.set_selection_mode(False)
|
||||
|
||||
# Clear selection
|
||||
self.selected_account_ids.clear()
|
||||
self._update_selection_ui()
|
||||
|
||||
def _on_card_selection_changed(self, account_id: int, selected: bool):
|
||||
"""Handler wenn eine Card ausgewählt/abgewählt wird"""
|
||||
if selected:
|
||||
self.selected_account_ids.add(account_id)
|
||||
else:
|
||||
self.selected_account_ids.discard(account_id)
|
||||
|
||||
self._update_selection_ui()
|
||||
|
||||
def _on_select_all_changed(self, state):
|
||||
"""Handler für "Alle auswählen" Checkbox"""
|
||||
if self._updating_selection:
|
||||
return
|
||||
|
||||
select_all = (state == Qt.Checked)
|
||||
|
||||
# Set all cards to the same selection state
|
||||
self._updating_selection = True
|
||||
for card in self.account_cards:
|
||||
card.set_selected(select_all)
|
||||
self._updating_selection = False
|
||||
|
||||
def _update_selection_ui(self):
|
||||
"""Aktualisiert die Selection-UI (Count-Label, Button-Status)"""
|
||||
count = len(self.selected_account_ids)
|
||||
|
||||
# Update count label
|
||||
if count == 0:
|
||||
self.selection_count_label.setText("0 ausgewählt")
|
||||
elif count == 1:
|
||||
self.selection_count_label.setText("1 ausgewählt")
|
||||
else:
|
||||
self.selection_count_label.setText(f"{count} ausgewählt")
|
||||
|
||||
# Enable/Disable export button
|
||||
self.bulk_export_btn.setEnabled(count > 0)
|
||||
|
||||
# Update "Alle auswählen" checkbox state
|
||||
total_cards = len(self.account_cards)
|
||||
if total_cards > 0:
|
||||
self._updating_selection = True
|
||||
if count == 0:
|
||||
self.select_all_checkbox.setCheckState(Qt.Unchecked)
|
||||
elif count == total_cards:
|
||||
self.select_all_checkbox.setCheckState(Qt.Checked)
|
||||
else:
|
||||
self.select_all_checkbox.setCheckState(Qt.PartiallyChecked)
|
||||
self._updating_selection = False
|
||||
|
||||
def _on_bulk_export_clicked(self):
|
||||
"""Handler für Bulk-Export-Button"""
|
||||
if len(self.selected_account_ids) == 0:
|
||||
return
|
||||
|
||||
# Emit signal with list of selected account IDs
|
||||
self.bulk_export_requested.emit(list(self.selected_account_ids))
|
||||
@ -60,6 +60,7 @@ class PlatformSelector(QWidget):
|
||||
self.accounts_overview.account_login_requested.connect(self._on_login_requested)
|
||||
self.accounts_overview.account_export_requested.connect(self._on_export_requested)
|
||||
self.accounts_overview.account_delete_requested.connect(self._on_delete_requested)
|
||||
self.accounts_overview.bulk_export_requested.connect(self._on_bulk_export_requested)
|
||||
self.content_stack.addWidget(self.accounts_overview)
|
||||
|
||||
# Für Kompatibilität mit MainController - accounts_tab Referenz
|
||||
@ -123,6 +124,13 @@ class PlatformSelector(QWidget):
|
||||
except Exception as e:
|
||||
print(f"Fehler beim Löschen des Accounts: {e}")
|
||||
|
||||
def _on_bulk_export_requested(self, account_ids):
|
||||
"""Behandelt Bulk-Export-Anfragen."""
|
||||
from controllers.profile_export_controller import ProfileExportController
|
||||
if self.db_manager:
|
||||
controller = ProfileExportController(self.db_manager)
|
||||
controller.export_multiple_accounts(self, account_ids)
|
||||
|
||||
def update_texts(self):
|
||||
"""Aktualisiert die Texte gemäß der aktuellen Sprache."""
|
||||
# Die Komponenten aktualisieren ihre Texte selbst
|
||||
|
||||
@ -4,7 +4,7 @@ Account Card Widget - Kompakte Account-Karte nach Styleguide
|
||||
|
||||
from PyQt5.QtWidgets import (
|
||||
QFrame, QVBoxLayout, QHBoxLayout, QLabel, QPushButton,
|
||||
QGridLayout, QWidget, QApplication
|
||||
QGridLayout, QWidget, QApplication, QCheckBox
|
||||
)
|
||||
from PyQt5.QtCore import Qt, pyqtSignal, QSize, QTimer
|
||||
from PyQt5.QtGui import QFont, QPixmap
|
||||
@ -17,17 +17,20 @@ 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
|
||||
|
||||
selection_changed = pyqtSignal(int, bool) # account_id, selected
|
||||
|
||||
def __init__(self, account_data, language_manager=None):
|
||||
super().__init__()
|
||||
self.account_data = account_data
|
||||
self.language_manager = language_manager
|
||||
self.password_visible = False
|
||||
self.selection_mode = False
|
||||
self.is_selected_state = False
|
||||
|
||||
# Timer für Icon-Animation
|
||||
self.email_copy_timer = QTimer()
|
||||
@ -136,16 +139,34 @@ class AccountCard(QFrame):
|
||||
|
||||
# Header Zeile
|
||||
header_layout = QHBoxLayout()
|
||||
|
||||
|
||||
# Platform Icon + Username
|
||||
info_layout = QHBoxLayout()
|
||||
info_layout.setSpacing(8)
|
||||
|
||||
|
||||
# Status wird jetzt über Karten-Hintergrund und Umrandung angezeigt
|
||||
|
||||
|
||||
# Selection Checkbox (hidden by default)
|
||||
self.selection_checkbox = QCheckBox()
|
||||
self.selection_checkbox.setVisible(False)
|
||||
self.selection_checkbox.stateChanged.connect(self._on_selection_changed)
|
||||
self.selection_checkbox.setStyleSheet("""
|
||||
QCheckBox::indicator {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 4px;
|
||||
border: 2px solid #D1D5DB;
|
||||
}
|
||||
QCheckBox::indicator:checked {
|
||||
background-color: #0099CC;
|
||||
border-color: #0099CC;
|
||||
}
|
||||
""")
|
||||
info_layout.addWidget(self.selection_checkbox)
|
||||
|
||||
# Platform Icon
|
||||
platform_icon = IconFactory.create_icon_label(
|
||||
self.account_data.get("platform", "").lower(),
|
||||
self.account_data.get("platform", "").lower(),
|
||||
size=18
|
||||
)
|
||||
info_layout.addWidget(platform_icon)
|
||||
@ -378,4 +399,46 @@ class AccountCard(QFrame):
|
||||
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()
|
||||
self._apply_status_styling()
|
||||
|
||||
# ========== Selection Mode Methods ==========
|
||||
|
||||
def set_selection_mode(self, enabled: bool):
|
||||
"""
|
||||
Aktiviert/Deaktiviert den Selection-Modus.
|
||||
|
||||
Args:
|
||||
enabled: True = Checkbox anzeigen, False = Checkbox verstecken
|
||||
"""
|
||||
self.selection_mode = enabled
|
||||
self.selection_checkbox.setVisible(enabled)
|
||||
|
||||
if not enabled:
|
||||
# Reset selection when mode is disabled
|
||||
self.set_selected(False)
|
||||
|
||||
def _on_selection_changed(self, state):
|
||||
"""Handler für Checkbox state change"""
|
||||
self.is_selected_state = (state == Qt.Checked)
|
||||
account_id = self.account_data.get("id")
|
||||
if account_id:
|
||||
self.selection_changed.emit(account_id, self.is_selected_state)
|
||||
|
||||
def is_selected(self) -> bool:
|
||||
"""
|
||||
Gibt zurück ob die Card ausgewählt ist.
|
||||
|
||||
Returns:
|
||||
True wenn ausgewählt, sonst False
|
||||
"""
|
||||
return self.is_selected_state
|
||||
|
||||
def set_selected(self, selected: bool):
|
||||
"""
|
||||
Setzt den Auswahl-Status.
|
||||
|
||||
Args:
|
||||
selected: True = auswählen, False = Auswahl aufheben
|
||||
"""
|
||||
self.is_selected_state = selected
|
||||
self.selection_checkbox.setChecked(selected)
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren